diff --git a/src/Neo.Compiler.CSharp/MethodConvert/CompilerLocation.cs b/src/Neo.Compiler.CSharp/MethodConvert/CompilerLocation.cs index 1d2c9d3ce..3a7146075 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/CompilerLocation.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/CompilerLocation.cs @@ -2,6 +2,9 @@ namespace Neo.Compiler { + /// + /// Which file and method in the compiler generates the OpCode + /// public class CompilerLocation { public int Line { get; set; } diff --git a/src/Neo.Compiler.CSharp/Optimizer/AssetBuilder/DebugInfoBuilder.cs b/src/Neo.Compiler.CSharp/Optimizer/AssetBuilder/DebugInfoBuilder.cs index 35095e5fd..2d0297011 100644 --- a/src/Neo.Compiler.CSharp/Optimizer/AssetBuilder/DebugInfoBuilder.cs +++ b/src/Neo.Compiler.CSharp/Optimizer/AssetBuilder/DebugInfoBuilder.cs @@ -69,12 +69,72 @@ static class DebugInfoBuilder && oldSequencePointAddressToNew.TryGetValue(startInstructionAddress, out int newStartInstructionAddress)) { newSequencePoints.Add(new JString($"{newStartInstructionAddress}{sequencePointGroups[2]}")); - previousSequencePoint = startInstructionAddress; + previousSequencePoint = newStartInstructionAddress; } else newSequencePoints.Add(new JString($"{previousSequencePoint}{sequencePointGroups[2]}")); } method["sequence-points"] = newSequencePoints; + + if (method["sequence-points-v2"] is JObject sequencePointsV2) + { + JObject newSequencePointsV2 = new(); + previousSequencePoint = methodStart; + foreach ((string addr, JToken? content) in sequencePointsV2.Properties) + { + int startInstructionAddress = int.Parse(addr); + Instruction oldInstruction = oldAddressToInstruction[startInstructionAddress]; + string writeAddr; + if (simplifiedInstructionsToAddress.Contains(oldInstruction)) + { + startInstructionAddress = (int)simplifiedInstructionsToAddress[oldInstruction]!; + writeAddr = startInstructionAddress.ToString(); + previousSequencePoint = startInstructionAddress; + } + else if (oldSequencePointAddressToNew != null + && oldSequencePointAddressToNew.TryGetValue(startInstructionAddress, out int newStartInstructionAddress)) + { + writeAddr = newStartInstructionAddress.ToString(); + previousSequencePoint = newStartInstructionAddress; + if (content is JArray oldContentArray) + foreach (JToken? i in oldContentArray) + ((JObject)i!)["optimization"] = Neo.Compiler.CompilationOptions.OptimizationType.Experimental.ToString().ToLowerInvariant(); + if (content is JObject oldContentObject) + content["optimization"] = Neo.Compiler.CompilationOptions.OptimizationType.Experimental.ToString().ToLowerInvariant(); + } + else + // previousSequencePoint unchanged + writeAddr = previousSequencePoint.ToString(); + switch (newSequencePointsV2[writeAddr]) + // TODO: compress newSequencePointsV2 array to non-duplicating array + { + case null: + newSequencePointsV2[writeAddr] = content; + break; + case JObject existingObject: + newSequencePointsV2[writeAddr] = new JArray() { existingObject, content }; + break; + case JArray existingArray: + if (content is JArray contentArray) + newSequencePointsV2[writeAddr] = existingArray.Concat(contentArray).ToArray(); + if (content is JObject contentObject) + existingArray.Add(contentObject); + break; + default: + throw new BadScriptException($"Invalid sequence-points-v2 in debug info: key {addr}, value {content}"); + } + } + method["sequence-points-v2"] = newSequencePointsV2; + } + if (method["abi"] is JObject abi && abi["offset"] != null) + { + int offset = int.Parse(abi["offset"]!.ToString()); + if (simplifiedInstructionsToAddress.Contains(oldAddressToInstruction[offset])) + offset = (int)simplifiedInstructionsToAddress[oldAddressToInstruction[offset]]!; + else + oldSequencePointAddressToNew?.TryGetValue(offset, out offset); + abi["offset"] = offset; + } } JArray methods = (JArray)debugInfo["methods"]!; foreach (JToken method in methodsToRemove) diff --git a/src/Neo.Disassembler.CSharp/Disassembler.cs b/src/Neo.Disassembler.CSharp/Disassembler.cs index f8fac2d3a..60580b424 100644 --- a/src/Neo.Disassembler.CSharp/Disassembler.cs +++ b/src/Neo.Disassembler.CSharp/Disassembler.cs @@ -43,7 +43,6 @@ public static List ConvertScriptToInstructions(byte[] script) if (method["abi"] is JObject abi) { var parsedMethod = ContractMethodDescriptor.FromJson(abi); - parsedMethod.Offset = abiMethod.Offset; // It can be optimized, we avoid to check the offset if (!parsedMethod.Equals(abiMethod)) continue; return method as JObject;