diff options
Diffstat (limited to 'src/pkg/runtime/iface.c')
-rw-r--r-- | src/pkg/runtime/iface.c | 178 |
1 files changed, 47 insertions, 131 deletions
diff --git a/src/pkg/runtime/iface.c b/src/pkg/runtime/iface.c index 000f834cf..2b60c4f23 100644 --- a/src/pkg/runtime/iface.c +++ b/src/pkg/runtime/iface.c @@ -3,17 +3,10 @@ // license that can be found in the LICENSE file. #include "runtime.h" +#include "arch_GOARCH.h" #include "type.h" #include "malloc.h" -enum -{ - // If an empty interface has these bits set in its type - // pointer, it was copied from a reflect.Value and is - // not a valid empty interface. - reflectFlags = 3, -}; - void runtime·printiface(Iface i) { @@ -126,7 +119,7 @@ search: if(!canfail) { throw: // didn't find method - runtime·newTypeAssertionError(nil, type, inter, + runtime·newTypeAssertionError( nil, type->string, inter->string, iname, &err); if(locked) @@ -158,17 +151,18 @@ out: static void copyin(Type *t, void *src, void **dst) { - int32 wid, alg; + uintptr size; void *p; + Alg *alg; - wid = t->size; + size = t->size; alg = t->alg; - if(wid <= sizeof(*dst)) - runtime·algarray[alg].copy(wid, dst, src); + if(size <= sizeof(*dst)) + alg->copy(size, dst, src); else { - p = runtime·mal(wid); - runtime·algarray[alg].copy(wid, p, src); + p = runtime·mal(size); + alg->copy(size, p, src); *dst = p; } } @@ -176,15 +170,16 @@ copyin(Type *t, void *src, void **dst) static void copyout(Type *t, void **src, void *dst) { - int32 wid, alg; + uintptr size; + Alg *alg; - wid = t->size; + size = t->size; alg = t->alg; - if(wid <= sizeof(*src)) - runtime·algarray[alg].copy(wid, dst, src); + if(size <= sizeof(*src)) + alg->copy(size, dst, src); else - runtime·algarray[alg].copy(wid, dst, *src); + alg->copy(size, dst, *src); } // func convT2I(typ *byte, typ2 *byte, elem any) (ret any) @@ -240,13 +235,13 @@ assertI2Tret(Type *t, Iface i, byte *ret) tab = i.tab; if(tab == nil) { - runtime·newTypeAssertionError(nil, nil, t, + runtime·newTypeAssertionError( nil, nil, t->string, nil, &err); runtime·panic(err); } if(tab->type != t) { - runtime·newTypeAssertionError(tab->inter, tab->type, t, + runtime·newTypeAssertionError( tab->inter->string, tab->type->string, t->string, nil, &err); runtime·panic(err); @@ -286,8 +281,6 @@ runtime·assertE2T(Type *t, Eface e, ...) { byte *ret; - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); ret = (byte*)(&e+1); assertE2Tret(t, e, ret); } @@ -297,16 +290,14 @@ assertE2Tret(Type *t, Eface e, byte *ret) { Eface err; - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); if(e.type == nil) { - runtime·newTypeAssertionError(nil, nil, t, + runtime·newTypeAssertionError( nil, nil, t->string, nil, &err); runtime·panic(err); } if(e.type != t) { - runtime·newTypeAssertionError(nil, e.type, t, + runtime·newTypeAssertionError( nil, e.type->string, t->string, nil, &err); runtime·panic(err); @@ -323,8 +314,6 @@ runtime·assertE2T2(Type *t, Eface e, ...) bool *ok; int32 wid; - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); ret = (byte*)(&e+1); wid = t->size; ok = (bool*)(ret + wid); @@ -363,7 +352,7 @@ runtime·assertI2E(InterfaceType* inter, Iface i, Eface ret) tab = i.tab; if(tab == nil) { // explicit conversions require non-nil interface value. - runtime·newTypeAssertionError(nil, nil, inter, + runtime·newTypeAssertionError( nil, nil, inter->string, nil, &err); runtime·panic(err); @@ -418,7 +407,7 @@ runtime·ifaceI2I(InterfaceType *inter, Iface i, Iface *ret) tab = i.tab; if(tab == nil) { // explicit conversions require non-nil interface value. - runtime·newTypeAssertionError(nil, nil, inter, + runtime·newTypeAssertionError( nil, nil, inter->string, nil, &err); runtime·panic(err); @@ -460,12 +449,10 @@ runtime·ifaceE2I(InterfaceType *inter, Eface e, Iface *ret) Type *t; Eface err; - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); t = e.type; if(t == nil) { // explicit conversions require non-nil interface value. - runtime·newTypeAssertionError(nil, nil, inter, + runtime·newTypeAssertionError( nil, nil, inter->string, nil, &err); runtime·panic(err); @@ -493,8 +480,6 @@ runtime·assertE2I(InterfaceType* inter, Eface e, Iface ret) void runtime·assertE2I2(InterfaceType *inter, Eface e, Iface ret, bool ok) { - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); if(e.type == nil) { ok = 0; ret.data = nil; @@ -517,12 +502,10 @@ runtime·assertE2E(InterfaceType* inter, Eface e, Eface ret) Type *t; Eface err; - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); t = e.type; if(t == nil) { // explicit conversions require non-nil interface value. - runtime·newTypeAssertionError(nil, nil, inter, + runtime·newTypeAssertionError( nil, nil, inter->string, nil, &err); runtime·panic(err); @@ -535,8 +518,6 @@ runtime·assertE2E(InterfaceType* inter, Eface e, Eface ret) void runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok) { - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); USED(inter); ret = e; ok = e.type != nil; @@ -547,23 +528,27 @@ runtime·assertE2E2(InterfaceType* inter, Eface e, Eface ret, bool ok) static uintptr ifacehash1(void *data, Type *t) { - int32 alg, wid; + Alg *alg; + uintptr size, h; Eface err; if(t == nil) return 0; alg = t->alg; - wid = t->size; - if(runtime·algarray[alg].hash == runtime·nohash) { + size = t->size; + if(alg->hash == runtime·nohash) { // calling nohash will panic too, // but we can print a better error. runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err); runtime·panic(err); } - if(wid <= sizeof(data)) - return runtime·algarray[alg].hash(wid, &data); - return runtime·algarray[alg].hash(wid, data); + h = 0; + if(size <= sizeof(data)) + alg->hash(&h, size, &data); + else + alg->hash(&h, size, data); + return h; } uintptr @@ -583,22 +568,27 @@ runtime·efacehash(Eface a) static bool ifaceeq1(void *data1, void *data2, Type *t) { - int32 alg, wid; + uintptr size; + Alg *alg; Eface err; + bool eq; alg = t->alg; - wid = t->size; + size = t->size; - if(runtime·algarray[alg].equal == runtime·noequal) { + if(alg->equal == runtime·noequal) { // calling noequal will panic too, // but we can print a better error. runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"comparing uncomparable type "), *t->string), &err); runtime·panic(err); } - if(wid <= sizeof(data1)) - return runtime·algarray[alg].equal(wid, &data1, &data2); - return runtime·algarray[alg].equal(wid, data1, data2); + eq = 0; + if(size <= sizeof(data1)) + alg->equal(&eq, size, &data1, &data2); + else + alg->equal(&eq, size, data1, data2); + return eq; } bool @@ -614,10 +604,6 @@ runtime·ifaceeq_c(Iface i1, Iface i2) bool runtime·efaceeq_c(Eface e1, Eface e2) { - if(((uintptr)e1.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); - if(((uintptr)e2.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); if(e1.type != e2.type) return false; if(e1.type == nil) @@ -660,8 +646,6 @@ runtime·efacethash(Eface e1, uint32 ret) { Type *t; - if(((uintptr)e1.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); ret = 0; t = e1.type; if(t != nil) @@ -670,10 +654,8 @@ runtime·efacethash(Eface e1, uint32 ret) } void -unsafe·Typeof(Eface e, Eface ret) +reflect·unsafe_Typeof(Eface e, Eface ret) { - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); if(e.type == nil) { ret.type = nil; ret.data = nil; @@ -684,73 +666,10 @@ unsafe·Typeof(Eface e, Eface ret) } void -unsafe·Reflect(Eface e, Eface rettype, void *retaddr) -{ - uintptr *p; - uintptr x; - - if(((uintptr)e.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); - if(e.type == nil) { - rettype.type = nil; - rettype.data = nil; - retaddr = 0; - } else { - rettype = *(Eface*)e.type; - if(e.type->size <= sizeof(uintptr)) { - // Copy data into x ... - x = 0; - runtime·algarray[e.type->alg].copy(e.type->size, &x, &e.data); - - // but then build pointer to x so that Reflect - // always returns pointer to data. - p = runtime·mal(sizeof(uintptr)); - *p = x; - } else { - // Already a pointer, but still make a copy, - // to preserve value semantics for interface data. - p = runtime·mal(e.type->size); - runtime·algarray[e.type->alg].copy(e.type->size, p, e.data); - } - retaddr = p; - } - FLUSH(&rettype); - FLUSH(&retaddr); -} - -void -unsafe·Unreflect(Eface typ, void *addr, Eface e) -{ - if(((uintptr)typ.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); - - // Reflect library has reinterpreted typ - // as its own kind of type structure. - // We know that the pointer to the original - // type structure sits before the data pointer. - e.type = (Type*)((Eface*)typ.data-1); - - // Interface holds either pointer to data - // or copy of original data. - if(e.type->size <= sizeof(uintptr)) - runtime·algarray[e.type->alg].copy(e.type->size, &e.data, addr); - else { - // Easier: already a pointer to data. - // TODO(rsc): Should this make a copy? - e.data = addr; - } - - FLUSH(&e); -} - -void -unsafe·New(Eface typ, void *ret) +reflect·unsafe_New(Eface typ, void *ret) { Type *t; - if(((uintptr)typ.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); - // Reflect library has reinterpreted typ // as its own kind of type structure. // We know that the pointer to the original @@ -765,14 +684,11 @@ unsafe·New(Eface typ, void *ret) } void -unsafe·NewArray(Eface typ, uint32 n, void *ret) +reflect·unsafe_NewArray(Eface typ, uint32 n, void *ret) { uint64 size; Type *t; - if(((uintptr)typ.type&reflectFlags) != 0) - runtime·throw("invalid interface value"); - // Reflect library has reinterpreted typ // as its own kind of type structure. // We know that the pointer to the original |