mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-19 12:04:03 +00:00
runtime: use package reflectlite
This commit is contained in:
+14
-14
@@ -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
@@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user