aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/stencil.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/noder/stencil.go')
-rw-r--r--src/cmd/compile/internal/noder/stencil.go47
1 files changed, 16 insertions, 31 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go
index 3e3de1908e..a82274a240 100644
--- a/src/cmd/compile/internal/noder/stencil.go
+++ b/src/cmd/compile/internal/noder/stencil.go
@@ -280,8 +280,8 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
// }
// Make a new internal function.
- fn := ir.NewFunc(pos)
- fn.SetIsHiddenClosure(true)
+ fn := ir.NewClosureFunc(pos, outer)
+ ir.NameClosure(fn.OClosure, outer)
// This is the dictionary we want to use.
// It may be a constant, or it may be a dictionary acquired from the outer function's dictionary.
@@ -346,13 +346,8 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
// Build an internal function with the right signature.
closureType := types.NewSignature(x.Type().Pkg(), nil, nil, formalParams, formalResults)
- sym := typecheck.ClosureName(outer)
- sym.SetFunc(true)
- fn.Nname = ir.NewNameAt(pos, sym)
- fn.Nname.Class = ir.PFUNC
- fn.Nname.Func = fn
- fn.Nname.Defn = fn
typed(closureType, fn.Nname)
+ typed(x.Type(), fn.OClosure)
fn.SetTypecheck(1)
// Build body of closure. This involves just calling the wrapped function directly
@@ -401,15 +396,12 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
typecheck.Stmt(innerCall)
ir.CurFunc = nil
fn.Body = []ir.Node{innerCall}
- if outer == nil {
- g.target.Decls = append(g.target.Decls, fn)
- }
// We're all done with the captured dictionary (and receiver, for method values).
ir.FinishCaptureNames(pos, outer, fn)
// Make a closure referencing our new internal function.
- c := ir.NewClosureExpr(pos, fn)
+ c := ir.UseClosure(fn.OClosure, g.target)
var init []ir.Node
if outer != nil {
init = append(init, dictAssign)
@@ -417,9 +409,7 @@ func (g *irgen) buildClosure(outer *ir.Func, x ir.Node) ir.Node {
if rcvrValue != nil {
init = append(init, rcvrAssign)
}
- c.SetInit(init)
- typed(x.Type(), c)
- return c
+ return ir.InitExpr(init, c)
}
// instantiateMethods instantiates all the methods of all fully-instantiated
@@ -859,24 +849,18 @@ func (subst *subster) node(n ir.Node) ir.Node {
}
case ir.OCLOSURE:
+ // We're going to create a new closure from scratch, so clear m
+ // to avoid using the ir.Copy by accident until we reassign it.
+ m = nil
+
x := x.(*ir.ClosureExpr)
// Need to duplicate x.Func.Nname, x.Func.Dcl, x.Func.ClosureVars, and
// x.Func.Body.
oldfn := x.Func
- newfn := ir.NewFunc(oldfn.Pos())
- if oldfn.ClosureCalled() {
- newfn.SetClosureCalled(true)
- }
- newfn.SetIsHiddenClosure(true)
- m.(*ir.ClosureExpr).Func = newfn
- // Closure name can already have brackets, if it derives
- // from a generic method
- newsym := typecheck.MakeInstName(oldfn.Nname.Sym(), subst.ts.Targs, subst.isMethod)
- newfn.Nname = ir.NewNameAt(oldfn.Nname.Pos(), newsym)
- newfn.Nname.Func = newfn
- newfn.Nname.Defn = newfn
- ir.MarkFunc(newfn.Nname)
- newfn.OClosure = m.(*ir.ClosureExpr)
+ newfn := ir.NewClosureFunc(oldfn.Pos(), subst.newf)
+ ir.NameClosure(newfn.OClosure, subst.newf)
+
+ newfn.SetClosureCalled(oldfn.ClosureCalled())
saveNewf := subst.newf
ir.CurFunc = newfn
@@ -885,7 +869,7 @@ func (subst *subster) node(n ir.Node) ir.Node {
newfn.ClosureVars = subst.namelist(oldfn.ClosureVars)
typed(subst.ts.Typ(oldfn.Nname.Type()), newfn.Nname)
- typed(newfn.Nname.Type(), m)
+ typed(newfn.Nname.Type(), newfn.OClosure)
newfn.SetTypecheck(1)
// Make sure type of closure function is set before doing body.
@@ -893,7 +877,8 @@ func (subst *subster) node(n ir.Node) ir.Node {
subst.newf = saveNewf
ir.CurFunc = saveNewf
- subst.g.target.Decls = append(subst.g.target.Decls, newfn)
+ m = ir.UseClosure(newfn.OClosure, subst.g.target)
+ m.(*ir.ClosureExpr).SetInit(subst.list(x.Init()))
case ir.OCONVIFACE:
x := x.(*ir.ConvExpr)