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.c59
1 files changed, 55 insertions, 4 deletions
diff --git a/src/pkg/runtime/iface.c b/src/pkg/runtime/iface.c
index 698aead3d..b1015f695 100644
--- a/src/pkg/runtime/iface.c
+++ b/src/pkg/runtime/iface.c
@@ -6,6 +6,14 @@
#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)
{
@@ -42,7 +50,7 @@ itab(InterfaceType *inter, Type *type, int32 canfail)
Method *t, *et;
IMethod *i, *ei;
uint32 h;
- String *iname;
+ String *iname, *ipkgPath;
Itab *m;
UncommonType *x;
Type *itype;
@@ -112,6 +120,7 @@ search:
for(; i < ei; i++) {
itype = i->type;
iname = i->name;
+ ipkgPath = i->pkgPath;
for(;; t++) {
if(t >= et) {
if(!canfail) {
@@ -128,7 +137,7 @@ search:
m->bad = 1;
goto out;
}
- if(t->mtyp == itype && t->name == iname)
+ if(t->mtyp == itype && t->name == iname && t->pkgPath == ipkgPath)
break;
}
if(m)
@@ -276,6 +285,8 @@ 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);
}
@@ -285,6 +296,8 @@ 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,
nil, nil, t->string,
@@ -309,6 +322,8 @@ 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+runtime·rnd(wid, 1));
@@ -444,6 +459,8 @@ 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.
@@ -456,6 +473,14 @@ runtime·ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
ret->tab = itab(inter, t, 0);
}
+// For reflect
+// func ifaceE2I(t *InterfaceType, e interface{}, dst *Iface)
+void
+reflect·ifaceE2I(InterfaceType *inter, Eface e, Iface *dst)
+{
+ runtime·ifaceE2I(inter, e, dst);
+}
+
// func ifaceE2I(sigi *byte, iface any) (ret any)
void
runtime·assertE2I(InterfaceType* inter, Eface e, Iface ret)
@@ -467,6 +492,8 @@ 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;
@@ -489,6 +516,8 @@ 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.
@@ -505,6 +534,8 @@ 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;
@@ -582,6 +613,10 @@ 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)
@@ -624,6 +659,8 @@ 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)
@@ -634,11 +671,14 @@ runtime·efacethash(Eface e1, uint32 ret)
void
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;
- } else
- ret = *(Eface*)e.type;
+ } else {
+ ret = *(Eface*)(e.type);
+ }
FLUSH(&ret);
}
@@ -648,6 +688,8 @@ 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;
@@ -678,6 +720,9 @@ unsafe·Reflect(Eface e, Eface rettype, void *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
@@ -702,6 +747,9 @@ 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
@@ -721,6 +769,9 @@ 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