return f.emit(e)
}
-// emitTailCall emits to f a function call in tail position.
+// emitTailCall emits to f a function call in tail position,
+// passing on all but the first formal parameter to f as actual
+// values in the call. Intended for delegating bridge methods.
// Precondition: f does/will not use deferred procedure calls.
// Postcondition: f.currentBlock is nil.
//
func emitTailCall(f *Function, call *Call) {
+ for _, arg := range f.Params[1:] {
+ call.Args = append(call.Args, arg)
+ }
+ call.Type_ = &types.Result{Values: f.Signature.Results}
tuple := f.emit(call)
var ret Ret
switch {
}
fn.start(nil)
fn.addSpilledParam(sig.Recv)
- var last *Parameter
- for _, p := range fn.Signature.Params {
- last = fn.addParam(p.Name, p.Type)
- }
- if fn.Signature.IsVariadic {
- last.Type_ = &types.Slice{Elt: last.Type_}
- }
+ createParams(fn)
// Each bridge method performs a sequence of selections,
// then tailcalls the promoted method.
fn.Pos = c.Func.(*Function).Pos // TODO(adonovan): fix: wrong.
c.Pos = fn.Pos // TODO(adonovan): fix: wrong.
c.Args = append(c.Args, v)
- for _, arg := range fn.Params[1:] {
- c.Args = append(c.Args, arg)
- }
} else {
c.Recv = v
c.Method = 0
- for _, arg := range fn.Params {
- c.Args = append(c.Args, arg)
- }
}
- c.Type_ = &types.Result{Values: sig.Results}
emitTailCall(fn, &c)
fn.finish()
return fn
}
+// createParams creates parameters for bridge method fn based on its Signature.
+func createParams(fn *Function) {
+ var last *Parameter
+ for i, p := range fn.Signature.Params {
+ name := p.Name
+ if name == "" {
+ name = fmt.Sprintf("arg%d", i)
+ }
+ last = fn.addParam(name, p.Type)
+ }
+ if fn.Signature.IsVariadic {
+ last.Type_ = &types.Slice{Elt: last.Type_}
+ }
+}
+
// Thunks for standalone interface methods ----------------------------------------
// makeImethodThunk returns a synthetic thunk function permitting an
// TODO(adonovan): set fn.Pos to location of interface method ast.Field.
fn.start(nil)
fn.addParam("recv", typ)
- var last *Parameter
- for _, p := range fn.Signature.Params {
- last = fn.addParam(p.Name, p.Type)
- }
- if fn.Signature.IsVariadic {
- last.Type_ = &types.Slice{Elt: last.Type_}
- }
-
+ createParams(fn)
var c Call
c.Method = index
c.Recv = fn.Params[0]
- for _, arg := range fn.Params[1:] {
- c.Args = append(c.Args, arg)
- }
- c.Type_ = &types.Result{Values: sig.Results}
emitTailCall(fn, &c)
fn.finish()
return fn