mirror of
https://github.com/golang/go
synced 2024-11-22 22:40:02 -07:00
[dev.regabi] cmd/compile: use ClosureVars for method value wrappers
Similar to with regular closures, we can change method value wrappers to use ClosureVars and allow SSA construction to take care of wiring it up appropriately. Change-Id: I05c0b1bcec4e24305324755df35b7bc5b8a6ce7a Reviewed-on: https://go-review.googlesource.com/c/go/+/281353 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
950cf4d46c
commit
c9c26d7ffb
@ -583,6 +583,9 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
|
||||
if n.Class == ir.PFUNC || n.Class == ir.PEXTERN {
|
||||
return
|
||||
}
|
||||
if n.IsClosureVar() && n.Defn == nil {
|
||||
return // ".this" from method value wrapper
|
||||
}
|
||||
e.flow(k, e.oldLoc(n))
|
||||
|
||||
case ir.ONAMEOFFSET:
|
||||
|
@ -264,7 +264,7 @@ const (
|
||||
nameNeedzero // if it contains pointers, needs to be zeroed on function entry
|
||||
nameAutoTemp // is the variable a temporary (implies no dwarf info. reset if escapes to heap)
|
||||
nameUsed // for variable declared and not used error
|
||||
nameIsClosureVar // PAUTOHEAP closure pseudo-variable; original at n.Name.Defn
|
||||
nameIsClosureVar // PAUTOHEAP closure pseudo-variable; original (if any) at n.Defn
|
||||
nameIsOutputParamHeapAddr // pointer to a result parameter's heap copy
|
||||
nameAddrtaken // address taken, even if not moved to heap
|
||||
nameInlFormal // PAUTO created by inliner, derived from callee formal
|
||||
@ -332,7 +332,7 @@ func (n *Name) SetVal(v constant.Value) {
|
||||
// it appears in the function that immediately contains the
|
||||
// declaration. Otherwise, Canonical simply returns n itself.
|
||||
func (n *Name) Canonical() *Name {
|
||||
if n.IsClosureVar() {
|
||||
if n.IsClosureVar() && n.Defn != nil {
|
||||
n = n.Defn.(*Name)
|
||||
}
|
||||
return n
|
||||
|
@ -246,29 +246,26 @@ func MethodValueWrapper(dot *ir.SelectorExpr) *ir.Func {
|
||||
fn.SetWrapper(true)
|
||||
|
||||
// Declare and initialize variable holding receiver.
|
||||
cr := ir.NewClosureRead(rcvrtype, types.Rnd(int64(types.PtrSize), int64(rcvrtype.Align)))
|
||||
var ptr *ir.Name
|
||||
var body []ir.Node
|
||||
if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
|
||||
ptr = Temp(rcvrtype)
|
||||
body = append(body, ir.NewAssignStmt(base.Pos, ptr, cr))
|
||||
} else {
|
||||
ptr = Temp(types.NewPtr(rcvrtype))
|
||||
body = append(body, ir.NewAssignStmt(base.Pos, ptr, NodAddr(cr)))
|
||||
}
|
||||
ptr := ir.NewNameAt(base.Pos, Lookup(".this"))
|
||||
ptr.Class = ir.PAUTOHEAP
|
||||
ptr.SetType(rcvrtype)
|
||||
ptr.Curfn = fn
|
||||
ptr.SetIsClosureVar(true)
|
||||
ptr.SetByval(true)
|
||||
fn.ClosureVars = append(fn.ClosureVars, ptr)
|
||||
|
||||
call := ir.NewCallExpr(base.Pos, ir.OCALL, ir.NewSelectorExpr(base.Pos, ir.OXDOT, ptr, meth), nil)
|
||||
call.Args = ir.ParamNames(tfn.Type())
|
||||
call.IsDDD = tfn.Type().IsVariadic()
|
||||
|
||||
var body ir.Node = call
|
||||
if t0.NumResults() != 0 {
|
||||
ret := ir.NewReturnStmt(base.Pos, nil)
|
||||
ret.Results = []ir.Node{call}
|
||||
body = append(body, ret)
|
||||
} else {
|
||||
body = append(body, call)
|
||||
body = ret
|
||||
}
|
||||
|
||||
fn.Body = body
|
||||
fn.Body = []ir.Node{body}
|
||||
FinishFuncBody()
|
||||
|
||||
Func(fn)
|
||||
|
Loading…
Reference in New Issue
Block a user