type CallExpr struct {
miniExpr
origNode
- X Node
- Args Nodes
- KeepAlive []*Name // vars to be kept alive until call returns
- IsDDD bool
- Use CallUse
- NoInline bool
- PreserveClosure bool // disable directClosureCall for this call
+ X Node
+ Args Nodes
+ KeepAlive []*Name // vars to be kept alive until call returns
+ IsDDD bool
+ Use CallUse
+ NoInline bool
}
func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr {
return // leave for walkClosure to handle
}
- // If wrapGoDefer() in the order phase has flagged this call,
- // avoid eliminating the closure even if there is a direct call to
- // (the closure is needed to simplify the register ABI). See
- // wrapGoDefer for more details.
- if n.PreserveClosure {
- return
- }
-
// We are going to insert captured variables before input args.
var params []*types.Field
var decls []*ir.Name
// TODO: maybe not wrap if the called function has no arguments and
// only in-register results?
if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
- if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE {
+ if callX.Op() == ir.OCLOSURE {
clo := callX.(*ir.ClosureExpr)
clo.Func.SetClosureCalled(false)
clo.IsGoWrap = true
- c.PreserveClosure = true
}
return
}
topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, nil)
typecheck.Call(topcall)
- // Tag the call to insure that directClosureCall doesn't undo our work.
- topcall.PreserveClosure = true
-
fn.SetClosureCalled(false)
// Finally, point the defer statement at the newly generated call.