"func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n"
"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n"
"func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
- "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n"
- "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 *any) (@\"\".ret·1 any)\n"
+ "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 *any) (@\"\".ret·1 any)\n"
"func @\"\".assertE2E (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
"func @\"\".assertE2E2 (@\"\".typ·3 *byte, @\"\".iface·4 any) (@\"\".ret·1 any, @\"\".ok·2 bool)\n"
"func @\"\".assertE2I (@\"\".typ·2 *byte, @\"\".iface·3 any) (@\"\".ret·1 any)\n"
func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
-func convT2E(typ *byte, elem any) (ret any)
-func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any)
+func convT2E(typ *byte, elem *any) (ret any)
+func convT2I(typ *byte, typ2 *byte, cache **byte, elem *any) (ret any)
// interface type assertions x.(T)
func assertE2E(typ *byte, iface any) (ret any)
goto ret;
}
}
- ll = list(ll, n->left);
+ if(isinter(n->left->type)) {
+ ll = list(ll, n->left);
+ } else {
+ // regular types are passed by reference to avoid C vararg calls
+ if(islvalue(n->left)) {
+ ll = list(ll, nod(OADDR, n->left, N));
+ } else {
+ var = temp(n->left->type);
+ n1 = nod(OAS, var, n->left);
+ typecheck(&n1, Etop);
+ *init = list(*init, n1);
+ ll = list(ll, nod(OADDR, var, N));
+ }
+ }
argtype(fn, n->left->type);
argtype(fn, n->type);
dowidth(fn->type);
FLUSH(&ret);
}
-// func convT2I(typ *byte, typ2 *byte, cache **byte, elem any) (ret any)
+// func convT2I(typ *byte, typ2 *byte, cache **byte, elem *any) (ret any)
#pragma textflag NOSPLIT
void
-runtime·convT2I(Type *t, InterfaceType *inter, Itab **cache, ...)
+runtime·convT2I(Type *t, InterfaceType *inter, Itab **cache, byte *elem, Iface ret)
{
- byte *elem;
- Iface *ret;
Itab *tab;
- int32 wid;
- elem = (byte*)(&cache+1);
- wid = t->size;
- ret = (Iface*)(elem + ROUND(wid, Structrnd));
tab = runtime·atomicloadp(cache);
if(!tab) {
tab = itab(inter, t, 0);
runtime·atomicstorep(cache, tab);
}
- ret->tab = tab;
- copyin(t, elem, &ret->data);
+ ret.tab = tab;
+ copyin(t, elem, &ret.data);
+ FLUSH(&ret);
}
-// func convT2E(typ *byte, elem any) (ret any)
+// func convT2E(typ *byte, elem *any) (ret any)
#pragma textflag NOSPLIT
void
-runtime·convT2E(Type *t, ...)
+runtime·convT2E(Type *t, byte *elem, Eface ret)
{
- byte *elem;
- Eface *ret;
- int32 wid;
-
- elem = (byte*)(&t+1);
- wid = t->size;
- ret = (Eface*)(elem + ROUND(wid, Structrnd));
- ret->type = t;
- copyin(t, elem, &ret->data);
+ ret.type = t;
+ copyin(t, elem, &ret.data);
+ FLUSH(&ret);
}
static void assertI2Tret(Type *t, Iface i, byte *ret);