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
This commit is contained in:
Russ Cox 2009-01-09 00:17:46 -08:00
parent 51c3ac7e3f
commit 484ba939d2
7 changed files with 138 additions and 63 deletions

View file

@ -46,10 +46,16 @@ func (c *Common) Addr() Addr {
}
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 @@ var creator = map[int] Creator {
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 CopyArray(dst ArrayValue, src ArrayValue, n int) {
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));
}