Merge pull request #2282 from nspcc-dev/defer-after-interop

Fix defers in functions using inlined calls
This commit is contained in:
Roman Khimov 2021-11-30 18:14:13 +03:00 committed by GitHub
commit c14376473b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 0 deletions

View file

@ -514,6 +514,9 @@ func (c *codegen) convertFuncDecl(file ast.Node, decl *ast.FuncDecl, pkg *types.
if !isLambda { if !isLambda {
for _, f := range c.lambda { 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.convertFuncDecl(file, f.decl, pkg)
} }
c.lambda = make(map[string]*funcScope) c.lambda = make(map[string]*funcScope)

View file

@ -50,6 +50,24 @@ func TestDefer(t *testing.T) {
func f() { a += 2 }` func f() { a += 2 }`
eval(t, src, big.NewInt(10)) 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) { t.Run("MultipleDefers", func(t *testing.T) {
src := `package main src := `package main
var a int var a int

View file

@ -99,6 +99,8 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) {
c.pkgInfoInline = append(c.pkgInfoInline, pkg) c.pkgInfoInline = append(c.pkgInfoInline, pkg)
oldMap := c.importMap oldMap := c.importMap
oldDefers := c.scope.deferStack
c.scope.deferStack = nil
c.fillImportMap(f.file, pkg.Pkg) c.fillImportMap(f.file, pkg.Pkg)
ast.Inspect(f.decl, c.scope.analyzeVoidCalls) ast.Inspect(f.decl, c.scope.analyzeVoidCalls)
ast.Walk(c, f.decl.Body) 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) emit.Opcodes(c.prog.BinWriter, opcode.DROP)
} }
} }
c.processDefers()
c.scope.deferStack = oldDefers
c.importMap = oldMap c.importMap = oldMap
c.pkgInfoInline = c.pkgInfoInline[:len(c.pkgInfoInline)-1] c.pkgInfoInline = c.pkgInfoInline[:len(c.pkgInfoInline)-1]
} }