a = b;
a->name = method->name;
- a->isym = methodsym(method, it);
- a->tsym = methodsym(method, t);
+ a->isym = methodsym(method, it, 1);
+ a->tsym = methodsym(method, t, 0);
a->type = methodfunc(f->type, 1);
a->mtype = methodfunc(f->type, 0);
if(!(a->isym->flags & SymSiggen)) {
a->isym->flags |= SymSiggen;
- if(!eqtype(this, it)) {
+ if(!eqtype(this, it) || this->width < types[tptr]->width) {
if(oldlist == nil)
oldlist = pc;
// Is okay to call genwrapper here always,
&& f->embedded && !isifacemethod(f->type))
genembedtramp(it, f, a->isym);
else
- genwrapper(it, f, a->isym);
+ genwrapper(it, f, a->isym, 1);
}
}
&& f->embedded && !isifacemethod(f->type))
genembedtramp(t, f, a->tsym);
else
- genwrapper(t, f, a->tsym);
+ genwrapper(t, f, a->tsym, 0);
}
}
}
* newnam - the eventual mangled name of this function
*/
void
-genwrapper(Type *rcvr, Type *method, Sym *newnam)
+genwrapper(Type *rcvr, Type *method, Sym *newnam, int iface)
{
- Node *this, *fn, *call, *n, *t;
+ Node *this, *fn, *call, *n, *t, *pad;
NodeList *l, *args, *in, *out;
+ Type *tpad;
if(debug['r'])
print("genwrapper rcvrtype=%T method=%T newnam=%S\n",
fn = nod(ODCLFUNC, N, N);
fn->nname = newname(newnam);
- t = nod(OTFUNC, this, N);
- t->list = in;
+ t = nod(OTFUNC, N, N);
+ l = list1(this);
+ if(iface && rcvr->width < types[tptr]->width) {
+ // Building method for interface table and receiver
+ // is smaller than the single pointer-sized word
+ // that the interface call will pass in.
+ // Add a dummy padding argument after the
+ // receiver to make up the difference.
+ tpad = typ(TARRAY);
+ tpad->type = types[TUINT8];
+ tpad->bound = types[tptr]->width - rcvr->width;
+ pad = nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad));
+ l = list(l, pad);
+ }
+ t->list = concat(l, in);
t->rlist = out;
fn->nname->ntype = t;
funchdr(fn);
--- /dev/null
+package main
+
+type I interface {
+ m(a, b, c, d, e, f, g, h byte)
+}
+
+type Int8 int8
+
+func (x Int8) m(a, b, c, d, e, f, g, h byte) {
+ check("Int8", int64(x), 0x01, a, b, c, d, e, f, g, h)
+}
+
+type Uint8 uint8
+
+func (x Uint8) m(a, b, c, d, e, f, g, h byte) {
+ check("Uint8", int64(x), 0x01, a, b, c, d, e, f, g, h)
+}
+
+type Int16 int16
+
+func (x Int16) m(a, b, c, d, e, f, g, h byte) {
+ check("Int16", int64(x), 0x0102, a, b, c, d, e, f, g, h)
+}
+
+type Uint16 uint16
+
+func (x Uint16) m(a, b, c, d, e, f, g, h byte) {
+ check("Uint16", int64(x), 0x0102, a, b, c, d, e, f, g, h)
+}
+
+type Int32 int32
+
+func (x Int32) m(a, b, c, d, e, f, g, h byte) {
+ check("Int32", int64(x), 0x01020304, a, b, c, d, e, f, g, h)
+}
+
+type Uint32 uint32
+
+func (x Uint32) m(a, b, c, d, e, f, g, h byte) {
+ check("Uint32", int64(x), 0x01020304, a, b, c, d, e, f, g, h)
+}
+
+type Int64 int64
+
+func (x Int64) m(a, b, c, d, e, f, g, h byte) {
+ check("Int64", int64(x), 0x0102030405060708, a, b, c, d, e, f, g, h)
+}
+
+type Uint64 uint64
+
+func (x Uint64) m(a, b, c, d, e, f, g, h byte) {
+ check("Uint64", int64(x), 0x0102030405060708, a, b, c, d, e, f, g, h)
+}
+
+var test = []I{
+ Int8(0x01),
+ Uint8(0x01),
+ Int16(0x0102),
+ Uint16(0x0102),
+ Int32(0x01020304),
+ Uint32(0x01020304),
+ Int64(0x0102030405060708),
+ Uint64(0x0102030405060708),
+}
+
+func main() {
+ for _, t := range test {
+ t.m(0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17)
+ }
+}
+
+var bug = false
+
+func check(desc string, have, want int64, a, b, c, d, e, f, g, h byte) {
+ if have != want || a != 0x10 || b != 0x11 || c != 0x12 || d != 0x13 || e != 0x14 || f != 0x15 || g != 0x16 || h != 0x17 {
+ if !bug {
+ bug = true
+ println("BUG")
+ }
+ println(desc, "check", have, want, a, b, c, d, e, f, g, h)
+ }
+}