From 60a3e0d778c2baf1e1fcdb8d5496be07f99ff879 Mon Sep 17 00:00:00 2001 From: Evgeniy Stratonikov Date: Wed, 28 Apr 2021 16:37:31 +0300 Subject: [PATCH] compiler: count auxiliary locals introduced by inlining During initialization of globals no function scope is present thus locals number is not saved anywere. Save it in `codegen` directly. --- pkg/compiler/analysis.go | 4 ++++ pkg/compiler/codegen.go | 3 +++ pkg/compiler/inline.go | 7 ++++++- pkg/compiler/syscall_test.go | 2 -- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index e9ead23b9..019f4a7c9 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -98,6 +98,10 @@ func (c *codegen) traverseGlobals() bool { c.scope = nil }) + if c.globalInlineCount > maxCnt { + maxCnt = c.globalInlineCount + } + // Here we remove `INITSLOT` if no code was emitted for `init` function. // Note that the `INITSSLOT` must stay in place. hasNoInit := initOffset+3 == c.prog.Len() diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 6081eda8a..c2cf96533 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -61,6 +61,9 @@ type codegen struct { // inlineLabelOffsets contains size of labelList at the start of inline call processing. // For such calls we need to drop only newly created part of stack. inlineLabelOffsets []int + // globalInlineCount contains amount of auxiliary variables introduced by + // function inlining during global variables initialization. + globalInlineCount int // A label for the for-loop being currently visited. currentFor string diff --git a/pkg/compiler/inline.go b/pkg/compiler/inline.go index f3471863b..d3653941b 100644 --- a/pkg/compiler/inline.go +++ b/pkg/compiler/inline.go @@ -32,7 +32,12 @@ func (c *codegen) inlineCall(f *funcScope, n *ast.CallExpr) { if c.scope == nil { c.scope = &funcScope{} c.scope.vars.newScope() - defer func() { c.scope = nil }() + defer func() { + if cnt := c.scope.vars.localsCnt; cnt > c.globalInlineCount { + c.globalInlineCount = cnt + } + c.scope = nil + }() } // Arguments need to be walked with the current scope, diff --git a/pkg/compiler/syscall_test.go b/pkg/compiler/syscall_test.go index 4a5df2d6e..86adb3306 100644 --- a/pkg/compiler/syscall_test.go +++ b/pkg/compiler/syscall_test.go @@ -191,8 +191,6 @@ func TestNotify(t *testing.T) { } func TestSyscallInGlobalInit(t *testing.T) { - // FIXME(fyrchik): count auxiliary inline locals for INITSLOT in global context - t.Skip() src := `package foo import "github.com/nspcc-dev/neo-go/pkg/interop/runtime" var a = runtime.CheckWitness([]byte("5T"))