]> Cypherpunks repositories - gostls13.git/commitdiff
runtime, gc: call interface conversion routines by reference.
authorKeith Randall <khr@golang.org>
Wed, 18 Dec 2013 00:55:06 +0000 (16:55 -0800)
committerKeith Randall <khr@golang.org>
Wed, 18 Dec 2013 00:55:06 +0000 (16:55 -0800)
Part of getting rid of vararg C calls.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/23310043

src/cmd/gc/builtin.c
src/cmd/gc/runtime.go
src/cmd/gc/walk.c
src/pkg/runtime/iface.c

index f88659ee00558b1b0bd14d531cd100aa9e23912d..1b0297d7ca53440e34c2b62b58dbe754cb514324 100644 (file)
@@ -42,8 +42,8 @@ char *runtimeimport =
        "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"
index 662eb8251fcd7a34c05a2df428f7dd2f68d824b4..852a545a91f35487bc755b9159bd5e922427b069 100644 (file)
@@ -58,8 +58,8 @@ func slicestringcopy(to any, fr any) int
 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)
index 590909f2343dfa549b3ae1141049b35c293e9b66..d28495d0b7a84b52a5bceabf49929e86294d1729 100644 (file)
@@ -898,7 +898,20 @@ walkexpr(Node **np, NodeList **init)
                                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);
index ecbdcc70770fc3bce886805add816b712cf15879..723d8ebd1de06b673eefa09f778c872d6432b4cb 100644 (file)
@@ -183,42 +183,31 @@ runtime·typ2Itab(Type *t, InterfaceType *inter, Itab **cache, Itab *ret)
        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);