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.
This commit is contained in:
Evgeniy Stratonikov 2021-04-28 16:37:31 +03:00
parent 87a69b13f1
commit 60a3e0d778
4 changed files with 13 additions and 3 deletions

View file

@ -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()

View file

@ -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

View file

@ -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,

View file

@ -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"))