rename map access methods to Elem, SetElem.
R=r
DELTA=95 (66 added, 7 deleted, 22 changed)
OCL=31456
CL=31469
}
p.printField(key);
p.addstr(":");
- p.printField(f.Get(key));
+ p.printField(f.Elem(key));
}
p.addstr("]");
case *reflect.StructValue:
i++;
// Check that value lookup is correct.
- vv := mv.Get(NewValue(k));
+ vv := mv.Elem(NewValue(k));
if vi := vv.(*IntValue).Get(); vi != v {
t.Errorf("Key %q: have value %d, want %d", vi, v);
}
// Copy into new map.
- newmap.Put(NewValue(k), NewValue(v));
+ newmap.SetElem(NewValue(k), NewValue(v));
}
- vv := mv.Get(NewValue("not-present"));
+ vv := mv.Elem(NewValue("not-present"));
if vv != nil {
t.Errorf("Invalid key: got non-nil value %s", valueToString(vv));
}
}
}
- newmap.Put(NewValue("a"), nil);
+ newmap.SetElem(NewValue("a"), nil);
v, ok := newm["a"];
if ok {
t.Errorf("newm[\"a\"] = %d after delete", v);
t.Errorf("Interface Method returned %d; want 250", i);
}
}
+
+func TestInterfaceSet(t *testing.T) {
+ p := &Point{3, 4};
+
+ var s struct {
+ I interface {};
+ P interface { Dist(int)int };
+ }
+ sv := NewValue(&s).(*PtrValue).Elem().(*StructValue);
+ sv.Field(0).(*InterfaceValue).Set(NewValue(p));
+ if q := s.I.(*Point); q != p {
+ t.Errorf("i: have %p want %p", q, p);
+ }
+
+ pv := sv.Field(1).(*InterfaceValue);
+ pv.Set(NewValue(p));
+ if q := s.P.(*Point); q != p {
+ t.Errorf("i: have %p want %p", q, p);
+ }
+
+ i := pv.Method(0).Call([]Value{NewValue(10)})[0].(*IntValue).Get();
+ if i != 250 {
+ t.Errorf("Interface Method returned %d; want 250", i);
+ }
+}
return false;
}
for i, k := range map1.Keys() {
- if !deepValueEqual(map1.Get(k), map2.Get(k), visited, depth+1) {
+ if !deepValueEqual(map1.Elem(k), map2.Elem(k), visited, depth+1) {
return false;
}
}
return NewValue(v.Interface());
}
+// ../runtime/reflect.cgo
+func setiface(typ *InterfaceType, x *interface{}, addr addr)
+
// Set assigns x to v.
-func (v *InterfaceValue) Set(x interface{}) {
+func (v *InterfaceValue) Set(x Value) {
+ i := x.Interface();
if !v.canSet {
panic(cannotSet);
}
// Two different representations; see comment in Get.
// Empty interface is easy.
- if v.typ.(*InterfaceType).NumMethod() == 0 {
- *(*interface{})(v.addr) = x;
+ t := v.typ.(*InterfaceType);
+ if t.NumMethod() == 0 {
+ *(*interface{})(v.addr) = i;
+ return;
}
// Non-empty interface requires a runtime check.
- panic("unimplemented: interface Set");
-// unsafe.SetInterface(v.typ, v.addr, x);
+ setiface(t, &i, v.addr);
}
// Method returns a FuncValue corresponding to v's i'th method.
func mapiterkey(it *byte, key *byte) bool
func makemap(t *runtime.MapType) *byte
-// Get returns the value associated with key in the map v.
+// Elem returns the value associated with key in the map v.
// It returns nil if key is not found in the map.
-func (v *MapValue) Get(key Value) Value {
+func (v *MapValue) Elem(key Value) Value {
t := v.Type().(*MapType);
typesMustMatch(t.Key(), key.Type());
m := *(**byte)(v.addr);
return newval;
}
-// Put sets the value associated with key in the map v to val.
+// SetElem sets the value associated with key in the map v to val.
// If val is nil, Put deletes the key from map.
-func (v *MapValue) Put(key, val Value) {
+func (v *MapValue) SetElem(key, val Value) {
t := v.Type().(*MapType);
typesMustMatch(t.Key(), key.Type());
var vaddr *byte;
// ifaceE2I(sigi *byte, iface any) (ret any);
// Called only for explicit conversions (with type assertion).
void
-sys·ifaceE2I(InterfaceType *inter, Eface e, Iface ret)
+ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
{
Type *t;
printf("interface is nil, not %S\n", *inter->string);
throw("interface conversion");
} else {
- ret.data = e.data;
- ret.tab = itab(inter, t, 0);
+ ret->data = e.data;
+ ret->tab = itab(inter, t, 0);
}
- FLUSH(&ret);
+}
+
+// ifaceE2I(sigi *byte, iface any) (ret any);
+// Called only for explicit conversions (with type assertion).
+void
+sys·ifaceE2I(InterfaceType *inter, Eface e, Iface ret)
+{
+ ifaceE2I(inter, e, &ret);
}
// ifaceE2I2(sigi *byte, iface any) (ret any, ok bool);
FLUSH(&e);
}
-
#include "runtime.h"
#include "type.h"
+static Type*
+gettype(void *typ)
+{
+ // typ is a *runtime.Type (or *runtime.MapType, etc), but the Type
+ // defined in type.h includes an interface value header
+ // in front of the raw structure. the -2 below backs up
+ // to the interface value header.
+ return (Type*)((void**)typ - 2);
+}
+
/*
* Go wrappers around the C functions near the bottom of hashmap.c
* There's no recursion here even though it looks like there is:
func makemap(typ *byte) (map *byte) {
MapType *t;
- // typ is a *runtime.MapType, but the MapType
- // defined in type.h includes an interface value header
- // in front of the raw MapType. the -2 below backs up
- // to the interface value header.
- t = (MapType*)((void**)typ - 2);
-
+ t = (MapType*)gettype(typ);
map = (byte*)makemap(t->key->size, t->elem->size, t->key->alg, t->elem->alg, 0);
}
// defined in type.h includes an interface value header
// in front of the raw ChanType. the -2 below backs up
// to the interface value header.
- t = (ChanType*)((void**)typ - 2);
+ t = (ChanType*)gettype(typ);
ch = (byte*)makechan(t->elem->size, t->elem->alg, size);
}
chanrecv((Hchan*)ch, val, pres);
}
+
+/*
+ * Go wrappers around the functions in iface.c
+ */
+
+func setiface(typ *byte, x *byte, ret *byte) {
+ InterfaceType *t;
+
+ t = (InterfaceType*)gettype(typ);
+ if(t->mhdr.nel == 0) {
+ // already an empty interface
+ *(Eface*)ret = *(Eface*)x;
+ return;
+ }
+ ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret);
+}
Hchan* makechan(uint32, uint32, uint32);
void chansend(Hchan*, void*, bool*);
void chanrecv(Hchan*, void*, bool*);
+
+void ifaceE2I(struct InterfaceType*, Eface, Iface*);