diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index 112c6945d..a28a8386a 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -121,7 +121,7 @@ func (c *codegen) traverseGlobals() (int, int, int) { // store auxiliary variables after all others. if hasDefer { c.exceptionIndex = len(c.globals) - c.globals[""] = c.exceptionIndex + c.globals[exceptionVarName] = c.exceptionIndex } } return n, initLocals, deployLocals diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 81d5dedcd..7822d1e0d 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -1296,7 +1296,9 @@ func (c *codegen) processDefers() { c.setLabel(stmt.catchLabel) c.emitStoreByIndex(varGlobal, c.exceptionIndex) emit.Int(c.prog.BinWriter, 1) - c.emitStoreByIndex(varLocal, c.scope.finallyProcessedIndex) + + finalIndex := c.getVarIndex("", finallyVarName).index + c.emitStoreByIndex(varLocal, finalIndex) ast.Walk(c, stmt.expr) if i == 0 { // After panic, default values must be returns, except for named returns, @@ -1309,12 +1311,12 @@ func (c *codegen) processDefers() { c.setLabel(stmt.finallyLabel) before := c.newLabel() - c.emitLoadByIndex(varLocal, c.scope.finallyProcessedIndex) + c.emitLoadByIndex(varLocal, finalIndex) emit.Jmp(c.prog.BinWriter, opcode.JMPIFL, before) ast.Walk(c, stmt.expr) c.setLabel(before) emit.Int(c.prog.BinWriter, 0) - c.emitStoreByIndex(varLocal, c.scope.finallyProcessedIndex) + c.emitStoreByIndex(varLocal, finalIndex) emit.Opcodes(c.prog.BinWriter, opcode.ENDFINALLY) c.setLabel(after) } diff --git a/pkg/compiler/func_scope.go b/pkg/compiler/func_scope.go index 672b839ef..e09d7a6b9 100644 --- a/pkg/compiler/func_scope.go +++ b/pkg/compiler/func_scope.go @@ -34,9 +34,6 @@ type funcScope struct { // deferStack is a stack containing encountered `defer` statements. deferStack []deferInfo - // finallyProcessed is a index of static slot with boolean flag determining - // if `defer` statement was already processed. - finallyProcessedIndex int // Local variables vars varScope @@ -59,6 +56,11 @@ type deferInfo struct { expr *ast.CallExpr } +const ( + finallyVarName = "" + exceptionVarName = "" +) + func (c *codegen) newFuncScope(decl *ast.FuncDecl, label uint16) *funcScope { var name string if decl.Name != nil { @@ -204,7 +206,6 @@ func (c *codegen) countLocalsInline(decl *ast.FuncDecl, pkg *types.Package, f *f func (c *codegen) countLocalsWithDefer(f *funcScope) int { size, hasDefer := c.countLocals(f.decl) if hasDefer { - f.finallyProcessedIndex = size size++ } return size