diff options
author | Russ Cox <rsc@golang.org> | 2009-01-09 00:17:46 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2009-01-09 00:17:46 -0800 |
commit | 6506670d5761f96ea24a2692f83765e21576da92 (patch) | |
tree | 8294974762ab403e555ab47cfa23caed71af1549 /src/lib/reflect/value.go | |
parent | e09d153f4e7e543dd288ce564b3bba787b01fe7a (diff) | |
download | golang-6506670d5761f96ea24a2692f83765e21576da92.tar.gz |
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
Diffstat (limited to 'src/lib/reflect/value.go')
-rw-r--r-- | src/lib/reflect/value.go | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go index 2ff4b85e0..1327e8f67 100644 --- a/src/lib/reflect/value.go +++ b/src/lib/reflect/value.go @@ -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)); } |