diff --git a/src/reflect/sidetables.go b/src/reflect/sidetables.go index f53b53bd..2268d3eb 100644 --- a/src/reflect/sidetables.go +++ b/src/reflect/sidetables.go @@ -25,9 +25,9 @@ var arrayTypesSidetable byte // table. func readStringSidetable(table unsafe.Pointer, index uintptr) string { nameLen, namePtr := readVarint(unsafe.Pointer(uintptr(table) + index)) - return *(*string)(unsafe.Pointer(&StringHeader{ - Data: uintptr(namePtr), - Len: nameLen, + return *(*string)(unsafe.Pointer(&stringHeader{ + data: namePtr, + len: nameLen, })) } diff --git a/src/reflect/swapper.go b/src/reflect/swapper.go index f3baaede..82842de9 100644 --- a/src/reflect/swapper.go +++ b/src/reflect/swapper.go @@ -24,15 +24,15 @@ func Swapper(slice interface{}) func(i, j int) { typ := v.typecode.Elem() size := typ.Size() - header := (*SliceHeader)(v.value) + header := (*sliceHeader)(v.value) tmp := unsafe.Pointer(&make([]byte, size)[0]) return func(i, j int) { - if uint(i) >= uint(header.Len) || uint(j) >= uint(header.Len) { + if uint(i) >= uint(header.len) || uint(j) >= uint(header.len) { panic("reflect: slice index out of range") } - val1 := unsafe.Pointer(header.Data + uintptr(i)*size) - val2 := unsafe.Pointer(header.Data + uintptr(j)*size) + val1 := unsafe.Pointer(uintptr(header.data) + uintptr(i)*size) + val2 := unsafe.Pointer(uintptr(header.data) + uintptr(j)*size) memcpy(tmp, val1, size) memcpy(val1, val2, size) memcpy(val2, tmp, size) diff --git a/src/reflect/value.go b/src/reflect/value.go index 08d828d8..7e89e68b 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -114,8 +114,8 @@ func (v Value) IsNil() bool { if v.value == nil { return true } - slice := (*SliceHeader)(v.value) - return slice.Data == 0 + slice := (*sliceHeader)(v.value) + return slice.data == nil case Interface: if v.value == nil { return true @@ -137,8 +137,8 @@ func (v Value) Pointer() uintptr { } return uintptr(v.value) case Slice: - slice := (*SliceHeader)(v.value) - return slice.Data + slice := (*sliceHeader)(v.value) + return uintptr(slice.data) case Func: panic("unimplemented: (reflect.Value).Pointer()") default: // not implemented: Func @@ -345,9 +345,9 @@ func (v Value) Len() int { case Map: return maplen(v.value) case Slice: - return int((*SliceHeader)(v.value).Len) + return int((*sliceHeader)(v.value).len) case String: - return int((*StringHeader)(v.value).Len) + return int((*stringHeader)(v.value).len) default: panic(&ValueError{"Len"}) } @@ -365,7 +365,7 @@ func (v Value) Cap() int { case Chan: return chancap(v.value) case Slice: - return int((*SliceHeader)(v.value).Cap) + return int((*sliceHeader)(v.value).cap) default: panic(&ValueError{"Cap"}) } @@ -462,28 +462,28 @@ func (v Value) Index(i int) Value { switch v.Kind() { case Slice: // Extract an element from the slice. - slice := *(*SliceHeader)(v.value) - if uint(i) >= uint(slice.Len) { + slice := *(*sliceHeader)(v.value) + if uint(i) >= uint(slice.len) { panic("reflect: slice index out of range") } elem := Value{ typecode: v.typecode.elem(), flags: v.flags | valueFlagIndirect, } - addr := uintptr(slice.Data) + elem.typecode.Size()*uintptr(i) // pointer to new value + addr := uintptr(slice.data) + elem.typecode.Size()*uintptr(i) // pointer to new value elem.value = unsafe.Pointer(addr) return elem case String: // Extract a character from a string. // A string is never stored directly in the interface, but always as a // pointer to the string value. - s := *(*StringHeader)(v.value) - if uint(i) >= uint(s.Len) { + s := *(*stringHeader)(v.value) + if uint(i) >= uint(s.len) { panic("reflect: string index out of range") } return Value{ typecode: Uint8.basicType(), - value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(s.Data + uintptr(i))))), + value: unsafe.Pointer(uintptr(*(*uint8)(unsafe.Pointer(uintptr(s.data) + uintptr(i))))), } case Array: // Extract an element from the array. @@ -745,11 +745,26 @@ type SliceHeader struct { Cap uintptr } +// Slice header that matches the underlying structure. Used for when we switch +// to a precise GC, which needs to know exactly where pointers live. +type sliceHeader struct { + data unsafe.Pointer + len uintptr + cap uintptr +} + type StringHeader struct { Data uintptr Len uintptr } +// Like sliceHeader, this type is used internally to make sure pointer and +// non-pointer fields match those of actual strings. +type stringHeader struct { + data unsafe.Pointer + len uintptr +} + type ValueError struct { Method string }