diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 4b7c3f2d2..90f4d62c9 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -708,6 +708,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { numArgs = len(n.Args) isBuiltin bool isFunc bool + isLiteral bool ) switch fun := n.Fun.(type) { @@ -746,6 +747,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { ast.Walk(c, n.Args[0]) c.emitConvert(stackitem.BufferT) return nil + case *ast.FuncLit: + isLiteral = true } c.saveSequencePoint(n) @@ -798,6 +801,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadVar("", name) emit.Opcode(c.prog.BinWriter, opcode.CALLA) } + case isLiteral: + ast.Walk(c, n.Fun) + emit.Opcode(c.prog.BinWriter, opcode.CALLA) case isSyscall(f): c.convertSyscall(n, f.pkg.Name(), f.name) default: diff --git a/pkg/compiler/lambda_test.go b/pkg/compiler/lambda_test.go index d9ab32613..f3e7132a7 100644 --- a/pkg/compiler/lambda_test.go +++ b/pkg/compiler/lambda_test.go @@ -13,3 +13,16 @@ func TestFuncLiteral(t *testing.T) { }` eval(t, src, big.NewInt(5)) } + +func TestCallInPlace(t *testing.T) { + src := `package foo + var a int = 1 + func Main() int { + func() { + a += 10 + }() + a += 100 + return a + }` + eval(t, src, big.NewInt(111)) +}