diff options
Diffstat (limited to 'src/cmd/compile/internal/gc/closure.go')
-rw-r--r-- | src/cmd/compile/internal/gc/closure.go | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 04f3e669e2..143e1969c7 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -5,19 +5,21 @@ package gc import ( + "cmd/compile/internal/syntax" "cmd/compile/internal/types" "fmt" ) -// function literals aka closures -func closurehdr(ntype *Node) { - n := nod(OCLOSURE, nil, nil) +func (p *noder) funcLit(expr *syntax.FuncLit) *Node { + ntype := p.typeExpr(expr.Type) + + n := p.nod(expr, OCLOSURE, nil, nil) n.Func.SetIsHiddenClosure(Curfn != nil) n.Func.Ntype = ntype n.Func.Depth = funcdepth n.Func.Outerfunc = Curfn - funchdr(n) + old := p.funchdr(n, expr.Pos()) // steal ntype's argument names and // leave a fresh copy in their place. @@ -25,8 +27,8 @@ func closurehdr(ntype *Node) { // refer to the variables in the external // function declared below; see walkclosure. n.List.Set(ntype.List.Slice()) - n.Rlist.Set(ntype.Rlist.Slice()) + ntype.List.Set(nil) ntype.Rlist.Set(nil) for _, n1 := range n.List.Slice() { @@ -48,23 +50,23 @@ func closurehdr(ntype *Node) { } ntype.Rlist.Append(nod(ODCLFIELD, name, n2.Right)) } -} -func closurebody(body []*Node) *Node { + body := p.stmts(expr.Body.List) + + lineno = Ctxt.PosTable.XPos(expr.Body.Rbrace) if len(body) == 0 { body = []*Node{nod(OEMPTY, nil, nil)} } - func_ := Curfn - func_.Nbody.Set(body) - func_.Func.Endlineno = lineno - funcbody(func_) + n.Nbody.Set(body) + n.Func.Endlineno = lineno + p.funcbody(n, expr.Body.Rbrace, old) // 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 func_.Func.Cvars.Slice() { + for _, v := range n.Func.Cvars.Slice() { // Unlink from v1; see comment in syntax.go type Param for these fields. v1 := v.Name.Defn v1.Name.Param.Innermost = v.Name.Param.Outer @@ -100,7 +102,7 @@ func closurebody(body []*Node) *Node { v.Name.Param.Outer = oldname(v.Sym) } - return func_ + return n } func typecheckclosure(func_ *Node, top int) { @@ -227,7 +229,11 @@ func makeclosure(func_ *Node) *Node { xfunc.Nbody.Set(func_.Nbody.Slice()) xfunc.Func.Dcl = append(func_.Func.Dcl, xfunc.Func.Dcl...) + xfunc.Func.Parents = func_.Func.Parents + xfunc.Func.Marks = func_.Func.Marks func_.Func.Dcl = nil + func_.Func.Parents = nil + func_.Func.Marks = nil if xfunc.Nbody.Len() == 0 { Fatalf("empty body - won't generate any code") } |