mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-13 15:33:40 +00:00
reflect: add support for struct types
This commit is contained in:
committed by
Ron Evans
parent
5012be337f
commit
e2c8654237
+37
-11
@@ -10,22 +10,48 @@ import (
|
||||
//go:extern reflect.namedNonBasicTypesSidetable
|
||||
var namedNonBasicTypesSidetable byte
|
||||
|
||||
func readVarint(buf unsafe.Pointer) Type {
|
||||
var t Type
|
||||
//go:extern reflect.structTypesSidetable
|
||||
var structTypesSidetable byte
|
||||
|
||||
//go:extern reflect.structNamesSidetable
|
||||
var structNamesSidetable byte
|
||||
|
||||
// readStringSidetable reads a string from the given table (like
|
||||
// structNamesSidetable) and returns this string. No heap allocation is
|
||||
// necessary because it makes the string point directly to the raw bytes of the
|
||||
// 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,
|
||||
}))
|
||||
}
|
||||
|
||||
// readVarint decodes a varint as used in the encoding/binary package.
|
||||
// It has an input pointer and returns the read varint and the pointer
|
||||
// incremented to the next field in the data structure, just after the varint.
|
||||
//
|
||||
// Details:
|
||||
// https://github.com/golang/go/blob/e37a1b1c/src/encoding/binary/varint.go#L7-L25
|
||||
func readVarint(buf unsafe.Pointer) (uintptr, unsafe.Pointer) {
|
||||
var n uintptr
|
||||
shift := uintptr(0)
|
||||
for {
|
||||
// Read the next byte.
|
||||
// Read the next byte in the buffer.
|
||||
c := *(*byte)(buf)
|
||||
|
||||
// Add this byte to the type code. The upper 7 bits are the value.
|
||||
t = t<<7 | Type(c>>1)
|
||||
|
||||
// Check whether this is the last byte of this varint. The lower bit
|
||||
// indicates whether any bytes follow.
|
||||
if c%1 == 0 {
|
||||
return t
|
||||
}
|
||||
// Decode the bits from this byte and add them to the output number.
|
||||
n |= uintptr(c&0x7f) << shift
|
||||
shift += 7
|
||||
|
||||
// Increment the buf pointer (pointer arithmetic!).
|
||||
buf = unsafe.Pointer(uintptr(buf) + 1)
|
||||
|
||||
// Check whether this is the last byte of this varint. The upper bit
|
||||
// (msb) indicates whether any bytes follow.
|
||||
if c>>7 == 0 {
|
||||
return n, buf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user