update sys.reflect and sys.unreflect to accomodate
the possibility of large objects in interface values.
R=r
DELTA=171 (97 added, 22 deleted, 52 changed)
OCL=22382
CL=22382
diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go
index 2ff4b85..1327e8f 100644
--- a/src/lib/reflect/value.go
+++ b/src/lib/reflect/value.go
@@ -46,10 +46,16 @@
}
func (c *Common) Interface() interface {} {
- if uintptr(c.addr) == 0 {
- panicln("reflect: address 0 for", c.typ.String());
+ var i interface {};
+ if c.typ.Size() > 8 { // TODO(rsc): how do we know it is 8?
+ i = sys.unreflect(c.addr.(uintptr).(uint64), c.typ.String(), true);
+ } else {
+ if uintptr(c.addr) == 0 {
+ panicln("reflect: address 0 for", c.typ.String());
+ }
+ i = sys.unreflect(uint64(uintptr(*c.addr.(*Addr))), c.typ.String(), false);
}
- return sys.unreflect(uint64(uintptr(*c.addr.(*Addr))), c.typ.String());
+ return i;
}
func NewValueAddr(typ Type, addr Addr) Value
@@ -783,7 +789,7 @@
FuncKind : &FuncCreator,
}
-var typecache = make(map[string] *Type);
+var typecache = make(map[string] Type);
func NewValueAddr(typ Type, addr Addr) Value {
c, ok := creator[typ.Kind()];
@@ -870,17 +876,21 @@
export func NewValue(e interface {}) Value {
- value, typestring := sys.reflect(e);
- p, ok := typecache[typestring];
+ value, typestring, indir := sys.reflect(e);
+ typ, ok := typecache[typestring];
if !ok {
- typ := ParseTypeString("", typestring);
- p = new(Type);
- *p = typ;
- typecache[typestring] = p;
+ typ = ParseTypeString("", typestring);
+ typecache[typestring] = typ;
}
- // Content of interface is a value; need a permanent copy to take its address
- // so we can modify the contents. Values contain pointers to 'values'.
+
+ if indir {
+ // Content of interface is a pointer.
+ return NewValueAddr(typ, value.(uintptr).(Addr));
+ }
+
+ // Content of interface is a value;
+ // need a permanent copy to take its address.
ap := new(uint64);
*ap = value;
- return NewValueAddr(*p, ap.(Addr));
+ return NewValueAddr(typ, ap.(Addr));
}