Skip to content

Commit

Permalink
fix inline for null body method (#1211)
Browse files Browse the repository at this point in the history
* fix inline for null body method

* fix return value issue for arrowexpression with return value.
  • Loading branch information
Jim8y authored Dec 29, 2024
1 parent 6ddf726 commit 8971d08
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 3 deletions.
23 changes: 22 additions & 1 deletion src/Neo.Compiler.CSharp/MethodConvert/Helpers/ConvertHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,29 @@ private bool TryProcessInlineMethods(SemanticModel model, IMethodSymbol symbol,
using (InsertSequencePoint(syntax))
{
if (arguments is not null) PrepareArgumentsForMethod(model, symbol, arguments);
if (syntax.Body != null) ConvertStatement(model, syntax.Body);
if (syntax.Body != null)
{
ConvertStatement(model, syntax.Body);
}
else if (syntax.ExpressionBody != null)
{
ConvertExpression(model, syntax.ExpressionBody.Expression);
}
}

// If the method has no return value,
// but the expression body has a return value, example: a+=1;
// drop the return value
// Problem:
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public void Test() => a+=1; // this will push an int value to the stack
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public void Test() { a+=1; } // this will not push value to the stack
if (syntax is MethodDeclarationSyntax methodSyntax
&& methodSyntax.ReturnType.ToString() == "void"
&& IsExpressionReturningValue(model, methodSyntax))
AddInstruction(OpCode.DROP);

return true;
}

Expand Down
23 changes: 23 additions & 0 deletions tests/Neo.Compiler.CSharp.TestContracts/Contract_Inline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,28 @@ private static int inline_C()
{
return 3;
}

public static int ArrowMethod()
{
return ArrowInline(1, 2);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int ArrowInline(int a, int b) => a + b;


public static void ArrowMethodNoRerurn()
{
ArrowInlineNoReturn(1, 1);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ArrowInlineNoReturn(int a, int b) => CallMethodThatReturnsInt(a, b);


private static int CallMethodThatReturnsInt(int a, int b)
{
return a + b;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,58 @@ public abstract class Contract_Inline(Neo.SmartContract.Testing.SmartContractIni
{
#region Compiled data

public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_Inline"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testInline"",""parameters"":[{""name"":""method"",""type"":""String""}],""returntype"":""Integer"",""offset"":0,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}");
public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_Inline"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testInline"",""parameters"":[{""name"":""method"",""type"":""String""}],""returntype"":""Integer"",""offset"":0,""safe"":false},{""name"":""arrowMethod"",""parameters"":[],""returntype"":""Integer"",""offset"":331,""safe"":false},{""name"":""arrowMethodNoRerurn"",""parameters"":[],""returntype"":""Void"",""offset"":381,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}");

/// <summary>
/// Optimization: "All"
/// </summary>
public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable<Neo.SmartContract.NefFile>(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP1LAVcBAXhwaAwGaW5saW5llyYEEUBoDBppbmxpbmVfd2l0aF9vbmVfcGFyYW1ldGVyc5cmBBNAaAwcaW5saW5lX3dpdGhfbXVsdGlfcGFyYW1ldGVyc5cmNBMSnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9AaAwKbm90X2lubGluZZcmBTR0QGgMHm5vdF9pbmxpbmVfd2l0aF9vbmVfcGFyYW1ldGVyc5cmBhM0TkBoDCBub3RfaW5saW5lX3dpdGhfbXVsdGlfcGFyYW1ldGVyc5cmBxMSNChAaAwNaW5saW5lX25lc3RlZJcmBTRHQAgmBQBjQGg6EUBXAAF4QFcAAnh5nkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9AE0Cui6ZE"));
public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable<Neo.SmartContract.NefFile>(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP24AVcBAXhwaAwGaW5saW5llyYEEUBoDBppbmxpbmVfd2l0aF9vbmVfcGFyYW1ldGVyc5cmBBNAaAwcaW5saW5lX3dpdGhfbXVsdGlfcGFyYW1ldGVyc5cmNBMSnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9AaAwKbm90X2lubGluZZcmBTR0QGgMHm5vdF9pbmxpbmVfd2l0aF9vbmVfcGFyYW1ldGVyc5cmBhM0TkBoDCBub3RfaW5saW5lX3dpdGhfbXVsdGlfcGFyYW1ldGVyc5cmBxMSNChAaAwNaW5saW5lX25lc3RlZJcmBTRHQAgmBQBjQGg6EUBXAAF4QFcAAnh5nkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9AE0ASEZ5KAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfQBERNARFQFcAAnh5nkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9Arb2CVw=="));

#endregion

#region Unsafe methods

/// <summary>
/// Unsafe method
/// </summary>
/// <remarks>
/// Script: EhGeSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn0A=
/// PUSH2 [1 datoshi]
/// PUSH1 [1 datoshi]
/// ADD [8 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 00000080 [1 datoshi]
/// JMPGE 04 [2 datoshi]
/// JMP 0A [2 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 FFFFFF7F [1 datoshi]
/// JMPLE 1E [2 datoshi]
/// PUSHINT64 FFFFFFFF00000000 [1 datoshi]
/// AND [8 datoshi]
/// DUP [2 datoshi]
/// PUSHINT32 FFFFFF7F [1 datoshi]
/// JMPLE 0C [2 datoshi]
/// PUSHINT64 0000000001000000 [1 datoshi]
/// SUB [8 datoshi]
/// RET [0 datoshi]
/// </remarks>
[DisplayName("arrowMethod")]
public abstract BigInteger? ArrowMethod();

/// <summary>
/// Unsafe method
/// </summary>
/// <remarks>
/// Script: ERE0BEVA
/// PUSH1 [1 datoshi]
/// PUSH1 [1 datoshi]
/// CALL 04 [512 datoshi]
/// DROP [2 datoshi]
/// RET [0 datoshi]
/// </remarks>
[DisplayName("arrowMethodNoRerurn")]
public abstract void ArrowMethodNoRerurn();

/// <summary>
/// Unsafe method
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Inline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,17 @@ public void Test_NestedInline()
Assert.AreEqual(new BigInteger(3), Contract.TestInline("inline_nested"));
AssertGasConsumed(1071930);
}

[TestMethod]
public void Test_ArrowMethod()
{
Assert.AreEqual(new BigInteger(3), Contract.ArrowMethod());
}

[TestMethod]
public void Test_ArrowMethodNoReturn()
{
Contract.ArrowMethodNoRerurn();
}
}
}

0 comments on commit 8971d08

Please sign in to comment.