(key selectionKey)
| 47 | } |
| 48 | |
| 49 | func (prog *Program) makeWrapperKey(key selectionKey) *Function { |
| 50 | obj := key.obj.(*Func) // the declared function |
| 51 | objSig := obj.Type().(*Signature) |
| 52 | objRecv := objSig.Recv() |
| 53 | |
| 54 | recv := NewVar(objRecv.Pos(), objRecv.Pkg(), objRecv.Name(), key.recv) |
| 55 | |
| 56 | var sig *Signature |
| 57 | |
| 58 | name := obj.Name() |
| 59 | var description string |
| 60 | var start int // first regular param |
| 61 | if key.kind == MethodExpr { |
| 62 | name += "$thunk" |
| 63 | description = "thunk" |
| 64 | start = 1 |
| 65 | |
| 66 | params := []*Var{recv} |
| 67 | for i := 0; i < objSig.Params().Len(); i++ { |
| 68 | params = append(params, objSig.Params().At(i)) |
| 69 | } |
| 70 | sig = NewSignatureType(nil, nil, nil, NewTuple(params...), objSig.Results(), objSig.Variadic()) |
| 71 | } else { |
| 72 | description = "wrapper" |
| 73 | sig = changeRecv(objSig, recv) |
| 74 | } |
| 75 | |
| 76 | description = fmt.Sprintf("%s for %s", description, key.obj) |
| 77 | if prog.mode&LogSource != 0 { |
| 78 | defer logStack("make %s to (%s)", description, recv.Type())() |
| 79 | } |
| 80 | |
| 81 | fn := &Function{ |
| 82 | name: name, |
| 83 | wrapperRecvType: key.recv, |
| 84 | object: obj, |
| 85 | Signature: sig, |
| 86 | Synthetic: description, |
| 87 | } |
| 88 | prog.build(fn, nil, func(b *builder) { |
| 89 | b.addSpilledParam(recv) |
| 90 | b.createParams(start) |
| 91 | |
| 92 | indices := key.indexSlice() |
| 93 | |
| 94 | var v Value = fn.Locals[0] // spilled receiver |
| 95 | if isPointer(key.recv) { |
| 96 | v = b.emitLoad(v) |
| 97 | |
| 98 | // For simple indirection wrappers, perform an informative nil-check: |
| 99 | // "value method (T).f called using nil *T pointer" |
| 100 | if len(indices) == 1 && !isPointer(recvType(obj)) { |
| 101 | var c Call |
| 102 | c.Call.Value = &SSABuiltin{ |
| 103 | name: "ssa:wrapnilchk", |
| 104 | sig: NewSignatureType(nil, nil, nil, |
| 105 | NewTuple(anonVar(key.recv), anonVar(tString), anonVar(tString)), |
| 106 | NewTuple(anonVar(key.recv)), false), |
no test coverage detected