runtime: use package reflectlite

This commit is contained in:
Randy Reddig
2025-03-08 12:53:15 -08:00
committed by Ron Evans
parent 9e143efd73
commit 99a618385b
2 changed files with 28 additions and 28 deletions
+14 -14
View File
@@ -6,7 +6,7 @@ package runtime
// https://golang.org/src/runtime/map.go // https://golang.org/src/runtime/map.go
import ( import (
"reflect" "internal/reflectlite"
"tinygo" "tinygo"
"unsafe" "unsafe"
) )
@@ -539,8 +539,8 @@ func hashmapStringDelete(m *hashmap, key string) {
// a field is exported and thus allows circumventing the type system. // a field is exported and thus allows circumventing the type system.
// The hash function needs it as it also needs to hash unexported struct fields. // The hash function needs it as it also needs to hash unexported struct fields.
// //
//go:linkname valueInterfaceUnsafe reflect.valueInterfaceUnsafe //go:linkname valueInterfaceUnsafe internal/reflectlite.valueInterfaceUnsafe
func valueInterfaceUnsafe(v reflect.Value) interface{} func valueInterfaceUnsafe(v reflectlite.Value) interface{}
func hashmapFloat32Hash(ptr unsafe.Pointer, seed uintptr) uint32 { func hashmapFloat32Hash(ptr unsafe.Pointer, seed uintptr) uint32 {
f := *(*uint32)(ptr) f := *(*uint32)(ptr)
@@ -561,7 +561,7 @@ func hashmapFloat64Hash(ptr unsafe.Pointer, seed uintptr) uint32 {
} }
func hashmapInterfaceHash(itf interface{}, seed uintptr) uint32 { func hashmapInterfaceHash(itf interface{}, seed uintptr) uint32 {
x := reflect.ValueOf(itf) x := reflectlite.ValueOf(itf)
if x.RawType() == nil { if x.RawType() == nil {
return 0 // nil interface return 0 // nil interface
} }
@@ -574,39 +574,39 @@ func hashmapInterfaceHash(itf interface{}, seed uintptr) uint32 {
} }
switch x.RawType().Kind() { switch x.RawType().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflectlite.Int, reflectlite.Int8, reflectlite.Int16, reflectlite.Int32, reflectlite.Int64:
return hash32(ptr, x.RawType().Size(), seed) return hash32(ptr, x.RawType().Size(), seed)
case reflect.Bool, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflectlite.Bool, reflectlite.Uint, reflectlite.Uint8, reflectlite.Uint16, reflectlite.Uint32, reflectlite.Uint64, reflectlite.Uintptr:
return hash32(ptr, x.RawType().Size(), seed) return hash32(ptr, x.RawType().Size(), seed)
case reflect.Float32: case reflectlite.Float32:
// It should be possible to just has the contents. However, NaN != NaN // It should be possible to just has the contents. However, NaN != NaN
// so if you're using lots of NaNs as map keys (you shouldn't) then hash // so if you're using lots of NaNs as map keys (you shouldn't) then hash
// time may become exponential. To fix that, it would be better to // time may become exponential. To fix that, it would be better to
// return a random number instead: // return a random number instead:
// https://research.swtch.com/randhash // https://research.swtch.com/randhash
return hashmapFloat32Hash(ptr, seed) return hashmapFloat32Hash(ptr, seed)
case reflect.Float64: case reflectlite.Float64:
return hashmapFloat64Hash(ptr, seed) return hashmapFloat64Hash(ptr, seed)
case reflect.Complex64: case reflectlite.Complex64:
rptr, iptr := ptr, unsafe.Add(ptr, 4) rptr, iptr := ptr, unsafe.Add(ptr, 4)
return hashmapFloat32Hash(rptr, seed) ^ hashmapFloat32Hash(iptr, seed) return hashmapFloat32Hash(rptr, seed) ^ hashmapFloat32Hash(iptr, seed)
case reflect.Complex128: case reflectlite.Complex128:
rptr, iptr := ptr, unsafe.Add(ptr, 8) rptr, iptr := ptr, unsafe.Add(ptr, 8)
return hashmapFloat64Hash(rptr, seed) ^ hashmapFloat64Hash(iptr, seed) return hashmapFloat64Hash(rptr, seed) ^ hashmapFloat64Hash(iptr, seed)
case reflect.String: case reflectlite.String:
return hashmapStringHash(x.String(), seed) return hashmapStringHash(x.String(), seed)
case reflect.Chan, reflect.Ptr, reflect.UnsafePointer: case reflectlite.Chan, reflectlite.Ptr, reflectlite.UnsafePointer:
// It might seem better to just return the pointer, but that won't // It might seem better to just return the pointer, but that won't
// result in an evenly distributed hashmap. Instead, hash the pointer // result in an evenly distributed hashmap. Instead, hash the pointer
// like most other types. // like most other types.
return hash32(ptr, x.RawType().Size(), seed) return hash32(ptr, x.RawType().Size(), seed)
case reflect.Array: case reflectlite.Array:
var hash uint32 var hash uint32
for i := 0; i < x.Len(); i++ { for i := 0; i < x.Len(); i++ {
hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Index(i)), seed) hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Index(i)), seed)
} }
return hash return hash
case reflect.Struct: case reflectlite.Struct:
var hash uint32 var hash uint32
for i := 0; i < x.NumField(); i++ { for i := 0; i < x.NumField(); i++ {
hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Field(i)), seed) hash ^= hashmapInterfaceHash(valueInterfaceUnsafe(x.Field(i)), seed)
+14 -14
View File
@@ -6,7 +6,7 @@ package runtime
// anything (including non-pointers). // anything (including non-pointers).
import ( import (
"reflect" "internal/reflectlite"
"unsafe" "unsafe"
) )
@@ -27,12 +27,12 @@ func decomposeInterface(i _interface) (unsafe.Pointer, unsafe.Pointer) {
// 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 {
return reflectValueEqual(reflect.ValueOf(x), reflect.ValueOf(y)) return reflectValueEqual(reflectlite.ValueOf(x), reflectlite.ValueOf(y))
} }
func reflectValueEqual(x, y reflect.Value) bool { func reflectValueEqual(x, y reflectlite.Value) bool {
// Note: doing a x.Type() == y.Type() comparison would not work here as that // Note: doing a x.Type() == y.Type() comparison would not work here as that
// would introduce an infinite recursion: comparing two reflect.Type values // would introduce an infinite recursion: comparing two reflectlite.Type values
// is done with this reflectValueEqual runtime call. // is done with this reflectValueEqual runtime call.
if x.RawType() == nil || y.RawType() == nil { if x.RawType() == nil || y.RawType() == nil {
// One of them is nil. // One of them is nil.
@@ -46,35 +46,35 @@ func reflectValueEqual(x, y reflect.Value) bool {
} }
switch x.RawType().Kind() { switch x.RawType().Kind() {
case reflect.Bool: case reflectlite.Bool:
return x.Bool() == y.Bool() return x.Bool() == y.Bool()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflectlite.Int, reflectlite.Int8, reflectlite.Int16, reflectlite.Int32, reflectlite.Int64:
return x.Int() == y.Int() return x.Int() == y.Int()
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: case reflectlite.Uint, reflectlite.Uint8, reflectlite.Uint16, reflectlite.Uint32, reflectlite.Uint64, reflectlite.Uintptr:
return x.Uint() == y.Uint() return x.Uint() == y.Uint()
case reflect.Float32, reflect.Float64: case reflectlite.Float32, reflectlite.Float64:
return x.Float() == y.Float() return x.Float() == y.Float()
case reflect.Complex64, reflect.Complex128: case reflectlite.Complex64, reflectlite.Complex128:
return x.Complex() == y.Complex() return x.Complex() == y.Complex()
case reflect.String: case reflectlite.String:
return x.String() == y.String() return x.String() == y.String()
case reflect.Chan, reflect.Ptr, reflect.UnsafePointer: case reflectlite.Chan, reflectlite.Ptr, reflectlite.UnsafePointer:
return x.UnsafePointer() == y.UnsafePointer() return x.UnsafePointer() == y.UnsafePointer()
case reflect.Array: case reflectlite.Array:
for i := 0; i < x.Len(); i++ { for i := 0; i < x.Len(); i++ {
if !reflectValueEqual(x.Index(i), y.Index(i)) { if !reflectValueEqual(x.Index(i), y.Index(i)) {
return false return false
} }
} }
return true return true
case reflect.Struct: case reflectlite.Struct:
for i := 0; i < x.NumField(); i++ { for i := 0; i < x.NumField(); i++ {
if !reflectValueEqual(x.Field(i), y.Field(i)) { if !reflectValueEqual(x.Field(i), y.Field(i)) {
return false return false
} }
} }
return true return true
case reflect.Interface: case reflectlite.Interface:
return reflectValueEqual(x.Elem(), y.Elem()) return reflectValueEqual(x.Elem(), y.Elem())
default: default:
runtimePanic("comparing un-comparable type") runtimePanic("comparing un-comparable type")