mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-11 06:23:39 +00:00
4f1b69827d
The reflect package needs to know the endianness of the system in a few places. Before this patch, it assumed little-endian systems. But with GOARCH=mips we now have a big-endian system which also needs to be supported. So this patch fixes the reflect package to work on big-endian systems. Also, I've updated the tests for MIPS: instead of running the little-endian tests, I've changed it to run the big-endian tests instead. The two are very similar except for endianness so this should be fine. To be sure we won't accidentally break little-endian support, I've kept a single MIPS little-endian test (the CGo test, which doesn't yet work on big-endian systems anyway).
36 lines
1.0 KiB
Go
36 lines
1.0 KiB
Go
//go:build !mips
|
|
|
|
package reflect
|
|
|
|
import "unsafe"
|
|
|
|
// loadValue loads a value that may or may not be word-aligned. The number of
|
|
// bytes given in size are loaded. The biggest possible size it can load is that
|
|
// of an uintptr.
|
|
func loadValue(ptr unsafe.Pointer, size uintptr) uintptr {
|
|
loadedValue := uintptr(0)
|
|
shift := uintptr(0)
|
|
for i := uintptr(0); i < size; i++ {
|
|
loadedValue |= uintptr(*(*byte)(ptr)) << shift
|
|
shift += 8
|
|
ptr = unsafe.Add(ptr, 1)
|
|
}
|
|
return loadedValue
|
|
}
|
|
|
|
// storeValue is the inverse of loadValue. It stores a value to a pointer that
|
|
// doesn't need to be aligned.
|
|
func storeValue(ptr unsafe.Pointer, size, value uintptr) {
|
|
for i := uintptr(0); i < size; i++ {
|
|
*(*byte)(ptr) = byte(value)
|
|
ptr = unsafe.Add(ptr, 1)
|
|
value >>= 8
|
|
}
|
|
}
|
|
|
|
// maskAndShift cuts out a part of a uintptr. Note that the offset may not be 0.
|
|
func maskAndShift(value, offset, size uintptr) uintptr {
|
|
mask := ^uintptr(0) >> ((unsafe.Sizeof(uintptr(0)) - size) * 8)
|
|
return (uintptr(value) >> (offset * 8)) & mask
|
|
}
|