From cddd5e1f6d6e6128f05364745bf11e14d8712b07 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 30 Nov 2021 18:02:38 +0300 Subject: [PATCH 1/2] compiler: add a panic on internal lambda inconsistency It's a bit better than behavior observer in #2281 (which is very cryptic). --- pkg/compiler/codegen.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index ab66620ed..b5cdc0480 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -514,6 +514,9 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl, pkg *types. if !isLambda { for _, f := range c.lambda { + if _, ok := c.lambda[c.getIdentName("", f.decl.Name.Name)]; !ok { + panic("ICE: lambda name doesn't match map key") + } c.convertFuncDecl(file, f.decl, pkg) } c.lambda = make(map[string]*funcScope) From f12f871432ece2a940841e03877cbb1862d54b25 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 30 Nov 2021 18:03:21 +0300 Subject: [PATCH 2/2] compiler: use new defer stack for inlined functions, fix #2281 Inlined functions shouldn't care about outer scope defer statements, they can't. --- pkg/compiler/defer_test.go | 18 ++++++++++++++++++ pkg/compiler/inline.go | 4 ++++ 2 files changed, 22 insertions(+) diff --git a/pkg/compiler/defer_test.go b/pkg/compiler/defer_test.go index 5d6784da1..37e43c6d8 100644 --- a/pkg/compiler/defer_test.go +++ b/pkg/compiler/defer_test.go @@ -50,6 +50,24 @@ func TestDefer(t *testing.T) { func f() { a += 2 }` eval(t, src, big.NewInt(10)) }) + t.Run("DeferAfterInterop", func(t *testing.T) { + src := `package main + + import ( + "github.com/nspcc-dev/neo-go/pkg/interop/storage" + ) + + func Main() { + defer func() { + }() + storage.GetContext() + }` + vm := vmAndCompile(t, src) + err := vm.Run() + require.NoError(t, err) + require.Equal(t, 0, vm.Estack().Len(), "stack contains unexpected items") + }) + t.Run("MultipleDefers", func(t *testing.T) { src := `package main var a int diff --git a/pkg/compiler/inline.go b/pkg/compiler/inline.go index 31329ddae..702ef46e2 100644 --- a/pkg/compiler/inline.go +++ b/pkg/compiler/inline.go @@ -99,6 +99,8 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) { c.pkgInfoInline = append(c.pkgInfoInline, pkg) oldMap := c.importMap + oldDefers := c.scope.deferStack + c.scope.deferStack = nil c.fillImportMap(f.file, pkg.Pkg) ast.Inspect(f.decl, c.scope.analyzeVoidCalls) ast.Walk(c, f.decl.Body) @@ -107,6 +109,8 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) { emit.Opcodes(c.prog.BinWriter, opcode.DROP) } } + c.processDefers() + c.scope.deferStack = oldDefers c.importMap = oldMap c.pkgInfoInline = c.pkgInfoInline[:len(c.pkgInfoInline)-1] }