compiler: do not allocate slotes for unused "_" vars

This commit is contained in:
Evgenii Stratonikov 2020-09-06 15:26:03 +03:00
parent 0b44a43043
commit 18369c489e
3 changed files with 29 additions and 7 deletions

View file

@ -112,7 +112,11 @@ func countGlobals(f ast.Node) (i int) {
case *ast.GenDecl: case *ast.GenDecl:
if n.Tok == token.VAR { if n.Tok == token.VAR {
for _, s := range n.Specs { for _, s := range n.Specs {
i += len(s.(*ast.ValueSpec).Names) for _, id := range s.(*ast.ValueSpec).Names {
if id.Name != "_" {
i++
}
}
} }
} }
return false return false

View file

@ -434,6 +434,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
switch t := spec.(type) { switch t := spec.(type) {
case *ast.ValueSpec: case *ast.ValueSpec:
for _, id := range t.Names { for _, id := range t.Names {
if id.Name != "_" {
if c.scope == nil { if c.scope == nil {
// it is a global declaration // it is a global declaration
c.newGlobal("", id.Name) c.newGlobal("", id.Name)
@ -442,6 +443,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
} }
c.registerDebugVariable(id.Name, t.Type) c.registerDebugVariable(id.Name, t.Type)
} }
}
for i := range t.Names { for i := range t.Names {
if len(t.Values) != 0 { if len(t.Values) != 0 {
ast.Walk(c, t.Values[i]) ast.Walk(c, t.Values[i])

View file

@ -255,3 +255,19 @@ func TestConstDontUseSlots(t *testing.T) {
src := buf.String() src := buf.String()
eval(t, src, big.NewInt(count)) eval(t, src, big.NewInt(count))
} }
func TestUnderscoreVarsDontUseSlots(t *testing.T) {
const count = 128
buf := bytes.NewBufferString("package foo\n")
for i := 0; i < count; i++ {
buf.WriteString(fmt.Sprintf("var _, n%d = 1, 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))
}