replace reflect.interfaceHeader with strongly typed runtime functions

Этот коммит содержится в:
Jaden Weiss 2019-09-21 20:29:20 -04:00 коммит произвёл Ayke
родитель 65beddafe8
коммит d17f500c8b
3 изменённых файлов: 25 добавлений и 19 удалений

Просмотреть файл

@ -318,7 +318,7 @@ func (t Type) Size() uintptr {
case Slice: case Slice:
return unsafe.Sizeof(SliceHeader{}) return unsafe.Sizeof(SliceHeader{})
case Interface: case Interface:
return unsafe.Sizeof(interfaceHeader{}) return unsafe.Sizeof(interface{}(nil))
case Array: case Array:
return t.Elem().Size() * uintptr(t.Len()) return t.Elem().Size() * uintptr(t.Len())
case Struct: case Struct:
@ -364,7 +364,7 @@ func (t Type) Align() int {
case Slice: case Slice:
return int(unsafe.Alignof(SliceHeader{})) return int(unsafe.Alignof(SliceHeader{}))
case Interface: case Interface:
return int(unsafe.Alignof(interfaceHeader{})) return int(unsafe.Alignof(interface{}(nil)))
case Struct: case Struct:
numField := t.NumField() numField := t.NumField()
alignment := 1 alignment := 1

Просмотреть файл

@ -35,20 +35,22 @@ func Indirect(v Value) Value {
return v.Elem() return v.Elem()
} }
//go:linkname composeInterface runtime.composeInterface
func composeInterface(Type, unsafe.Pointer) interface{}
//go:linkname decomposeInterface runtime.decomposeInterface
func decomposeInterface(i interface{}) (Type, unsafe.Pointer)
func ValueOf(i interface{}) Value { func ValueOf(i interface{}) Value {
v := (*interfaceHeader)(unsafe.Pointer(&i)) typecode, value := decomposeInterface(i)
return Value{ return Value{
typecode: v.typecode, typecode: typecode,
value: v.value, value: value,
flags: valueFlagExported, flags: valueFlagExported,
} }
} }
func (v Value) Interface() interface{} { func (v Value) Interface() interface{} {
i := interfaceHeader{
typecode: v.typecode,
value: v.value,
}
if v.isIndirect() && v.Type().Size() <= unsafe.Sizeof(uintptr(0)) { if v.isIndirect() && v.Type().Size() <= unsafe.Sizeof(uintptr(0)) {
// Value was indirect but must be put back directly in the interface // Value was indirect but must be put back directly in the interface
// value. // value.
@ -56,9 +58,9 @@ func (v Value) Interface() interface{} {
for j := v.Type().Size(); j != 0; j-- { for j := v.Type().Size(); j != 0; j-- {
value = (value << 8) | uintptr(*(*uint8)(unsafe.Pointer(uintptr(v.value) + j - 1))) value = (value << 8) | uintptr(*(*uint8)(unsafe.Pointer(uintptr(v.value) + j - 1)))
} }
i.value = unsafe.Pointer(value) v.value = unsafe.Pointer(value)
} }
return *(*interface{})(unsafe.Pointer(&i)) return composeInterface(v.typecode, v.value)
} }
func (v Value) Type() Type { func (v Value) Type() Type {
@ -94,8 +96,8 @@ func (v Value) IsNil() bool {
if v.value == nil { if v.value == nil {
return true return true
} }
itf := (*interfaceHeader)(v.value) _, val := decomposeInterface(*(*interface{})(v.value))
return itf.value == nil return val == nil
default: default:
panic(&ValueError{"IsNil"}) panic(&ValueError{"IsNil"})
} }
@ -657,12 +659,6 @@ type funcHeader struct {
Code unsafe.Pointer Code unsafe.Pointer
} }
// This is the same thing as an interface{}.
type interfaceHeader struct {
typecode Type
value unsafe.Pointer
}
type SliceHeader struct { type SliceHeader struct {
Data uintptr Data uintptr
Len uintptr Len uintptr

Просмотреть файл

@ -12,6 +12,16 @@ type _interface struct {
value unsafe.Pointer value unsafe.Pointer
} }
//go:inline
func composeInterface(typecode uintptr, value unsafe.Pointer) _interface {
return _interface{typecode, value}
}
//go:inline
func decomposeInterface(i _interface) (uintptr, unsafe.Pointer) {
return i.typecode, i.value
}
// Return true iff both interfaces are equal. // Return true iff both interfaces are equal.
func interfaceEqual(x, y _interface) bool { func interfaceEqual(x, y _interface) bool {
if x.typecode != y.typecode { if x.typecode != y.typecode {