aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/noder.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-01-11 15:58:19 -0800
committerMatthew Dempsky <mdempsky@google.com>2021-01-12 02:46:27 +0000
commitb4d2a0445b0ca54a159e0895e1a8b31d47411894 (patch)
tree2749d36d62ec3b0ea128e39766c49527cfc73978 /src/cmd/compile/internal/noder/noder.go
parentf57f484053f276c6fb57047cf02fa043974d7b95 (diff)
downloadgo-b4d2a0445b0ca54a159e0895e1a8b31d47411894.tar.gz
go-b4d2a0445b0ca54a159e0895e1a8b31d47411894.zip
[dev.regabi] cmd/compile: refactor closure var setup/teardown
Creating closure vars is subtle and is also needed in both CL 281932 and CL 283112, so refactor out a common implementation that can be used in all 3 places. Passes toolstash -cmp. Change-Id: Ib993eb90c895b52759bfbfbaad88921e391b0b4d Reviewed-on: https://go-review.googlesource.com/c/go/+/283194 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com> Trust: Dan Scales <danscales@google.com> Trust: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/noder.go')
-rw-r--r--src/cmd/compile/internal/noder/noder.go64
1 files changed, 3 insertions, 61 deletions
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index 76913c62a6..ec0debdbbd 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -1872,45 +1872,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) ir.Node {
p.funcBody(fn, expr.Body)
- // closure-specific variables are hanging off the
- // ordinary ones in the symbol table; see oldname.
- // unhook them.
- // make the list of pointers for the closure call.
- for _, v := range fn.ClosureVars {
- // Unlink from v1; see comment in syntax.go type Param for these fields.
- v1 := v.Defn
- v1.Name().Innermost = v.Outer
-
- // If the closure usage of v is not dense,
- // we need to make it dense; now that we're out
- // of the function in which v appeared,
- // look up v.Sym in the enclosing function
- // and keep it around for use in the compiled code.
- //
- // That is, suppose we just finished parsing the innermost
- // closure f4 in this code:
- //
- // func f() {
- // v := 1
- // func() { // f2
- // use(v)
- // func() { // f3
- // func() { // f4
- // use(v)
- // }()
- // }()
- // }()
- // }
- //
- // At this point v.Outer is f2's v; there is no f3's v.
- // To construct the closure f4 from within f3,
- // we need to use f3's v and in this case we need to create f3's v.
- // We are now in the context of f3, so calling oldname(v.Sym)
- // obtains f3's v, creating it if necessary (as it is in the example).
- //
- // capturevars will decide whether to use v directly or &v.
- v.Outer = oldname(v.Sym()).(*ir.Name)
- }
+ ir.FinishCaptureNames(base.Pos, ir.CurFunc, fn)
return clo
}
@@ -1944,32 +1906,12 @@ func oldname(s *types.Sym) ir.Node {
return ir.NewIdent(base.Pos, s)
}
- if ir.CurFunc != nil && n.Op() == ir.ONAME && n.Name().Curfn != nil && n.Name().Curfn != ir.CurFunc {
- // Inner func is referring to var in outer func.
- //
+ if n, ok := n.(*ir.Name); ok {
// TODO(rsc): If there is an outer variable x and we
// are parsing x := 5 inside the closure, until we get to
// the := it looks like a reference to the outer x so we'll
// make x a closure variable unnecessarily.
- n := n.(*ir.Name)
- c := n.Innermost
- if c == nil || c.Curfn != ir.CurFunc {
- // Do not have a closure var for the active closure yet; make one.
- c = typecheck.NewName(s)
- c.Class = ir.PAUTOHEAP
- c.SetIsClosureVar(true)
- c.Defn = n
-
- // Link into list of active closure variables.
- // Popped from list in func funcLit.
- c.Outer = n.Innermost
- n.Innermost = c
-
- ir.CurFunc.ClosureVars = append(ir.CurFunc.ClosureVars, c)
- }
-
- // return ref to closure var, not original
- return c
+ return ir.CaptureName(base.Pos, ir.CurFunc, n)
}
return n