summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/iface.c')
-rw-r--r--src/pkg/runtime/iface.c178
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