diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2023-08-16 21:16:29 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2023-08-17 19:36:29 +0000 |
| commit | f4e6815652cf3c4803001dd9ab7f0d7f125a466c (patch) | |
| tree | 5ae59cbf9e4055a08d1f8e594ade2c806cc840b7 /src/cmd/compile/internal/noder/reader.go | |
| parent | 4e411e7bc44378422fa52f478927d9f71c39f385 (diff) | |
| download | go-f4e6815652cf3c4803001dd9ab7f0d7f125a466c.tar.xz | |
cmd/compile/internal/noder: remove inlined closure naming hack
I previously used a clumsy hack to copy Closgen back and forth while
inlining, to handle when an inlined function contains closures, which
need to each be uniquely numbered.
The real solution was to name the closures using r.inlCaller, rather
than r.curfn. This CL adds a helper method to do exactly this.
Change-Id: I510553b5d7a8f6581ea1d21604e834fd6338cb06
Reviewed-on: https://go-review.googlesource.com/c/go/+/520339
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/reader.go')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 59b10b3b33..a07fec68ec 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -2722,15 +2722,12 @@ func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack b return false } - // The ODCLFUNC and its body need to use the original position, but - // the OCLOSURE node and any Init statements should use the inlined - // position instead. See also the explanation in reader.funcLit. - inlPos := r.inlPos(origPos) - - // TODO(mdempsky): Remove hard-coding of typecheck.Target. - fn := ir.NewClosureFunc(origPos, inlPos, typ, r.curfn, typecheck.Target) + fn := r.inlClosureFunc(origPos, typ) fn.SetWrapper(true) + clo := fn.OClosure + inlPos := clo.Pos() + var init ir.Nodes for i, n := range captures { if isSafe(n) { @@ -2766,7 +2763,7 @@ func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack b bodyReader[fn] = pri pri.funcBody(fn) - return ir.InitExpr(init, fn.OClosure) + return ir.InitExpr(init, clo) } // syntheticSig duplicates and returns the params and results lists @@ -3114,15 +3111,16 @@ func (r *reader) funcLit() ir.Node { // OCLOSURE node, because that position represents where any heap // allocation of the closure is credited (#49171). r.suppressInlPos++ - pos := r.pos() - xtype2 := r.signature(nil) + origPos := r.pos() + sig := r.signature(nil) r.suppressInlPos-- - // TODO(mdempsky): Remove hard-coding of typecheck.Target. - fn := ir.NewClosureFunc(pos, r.inlPos(pos), xtype2, r.curfn, typecheck.Target) + fn := r.inlClosureFunc(origPos, sig) fn.ClosureVars = make([]*ir.Name, 0, r.Len()) for len(fn.ClosureVars) < cap(fn.ClosureVars) { + // TODO(mdempsky): I think these should be original positions too + // (i.e., not inline-adjusted). ir.NewClosureVar(r.pos(), fn, r.useLocal()) } if param := r.dictParam; param != nil { @@ -3136,6 +3134,18 @@ func (r *reader) funcLit() ir.Node { return fn.OClosure } +// inlClosureFunc constructs a new closure function, but correctly +// handles inlining. +func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type) *ir.Func { + curfn := r.inlCaller + if curfn == nil { + curfn = r.curfn + } + + // TODO(mdempsky): Remove hard-coding of typecheck.Target. + return ir.NewClosureFunc(origPos, r.inlPos(origPos), sig, curfn, typecheck.Target) +} + func (r *reader) exprList() []ir.Node { r.Sync(pkgbits.SyncExprList) return r.exprs() @@ -3451,10 +3461,7 @@ func unifiedInlineCall(call *ir.CallExpr, fn *ir.Func, inlIndex int) *ir.Inlined r := pri.asReader(pkgbits.RelocBody, pkgbits.SyncFuncBody) - // TODO(mdempsky): This still feels clumsy. Can we do better? tmpfn := ir.NewFunc(fn.Pos(), fn.Nname.Pos(), callerfn.Sym(), fn.Type()) - tmpfn.Closgen = callerfn.Closgen - defer func() { callerfn.Closgen = tmpfn.Closgen }() r.curfn = tmpfn |
