]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: refactor CaptureName
authorMatthew Dempsky <mdempsky@google.com>
Wed, 23 Jun 2021 01:10:59 +0000 (18:10 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 23 Jun 2021 04:03:38 +0000 (04:03 +0000)
CaptureName currently does a few things: checks if a variable needs to
be captured at all; checks if the variable has already been captured;
and creates and saves a new variable. This full suite of functionality
is useful for noder and irgen, but unified IR and other backend code
only has a need for the last feature.

This CL refactors CaptureName a little bit and extracts out
NewClosureVar as a function usable for callers that don't need the
extra features of CaptureName.

Change-Id: I8a67c6375e44babe53344bf78e335535c57f9607
Reviewed-on: https://go-review.googlesource.com/c/go/+/330193
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/ir/name.go
src/cmd/compile/internal/noder/reader.go

index b6c68bc5e01a4b33d8b590f29658886446584fbf..ff9784df1b15a16ab8dfb5c4eb0903b0f3c406e2 100644 (file)
@@ -358,39 +358,52 @@ func (n *Name) Byval() bool {
        return n.Canonical().flags&nameByval != 0
 }
 
+// NewClosureVar creates a new closure variable for fn to refer to
+// outer variable n.
+func NewClosureVar(pos src.XPos, fn *Func, n *Name) *Name {
+       c := NewNameAt(pos, n.Sym())
+       c.Curfn = fn
+       c.Class = PAUTOHEAP
+       c.SetIsClosureVar(true)
+       c.Defn = n.Canonical()
+       c.Outer = n
+
+       fn.ClosureVars = append(fn.ClosureVars, c)
+
+       return c
+}
+
 // CaptureName returns a Name suitable for referring to n from within function
 // fn or from the package block if fn is nil. If n is a free variable declared
-// within a function that encloses fn, then CaptureName returns a closure
-// variable that refers to n and adds it to fn.ClosureVars. Otherwise, it simply
-// returns n.
+// within a function that encloses fn, then CaptureName returns the closure
+// variable that refers to n within fn, creating it if necessary.
+// Otherwise, it simply returns n.
 func CaptureName(pos src.XPos, fn *Func, n *Name) *Name {
-       if n.IsClosureVar() {
-               base.FatalfAt(pos, "misuse of CaptureName on closure variable: %v", n)
-       }
-       if n.Op() != ONAME || n.Curfn == nil || n.Curfn == fn {
+       if n.Op() != ONAME || n.Curfn == nil {
                return n // okay to use directly
        }
-       if fn == nil {
-               base.FatalfAt(pos, "package-block reference to %v, declared in %v", n, n.Curfn)
+       if n.IsClosureVar() {
+               base.FatalfAt(pos, "misuse of CaptureName on closure variable: %v", n)
        }
 
        c := n.Innermost
-       if c != nil && c.Curfn == fn {
+       if c == nil {
+               c = n
+       }
+       if c.Curfn == fn {
                return c
        }
 
+       if fn == nil {
+               base.FatalfAt(pos, "package-block reference to %v, declared in %v", n, n.Curfn)
+       }
+
        // Do not have a closure var for the active closure yet; make one.
-       c = NewNameAt(pos, n.Sym())
-       c.Curfn = fn
-       c.Class = PAUTOHEAP
-       c.SetIsClosureVar(true)
-       c.Defn = n
+       c = NewClosureVar(pos, fn, c)
 
        // Link into list of active closure variables.
        // Popped from list in FinishCaptureNames.
-       c.Outer = n.Innermost
        n.Innermost = c
-       fn.ClosureVars = append(fn.ClosureVars, c)
 
        return c
 }
index 4fc9e7a777a7bcb43019305b1c3b7f924fbec81e..b106e89892781e95c47c2c75fc285444fe666f4d 100644 (file)
@@ -1558,20 +1558,13 @@ func (r *reader) funcLit() ir.Node {
                fn.Nname.Ntype = ir.TypeNodeAt(typPos, xtype2)
        }
 
-       fn.ClosureVars = make([]*ir.Name, r.len())
-       for i := range fn.ClosureVars {
+       fn.ClosureVars = make([]*ir.Name, 0, r.len())
+       for len(fn.ClosureVars) < cap(fn.ClosureVars) {
                pos := r.pos()
                outer := r.useLocal()
 
-               cv := ir.NewNameAt(pos, outer.Sym())
+               cv := ir.NewClosureVar(pos, fn, outer)
                r.setType(cv, outer.Type())
-               cv.Curfn = fn
-               cv.Class = ir.PAUTOHEAP
-               cv.SetIsClosureVar(true)
-               cv.Defn = outer.Canonical()
-               cv.Outer = outer
-
-               fn.ClosureVars[i] = cv
        }
 
        r.addBody(fn)