-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Describe the bug
Please see below, or a new test case at https://github.com/neo-project/neo-devpack-dotnet/pull/1283/files#diff-544e2dcb82be726cf5037a446b68a0111e7851c29aafea4173b6565f7cef123e
To Reproduce
Compile the following contracts with the latest master branch neo-project/neo-devpack-dotnet@db9248a , or the codes at neo-project/neo-devpack-dotnet#1283 .
namespace Neo.Compiler.CSharp.TestContracts
{
public class Contract_Returns : SmartContract.Framework.SmartContract
{
private int MinimalTryReturnInternal()
{
try { return 1; }
finally { throw new System.Exception(); } // should execute finally after return
}
public void MinimalTryReturn()
{
try { MinimalTryReturnInternal(); }
catch { return; }
}
}
}# Method Start Neo.Compiler.CSharp.TestContracts.Contract_Returns.MinimalTryReturnInternal()
00 TRY 00-06 # no catch block, finally pos: 6 (offset: 6)
# Code test-compiler.cs line 21: "1"
03 PUSH1
# Code test-compiler.cs line 21: "return 1;"
04 ENDTRY 00 # pos: 4 (offset: 0)
# Code test-compiler.cs line 22: "throw new System.Exception();"
06 PUSHDATA1 65-78-63-65-70-74-69-6F-6E # as text: "exception"
# Method End Neo.Compiler.CSharp.TestContracts.Contract_Returns.MinimalTryReturnInternal()
# Code test-compiler.cs line 22: "throw new System.Exception();"
# Code test-compiler.cs line 23: "}"
17 THROW
# Method Start Neo.Compiler.CSharp.TestContracts.Contract_Returns.MinimalTryReturn()
18 INITSLOT 01-00 # 1 local variables, 0 arguments
21 TRY 05-00 # catch pos: 26 (offset: 5), no finally block
# Code test-compiler.cs line 27: "MinimalTryReturnInternal()"
# Code test-compiler.cs line 27: "MinimalTryReturnInternal()"
24 CALL E8 # pos: 0 (offset: -24)
# Code test-compiler.cs line 28: "catch"
26 STLOC0
# Code test-compiler.cs line 28: "return;"
27 ENDTRY 02 # pos: 29 (offset: 2)
# Method End Neo.Compiler.CSharp.TestContracts.Contract_Returns.MinimalTryReturn()
# Code test-compiler.cs line 29: "}"
29 RETCall minimalTryReturn to get exception Return value count mismatch: expected 0, but got 1 items on the evaluation stack. This is because 1 is pushed into the evaluation stack when MinimalTryReturnInternal tries to return 1, and the external context has no way to DROP the returned 1, because there is an exception to be catched.
And it seems impossible for the compiler to deal with the problem. During the execution of an expression, there is always possibility of exception at any instruction, and the exception can always be caught by the user to generate orphaned items in the evaluation stack.
Expected behavior
No exception
Possible Solutions
- Exception clears the evaluation stack
- (Optional) ENDFINALLY clears the evaluation stack
TRYmay have a higher GAS price, if necessary. Current price forTRYis 4, andCLEARhas 16.