From 1eceb0065c4edb2e2d42c8649399f265e6346969 Mon Sep 17 00:00:00 2001 From: Hecate2 <2474101468@qq.com> Date: Thu, 16 Jan 2025 12:46:46 +0800 Subject: [PATCH] break from multiple try --- .../MethodConvert/Statement/BreakStatement.cs | 47 ++++++----- .../Statement/CommonForEachStatement.cs | 8 +- .../MethodConvert/Statement/DoStatement.cs | 2 +- .../MethodConvert/Statement/ForStatement.cs | 2 +- .../MethodConvert/Statement/Statement.cs | 28 ++++++- .../Statement/SwitchStatement.cs | 2 +- .../MethodConvert/Statement/TryStatement.cs | 12 ++- .../MethodConvert/Statement/WhileStatement.cs | 2 +- .../Contract_Break.cs | 24 ++++-- .../TestingArtifacts/Contract_Break.cs | 81 +++++++++++++------ 10 files changed, 146 insertions(+), 62 deletions(-) diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/BreakStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/BreakStatement.cs index 7c1299fba..3c0ca34a2 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/BreakStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/BreakStatement.cs @@ -10,6 +10,8 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Neo.VM; +using System.Collections.Generic; +using System.Linq; namespace Neo.Compiler { @@ -45,31 +47,36 @@ private void ConvertBreakStatement(BreakStatementSyntax syntax) { using (InsertSequencePoint(syntax)) { - int nestedTryWithFinally = 0; + JumpTarget? breakTarget = null; + List visitedTry = []; // from shallow to deep foreach (StatementContext sc in _generalStatementStack) - { + {// start from the deepest context + // find the final break target if (sc.BreakTarget != null) { - if (nestedTryWithFinally == 0) - Jump(OpCode.JMP_L, sc.BreakTarget); - else - Jump(OpCode.ENDTRY_L, sc.BreakTarget); - return; - } - if (sc.StatementSyntax is TryStatementSyntax && sc.FinallyTarget != null) - { - if (nestedTryWithFinally > 0) - throw new CompilationException(sc.StatementSyntax, DiagnosticId.SyntaxNotSupported, "Neo VM does not support `break` from multi-layered nested try-catch with finally."); - if (sc.TryState != ExceptionHandlingState.Finally) - nestedTryWithFinally++; - else // Not likely to happen. C# syntax analyzer should forbid break in finally - throw new CompilationException(sc.StatementSyntax, DiagnosticId.SyntaxNotSupported, "Cannot break in finally."); + breakTarget = sc.BreakTarget; + break; } + // stage the try stacks on the way + if (sc.StatementSyntax is TryStatementSyntax) + visitedTry.Add(sc); } - // break is not handled - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Cannot find what to break. " + - $"If not syntax error, this is probably a compiler bug. " + - $"Check whether the compiler is leaving out a push into {nameof(_generalStatementStack)}."); + if (breakTarget == null) + // break is not handled + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Cannot find what to break. " + + $"If not syntax error, this is probably a compiler bug. " + + $"Check whether the compiler is leaving out a push into {nameof(_generalStatementStack)}."); + + foreach (StatementContext sc in visitedTry) + // start from the most external try + // internal try should ENDTRY, targeting the correct external break target + breakTarget = sc.AddEndTry(breakTarget); + + Jump(OpCode.JMP_L, breakTarget); + // We could use ENDTRY if current statement calling `break` is a try statement, + // but this job can be done by the optimizer + // Note that, do not Jump(OpCode.ENDTRY_L, breakTarget) here, + // because the breakTarget here is already an ENDTRY_L for current try stack. } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/CommonForEachStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/CommonForEachStatement.cs index dea86ada5..c4c2237ce 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/CommonForEachStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/CommonForEachStatement.cs @@ -100,7 +100,7 @@ private void ConvertIteratorForEachStatement(SemanticModel model, ForEachStateme PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } /// @@ -197,7 +197,7 @@ private void ConvertIteratorForEachVariableStatement(SemanticModel model, ForEac PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } /// @@ -266,7 +266,7 @@ private void ConvertArrayForEachStatement(SemanticModel model, ForEachStatementS PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } /// @@ -349,7 +349,7 @@ private void ConvertArrayForEachVariableStatement(SemanticModel model, ForEachVa PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/DoStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/DoStatement.cs index 61ef83c92..bd2057aa2 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/DoStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/DoStatement.cs @@ -59,7 +59,7 @@ private void ConvertDoStatement(SemanticModel model, DoStatementSyntax syntax) PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/ForStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/ForStatement.cs index bcb344c5b..ae47e9abc 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/ForStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/ForStatement.cs @@ -102,7 +102,7 @@ private void ConvertForStatement(SemanticModel model, ForStatementSyntax syntax) PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/Statement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/Statement.cs index bc1ddf548..1997e0657 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/Statement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/Statement.cs @@ -11,7 +11,9 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Neo.VM; +using Org.BouncyCastle.Asn1.X509; using System.Collections.Generic; +using System.Linq; namespace Neo.Compiler { @@ -39,19 +41,37 @@ internal class StatementContext(StatementSyntax statementSyntax, public readonly JumpTarget? EndFinallyTarget = endFinallyTarget; public /*readonly*/ Dictionary? GotoLabels = gotoLabels; public /*readonly*/ Dictionary? SwitchLabels = switchLabels; + // handles `break`, `continue` and `goto` in multi-layered nested try with finally + // key: target of this ENDTRY + // value: this ENDTRY + public Dictionary? AdditionalEndTryTargetToInstruction { get; protected set; } = null; //public readonly StatementSyntax? ParentStatement = parentStatement; //public readonly HashSet? ChildrenStatements = childrenStatements; + /// Jump target of this added ENDTRY + /// The added ENDTRY + /// + public JumpTarget AddEndTry(JumpTarget target) + { + if (StatementSyntax is not TryStatementSyntax) + throw new CompilationException(StatementSyntax, DiagnosticId.SyntaxNotSupported, $"Can only append ENDTRY for TryStatement. Got {typeof(StatementSyntax)} {StatementSyntax}. This is a compiler bug."); + AdditionalEndTryTargetToInstruction ??= []; + if (AdditionalEndTryTargetToInstruction.TryGetValue(target, out JumpTarget? existingEndTry)) + return existingEndTry; + Instruction i = new() { OpCode = OpCode.ENDTRY_L, Target = target }; + existingEndTry = new JumpTarget() { Instruction = i }; + AdditionalEndTryTargetToInstruction.Add(target, existingEndTry); + return existingEndTry; + } + public bool AddLabel(ILabelSymbol label, JumpTarget target) { - if (GotoLabels == null) - GotoLabels = []; + GotoLabels ??= []; return GotoLabels.TryAdd(label, target); } public bool AddLabel(SwitchLabelSyntax label, JumpTarget target) { - if (SwitchLabels == null) - SwitchLabels = []; + SwitchLabels ??= []; return SwitchLabels.TryAdd(label, target); } public bool ContainsLabel(ILabelSymbol label) => GotoLabels is not null && GotoLabels.ContainsKey(label); diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/SwitchStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/SwitchStatement.cs index d62585e92..52f985782 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/SwitchStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/SwitchStatement.cs @@ -114,7 +114,7 @@ private void ConvertSwitchStatement(SemanticModel model, SwitchStatementSyntax s PopSwitchLabels(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/TryStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/TryStatement.cs index 020dc6a30..6f19b30c3 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/TryStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/TryStatement.cs @@ -59,6 +59,11 @@ private void ConvertTryStatement(SemanticModel model, TryStatementSyntax syntax) _tryStack.Push(new ExceptionHandling { State = ExceptionHandlingState.Try }); ConvertStatement(model, syntax.Block); Jump(OpCode.ENDTRY_L, endTarget); + if (syntax.Catches.Count == 0 && sc.AdditionalEndTryTargetToInstruction != null) + // handles `break`, `continue` and `goto` in multi-layered nested try with finally + foreach (JumpTarget i in sc.AdditionalEndTryTargetToInstruction.Values) + AddInstruction(i.Instruction!); + if (syntax.Catches.Count > 1) throw new CompilationException(syntax.Catches[1], DiagnosticId.MultiplyCatches, "Only support one single catch."); if (syntax.Catches.Count > 0) @@ -86,6 +91,11 @@ private void ConvertTryStatement(SemanticModel model, TryStatementSyntax syntax) _exceptionStack.Push(exceptionIndex); ConvertStatement(model, catchClause.Block); Jump(OpCode.ENDTRY_L, endTarget); + if (sc.AdditionalEndTryTargetToInstruction != null) + // handles `break`, `continue` and `goto` in multi-layered nested try with finally + foreach (JumpTarget i in sc.AdditionalEndTryTargetToInstruction.Values) + AddInstruction(i.Instruction!); + if (exceptionSymbol is null) RemoveAnonymousVariable(exceptionIndex); else @@ -103,7 +113,7 @@ private void ConvertTryStatement(SemanticModel model, TryStatementSyntax syntax) endTarget.Instruction = AddInstruction(OpCode.NOP); _tryStack.Pop(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Statement/WhileStatement.cs b/src/Neo.Compiler.CSharp/MethodConvert/Statement/WhileStatement.cs index 9c226a86b..2643515cd 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Statement/WhileStatement.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Statement/WhileStatement.cs @@ -59,7 +59,7 @@ private void ConvertWhileStatement(SemanticModel model, WhileStatementSyntax syn PopContinueTarget(); PopBreakTarget(); if (_generalStatementStack.Pop() != sc) - throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside."); + throw new CompilationException(syntax, DiagnosticId.SyntaxNotSupported, $"Bad statement stack handling inside. This is a compiler bug."); } } } diff --git a/tests/Neo.Compiler.CSharp.TestContracts/Contract_Break.cs b/tests/Neo.Compiler.CSharp.TestContracts/Contract_Break.cs index 9ff7792af..25134c1ba 100644 --- a/tests/Neo.Compiler.CSharp.TestContracts/Contract_Break.cs +++ b/tests/Neo.Compiler.CSharp.TestContracts/Contract_Break.cs @@ -14,13 +14,17 @@ public static void BreakInTryCatch() finally { Storage.Put("\xff\x00", "\x01"); } ExecutionEngine.Assert(Storage.Get("\xff\x00")! == "\x01"); foreach (object i in Storage.Find("\xff")) - try { throw new System.Exception(); } + try + { + for (int j = 0; j < 3;) + throw new System.Exception(); + } catch { do { break; } while (true); - Storage.Put("\xff\x00", "\x00"); - break; // break foreach; should execute finally + try { break; } // break foreach; should execute finally + finally { Storage.Put("\xff\x00", "\x00"); } } finally { @@ -37,14 +41,24 @@ public static void BreakInTryCatch() { for (int j = 0; j < 3;) break; - throw new System.Exception(); } catch { int j = 0; while (j < 3) break; - break; // foreach; should execute finally + ExecutionEngine.Assert(j == 0); + try + { + Storage.Put("\xff\x00", "\x03"); + throw; + } + catch { break; } // foreach; should execute finally + finally + { + ExecutionEngine.Assert(Storage.Get("\xff\x00")! == "\x03"); + Storage.Put("\xff\x00", "\x02"); + } } finally { diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_Break.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_Break.cs index 306a105ff..ac164ec9a 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_Break.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_Break.cs @@ -15,7 +15,7 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP1DAVcGAAwBAAwC/wA1CgEAABAMAf81EQEAAHAiG2hB81S/HXE7AAU9FwwBAQwC/wA15gAAAD9oQZwI7Zwk4QwC/wA19AAAAAwBAZc5EAwB/zXWAAAAcCJWaEHzVL8dcTsPHgwJZXhjZXB0aW9uOnIMAQAMAv8ANaAAAAA9OQwC/wA1tQAAAAwBAJc5EhEQE8BKcspzEHQiEWpsznUMAQIMAv8ANHMiBmxrMO8/aEGcCO2cJKYMAv8ANH4MAQKXORAMAf80Y3AiPGhB81S/HXE7FR4QcmoTtUUMCWV4Y2VwdGlvbjpyEHNrE7VFPR8MAv8ANEUMAQKXOQwBAwwC/wA0Fz9oQZwI7ZwkwAwC/wA0KAwBA5c5QFcAAnl4QZv2Z85B5j8YhEBXAAJ5eEH2tGviQd8wuJpAVwABeEH2tGviQZJd6DFAEImfDw==")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP2BAVcGAAwBAAwC/wA1SAEAABAMAf81TwEAAHAiG2hB81S/HXE7AAU9FwwBAQwC/wA1JAEAAD9oQZwI7Zwk4QwC/wA1MgEAAAwBAZc5EAwB/zUUAQAAcCJsaEHzVL8dcTsaMRByIg4MCWV4Y2VwdGlvbjpqE7Uk8T1LcjsAByIRPUsMAQAMAv8ANcwAAAA/PfEMAv8ANeAAAAAMAQCXORIREBPASnLKcxB0IhRqbM51DAECDAL/ADWeAAAAIgZsazDsP2hBnAjtnCSQDAL/ADWmAAAADAEClzkQDAH/NYgAAABwIl5oQfNUvx1xOwtAEHJqE7VFPUxyEHNrE7VFaxCXOTsOEwwBAwwC/wA0SWo6dCIZPTYMAv8ANFwMAQOXOQwBAgwC/wA0Lj896QwC/wA0RQwBApc5DAEDDAL/ADQXP2hBnAjtnCSeDAL/ADQoDAEDlzlAVwACeXhBm/ZnzkHmPxiEQFcAAnl4Qfa0a+JB3zC4mkBXAAF4Qfa0a+JBkl3oMUB6sNlU")); #endregion @@ -25,14 +25,14 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// Unsafe method /// /// - /// Script: VwYADAEADAL/ADUKAQAAEAwB/zURAQAAcCIbaEHzVL8dcTsABT0XDAEBDAL/ADXmAAAAP2hBnAjtnCThDAL/ADX0AAAADAEBlzkQDAH/NdYAAABwIlZoQfNUvx1xOw8eDAlleGNlcHRpb246cgwBAAwC/wA1oAAAAD05DAL/ADW1AAAADAEAlzkSERATwEpyynMQdCIRamzOdQwBAgwC/wA0cyIGbGsw7z9oQZwI7ZwkpgwC/wA0fgwBApc5EAwB/zRjcCI8aEHzVL8dcTsVHhByahO1RQwJZXhjZXB0aW9uOnIQc2sTtUU9HwwC/wA0RQwBApc5DAEDDAL/ADQXP2hBnAjtnCTADAL/ADQoDAEDlzlA + /// Script: VwYADAEADAL/ADVIAQAAEAwB/zVPAQAAcCIbaEHzVL8dcTsABT0XDAEBDAL/ADUkAQAAP2hBnAjtnCThDAL/ADUyAQAADAEBlzkQDAH/NRQBAABwImxoQfNUvx1xOxoxEHIiDgwJZXhjZXB0aW9uOmoTtSTxPUtyOwAHIhE9SwwBAAwC/wA1zAAAAD898QwC/wA14AAAAAwBAJc5EhEQE8BKcspzEHQiFGpsznUMAQIMAv8ANZ4AAAAiBmxrMOw/aEGcCO2cJJAMAv8ANaYAAAAMAQKXORAMAf81iAAAAHAiXmhB81S/HXE7C0AQcmoTtUU9THIQc2sTtUVrEJc5Ow4TDAEDDAL/ADRJajp0Ihk9NgwC/wA0XAwBA5c5DAECDAL/ADQuPz3pDAL/ADRFDAEClzkMAQMMAv8ANBc/aEGcCO2cJJ4MAv8ANCgMAQOXOUA= /// INITSLOT 0600 [64 datoshi] /// PUSHDATA1 00 [8 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL_L 0A010000 [512 datoshi] + /// CALL_L 48010000 [512 datoshi] /// PUSH0 [1 datoshi] /// PUSHDATA1 FF '?' [8 datoshi] - /// CALL_L 11010000 [512 datoshi] + /// CALL_L 4F010000 [512 datoshi] /// STLOC0 [2 datoshi] /// JMP 1B [2 datoshi] /// LDLOC0 [2 datoshi] @@ -42,34 +42,46 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// ENDTRY 17 [4 datoshi] /// PUSHDATA1 01 [8 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL_L E6000000 [512 datoshi] + /// CALL_L 24010000 [512 datoshi] /// ENDFINALLY [4 datoshi] /// LDLOC0 [2 datoshi] /// SYSCALL 9C08ED9C 'System.Iterator.Next' [32768 datoshi] /// JMPIF E1 [2 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL_L F4000000 [512 datoshi] + /// CALL_L 32010000 [512 datoshi] /// PUSHDATA1 01 [8 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// PUSH0 [1 datoshi] /// PUSHDATA1 FF '?' [8 datoshi] - /// CALL_L D6000000 [512 datoshi] + /// CALL_L 14010000 [512 datoshi] /// STLOC0 [2 datoshi] - /// JMP 56 [2 datoshi] + /// JMP 6C [2 datoshi] /// LDLOC0 [2 datoshi] /// SYSCALL F354BF1D 'System.Iterator.Value' [16 datoshi] /// STLOC1 [2 datoshi] - /// TRY 0F1E [4 datoshi] + /// TRY 1A31 [4 datoshi] + /// PUSH0 [1 datoshi] + /// STLOC2 [2 datoshi] + /// JMP 0E [2 datoshi] /// PUSHDATA1 657863657074696F6E 'exception' [8 datoshi] /// THROW [512 datoshi] + /// LDLOC2 [2 datoshi] + /// PUSH3 [1 datoshi] + /// LT [8 datoshi] + /// JMPIF F1 [2 datoshi] + /// ENDTRY 4B [4 datoshi] /// STLOC2 [2 datoshi] + /// TRY 0007 [4 datoshi] + /// JMP 11 [2 datoshi] + /// ENDTRY 4B [4 datoshi] /// PUSHDATA1 00 [8 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL_L A0000000 [512 datoshi] - /// ENDTRY 39 [4 datoshi] + /// CALL_L CC000000 [512 datoshi] + /// ENDFINALLY [4 datoshi] + /// ENDTRY F1 [4 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL_L B5000000 [512 datoshi] + /// CALL_L E0000000 [512 datoshi] /// PUSHDATA1 00 [8 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] @@ -84,44 +96,43 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// STLOC3 [2 datoshi] /// PUSH0 [1 datoshi] /// STLOC4 [2 datoshi] - /// JMP 11 [2 datoshi] + /// JMP 14 [2 datoshi] /// LDLOC2 [2 datoshi] /// LDLOC4 [2 datoshi] /// PICKITEM [64 datoshi] /// STLOC5 [2 datoshi] /// PUSHDATA1 02 [8 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL 73 [512 datoshi] + /// CALL_L 9E000000 [512 datoshi] /// JMP 06 [2 datoshi] /// LDLOC4 [2 datoshi] /// LDLOC3 [2 datoshi] - /// JMPLT EF [2 datoshi] + /// JMPLT EC [2 datoshi] /// ENDFINALLY [4 datoshi] /// LDLOC0 [2 datoshi] /// SYSCALL 9C08ED9C 'System.Iterator.Next' [32768 datoshi] - /// JMPIF A6 [2 datoshi] + /// JMPIF 90 [2 datoshi] /// PUSHDATA1 FF00 [8 datoshi] - /// CALL 7E [512 datoshi] + /// CALL_L A6000000 [512 datoshi] /// PUSHDATA1 02 [8 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// PUSH0 [1 datoshi] /// PUSHDATA1 FF '?' [8 datoshi] - /// CALL 63 [512 datoshi] + /// CALL_L 88000000 [512 datoshi] /// STLOC0 [2 datoshi] - /// JMP 3C [2 datoshi] + /// JMP 5E [2 datoshi] /// LDLOC0 [2 datoshi] /// SYSCALL F354BF1D 'System.Iterator.Value' [16 datoshi] /// STLOC1 [2 datoshi] - /// TRY 151E [4 datoshi] + /// TRY 0B40 [4 datoshi] /// PUSH0 [1 datoshi] /// STLOC2 [2 datoshi] /// LDLOC2 [2 datoshi] /// PUSH3 [1 datoshi] /// LT [8 datoshi] /// DROP [2 datoshi] - /// PUSHDATA1 657863657074696F6E 'exception' [8 datoshi] - /// THROW [512 datoshi] + /// ENDTRY 4C [4 datoshi] /// STLOC2 [2 datoshi] /// PUSH0 [1 datoshi] /// STLOC3 [2 datoshi] @@ -129,7 +140,29 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// PUSH3 [1 datoshi] /// LT [8 datoshi] /// DROP [2 datoshi] - /// ENDTRY 1F [4 datoshi] + /// LDLOC3 [2 datoshi] + /// PUSH0 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// TRY 0E13 [4 datoshi] + /// PUSHDATA1 03 [8 datoshi] + /// PUSHDATA1 FF00 [8 datoshi] + /// CALL 49 [512 datoshi] + /// LDLOC2 [2 datoshi] + /// THROW [512 datoshi] + /// STLOC4 [2 datoshi] + /// JMP 19 [2 datoshi] + /// ENDTRY 36 [4 datoshi] + /// PUSHDATA1 FF00 [8 datoshi] + /// CALL 5C [512 datoshi] + /// PUSHDATA1 03 [8 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// PUSHDATA1 02 [8 datoshi] + /// PUSHDATA1 FF00 [8 datoshi] + /// CALL 2E [512 datoshi] + /// ENDFINALLY [4 datoshi] + /// ENDTRY E9 [4 datoshi] /// PUSHDATA1 FF00 [8 datoshi] /// CALL 45 [512 datoshi] /// PUSHDATA1 02 [8 datoshi] @@ -141,7 +174,7 @@ public abstract class Contract_Break(Neo.SmartContract.Testing.SmartContractInit /// ENDFINALLY [4 datoshi] /// LDLOC0 [2 datoshi] /// SYSCALL 9C08ED9C 'System.Iterator.Next' [32768 datoshi] - /// JMPIF C0 [2 datoshi] + /// JMPIF 9E [2 datoshi] /// PUSHDATA1 FF00 [8 datoshi] /// CALL 28 [512 datoshi] /// PUSHDATA1 03 [8 datoshi]