From 0b44a430430813c524bdebc279409d0e88e28818 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Sun, 6 Sep 2020 15:20:15 +0300 Subject: [PATCH] compiler: do not allocate static slot for constants Their value is known at compile time. --- pkg/compiler/analysis.go | 9 +++++++-- pkg/compiler/global_test.go | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/pkg/compiler/analysis.go b/pkg/compiler/analysis.go index 730a9bd89..190ea7511 100644 --- a/pkg/compiler/analysis.go +++ b/pkg/compiler/analysis.go @@ -109,8 +109,13 @@ func countGlobals(f ast.Node) (i int) { return false // After skipping all funcDecls we are sure that each value spec // is a global declared variable or constant. - case *ast.ValueSpec: - i += len(n.Names) + case *ast.GenDecl: + if n.Tok == token.VAR { + for _, s := range n.Specs { + i += len(s.(*ast.ValueSpec).Names) + } + } + return false } return true }) diff --git a/pkg/compiler/global_test.go b/pkg/compiler/global_test.go index e4f29f89b..b8ab1b045 100644 --- a/pkg/compiler/global_test.go +++ b/pkg/compiler/global_test.go @@ -1,6 +1,7 @@ package compiler_test import ( + "bytes" "fmt" "math/big" "strings" @@ -238,3 +239,19 @@ func TestMultipleFuncSameName(t *testing.T) { eval(t, src, big.NewInt(42)) }) } + +func TestConstDontUseSlots(t *testing.T) { + const count = 256 + buf := bytes.NewBufferString("package foo\n") + for i := 0; i < count; i++ { + buf.WriteString(fmt.Sprintf("const n%d = 1\n", i)) + } + buf.WriteString("func Main() int { sum := 0\n") + for i := 0; i < count; i++ { + buf.WriteString(fmt.Sprintf("sum += n%d\n", i)) + } + buf.WriteString("return sum }") + + src := buf.String() + eval(t, src, big.NewInt(count)) +}