mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
[dev.typeparams] cmd/compile: refactor CaptureName
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>
This commit is contained in:
parent
62095c66e0
commit
c4e0c652fb
|
@ -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.Op() != ONAME || n.Curfn == nil {
|
||||
return n // okay to use directly
|
||||
}
|
||||
if n.IsClosureVar() {
|
||||
base.FatalfAt(pos, "misuse of CaptureName on closure variable: %v", n)
|
||||
}
|
||||
if n.Op() != ONAME || n.Curfn == nil || n.Curfn == fn {
|
||||
return n // okay to use directly
|
||||
|
||||
c := n.Innermost
|
||||
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)
|
||||
}
|
||||
|
||||
c := n.Innermost
|
||||
if c != nil && c.Curfn == fn {
|
||||
return c
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue