summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-kv/v2/format/abi.go')
-rw-r--r--vendor/codeberg.org/gruf/go-kv/v2/format/abi.go262
1 files changed, 262 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go b/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go
new file mode 100644
index 000000000..815660a5e
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-kv/v2/format/abi.go
@@ -0,0 +1,262 @@
+//go:build go1.24 && !go1.25
+
+package format
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+const (
+ // see: go/src/internal/abi/type.go
+ abi_KindDirectIface uint8 = 1 << 5
+ abi_KindMask uint8 = (1 << 5) - 1
+)
+
+// abi_Type is a copy of the memory layout of abi.Type{}.
+//
+// see: go/src/internal/abi/type.go
+type abi_Type struct {
+ _ uintptr
+ PtrBytes uintptr
+ _ uint32
+ _ uint8
+ _ uint8
+ _ uint8
+ Kind_ uint8
+ _ func(unsafe.Pointer, unsafe.Pointer) bool
+ _ *byte
+ _ int32
+ _ int32
+}
+
+// abi_EmptyInterface is a copy of the memory layout of abi.EmptyInterface{},
+// which is to say also the memory layout of any method-less interface.
+//
+// see: go/src/internal/abi/iface.go
+type abi_EmptyInterface struct {
+ Type *abi_Type
+ Data unsafe.Pointer
+}
+
+// see: go/src/internal/abi/type.go Type.Kind()
+func abi_Type_Kind(t reflect.Type) uint8 {
+ iface := (*reflect_nonEmptyInterface)(unsafe.Pointer(&t))
+ atype := (*abi_Type)(unsafe.Pointer(iface.word))
+ return atype.Kind_ & abi_KindMask
+}
+
+// see: go/src/internal/abi/type.go Type.IfaceIndir()
+func abi_Type_IfaceIndir(t reflect.Type) bool {
+ iface := (*reflect_nonEmptyInterface)(unsafe.Pointer(&t))
+ atype := (*abi_Type)(unsafe.Pointer(iface.word))
+ return atype.Kind_&abi_KindDirectIface == 0
+}
+
+// pack_iface packs a new reflect.nonEmptyInterface{} using shielded itab
+// pointer and data (word) pointer, returning a pointer for caller casting.
+func pack_iface(itab uintptr, word unsafe.Pointer) unsafe.Pointer {
+ return unsafe.Pointer(&reflect_nonEmptyInterface{
+ itab: itab,
+ word: word,
+ })
+}
+
+// get_iface_ITab generates a new value of given type,
+// casts it to the generic param interface type, and
+// returns the .itab portion of the reflect.nonEmptyInterface{}.
+// this is useful for later calls to pack_iface for known type.
+func get_iface_ITab[I any](t reflect.Type) uintptr {
+ s := reflect.New(t).Elem().Interface().(I)
+ i := (*reflect_nonEmptyInterface)(unsafe.Pointer(&s))
+ return i.itab
+}
+
+// unpack_eface returns the .Data portion of an abi.EmptyInterface{}.
+func unpack_eface(a any) unsafe.Pointer {
+ return (*abi_EmptyInterface)(unsafe.Pointer((&a))).Data
+}
+
+// add returns the ptr addition of starting ptr and a delta.
+func add(ptr unsafe.Pointer, delta uintptr) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(ptr) + delta)
+}
+
+// typeof is short-hand for reflect.TypeFor[T]().
+func typeof[T any]() reflect.Type {
+ return reflect.TypeFor[T]()
+}
+
+// see: go/src/reflect/value.go
+type reflect_flag uintptr
+
+const (
+ // see: go/src/reflect/value.go
+ reflect_flagKindWidth = 5 // there are 27 kinds
+ reflect_flagKindMask reflect_flag = 1<<reflect_flagKindWidth - 1
+ reflect_flagStickyRO reflect_flag = 1 << 5
+ reflect_flagEmbedRO reflect_flag = 1 << 6
+ reflect_flagIndir reflect_flag = 1 << 7
+ reflect_flagAddr reflect_flag = 1 << 8
+ reflect_flagMethod reflect_flag = 1 << 9
+ reflect_flagMethodShift = 10
+ reflect_flagRO reflect_flag = reflect_flagStickyRO | reflect_flagEmbedRO
+
+ // custom flag to indicate key types.
+ flagKeyType = 1 << 10
+)
+
+// reflect_iface_elem_flags returns the reflect_flag expected of an unboxed interface element of type.
+//
+// see: go/src/reflect/value.go unpackElem()
+func reflect_iface_elem_flags(elemType reflect.Type) reflect_flag {
+ if elemType == nil {
+ return 0
+ }
+ flags := reflect_flag(abi_Type_Kind(elemType))
+ if abi_Type_IfaceIndir(elemType) {
+ flags |= reflect_flagIndir
+ }
+ return flags
+}
+
+// reflect_pointer_elem_flags returns the reflect_flag expected of a dereferenced pointer element of type.
+//
+// see: go/src/reflect/value.go Value.Elem()
+func reflect_pointer_elem_flags(ptrFlags reflect_flag, elemType reflect.Type) reflect_flag {
+ return ptrFlags | reflect_flagIndir | reflect_flagAddr | reflect_flag(abi_Type_Kind(elemType))
+}
+
+// reflect_array_elem_flags returns the reflect_flag expected of an element of type in an array.
+//
+// see: go/src/reflect/value.go Value.Index()
+func reflect_array_elem_flags(arrayFlags reflect_flag, elemType reflect.Type) reflect_flag {
+ return arrayFlags&(reflect_flagIndir|reflect_flagAddr) | reflect_flag(abi_Type_Kind(elemType))
+}
+
+// reflect_slice_elem_flags returns the reflect_flag expected of a slice element of type.
+//
+// see: go/src/reflect/value.go Value.Index()
+func reflect_slice_elem_flags(elemType reflect.Type) reflect_flag {
+ return reflect_flagAddr | reflect_flagIndir | reflect_flag(abi_Type_Kind(elemType))
+}
+
+// reflect_struct_field_flags returns the reflect_flag expected of a struct field of type.
+//
+// see: go/src/reflect/value.go Value.Field()
+func reflect_struct_field_flags(structFlags reflect_flag, fieldType reflect.Type) reflect_flag {
+ return structFlags&(reflect_flagIndir|reflect_flagAddr) | reflect_flag(abi_Type_Kind(fieldType))
+}
+
+// reflect_map_key_flags returns the reflect_flag expected of a map key of type (with our own key type mask set).
+//
+// see: go/src/reflect/map_swiss.go MapIter.Key()
+func reflect_map_key_flags(keyType reflect.Type) reflect_flag {
+ return flagKeyType | reflect_flag(abi_Type_Kind(keyType))
+}
+
+// reflect_map_elem_flags returns the reflect_flag expected of a map element of type.
+//
+// see: go/src/reflect/map_swiss.go MapIter.Value()
+func reflect_map_elem_flags(elemType reflect.Type) reflect_flag {
+ return reflect_flag(abi_Type_Kind(elemType))
+}
+
+// reflect_nonEmptyInterface is a copy of the memory layout of reflect.nonEmptyInterface,
+// which is also to say the memory layout of any non-empty (i.e. w/ method) interface.
+//
+// see: go/src/reflect/value.go
+type reflect_nonEmptyInterface struct {
+ itab uintptr
+ word unsafe.Pointer
+}
+
+// reflect_Value is a copy of the memory layout of reflect.Value{}.
+//
+// see: go/src/reflect/value.go
+type reflect_Value struct {
+ typ_ unsafe.Pointer
+ ptr unsafe.Pointer
+ reflect_flag
+}
+
+func init() {
+ if unsafe.Sizeof(reflect_Value{}) != unsafe.Sizeof(reflect.Value{}) {
+ panic("reflect_Value{} not in sync with reflect.Value{}")
+ }
+}
+
+// reflect_type_data returns the .word from the reflect.Type{} cast
+// as the reflect.nonEmptyInterface{}, which itself will be a pointer
+// to the actual abi.Type{} that this reflect.Type{} is wrapping.
+func reflect_type_data(t reflect.Type) unsafe.Pointer {
+ return (*reflect_nonEmptyInterface)(unsafe.Pointer(&t)).word
+}
+
+// build_reflect_value manually builds a reflect.Value{} by setting the internal field members.
+func build_reflect_value(rtype reflect.Type, data unsafe.Pointer, flags reflect_flag) reflect.Value {
+ return *(*reflect.Value)(unsafe.Pointer(&reflect_Value{reflect_type_data(rtype), data, flags}))
+}
+
+// maps_Iter is a copy of the memory layout of maps.Iter{}.
+//
+// see: go/src/internal/runtime/maps/table.go
+type maps_Iter struct {
+ key unsafe.Pointer
+ elem unsafe.Pointer
+ _ uintptr
+ _ uintptr
+ _ uint64
+ _ uint64
+ _ uint64
+ _ uint8
+ _ int
+ _ uintptr
+ _ struct{ _ unsafe.Pointer }
+ _ uint64
+}
+
+// reflect_MapIter is a copy of the memory layout of reflect.MapIter{}.
+//
+// see: go/src/reflect/map_swiss.go
+type reflect_MapIter struct {
+ m reflect.Value
+ hiter maps_Iter
+}
+
+func init() {
+ if unsafe.Sizeof(reflect_MapIter{}) != unsafe.Sizeof(reflect.MapIter{}) {
+ panic("reflect_MapIter{} not in sync with reflect.MapIter{}")
+ }
+}
+
+// map_iter creates a new map iterator from value,
+// skipping the initial v.MapRange() type checking.
+func map_iter(v reflect.Value) *reflect.MapIter {
+ var i reflect_MapIter
+ i.m = v
+ return (*reflect.MapIter)(unsafe.Pointer(&i))
+}
+
+// map_key returns ptr to current map key in iter.
+func map_key(i *reflect.MapIter) unsafe.Pointer {
+ return (*reflect_MapIter)(unsafe.Pointer(i)).hiter.key
+}
+
+// map_elem returns ptr to current map element in iter.
+func map_elem(i *reflect.MapIter) unsafe.Pointer {
+ return (*reflect_MapIter)(unsafe.Pointer(i)).hiter.elem
+}
+
+// see: go/src/internal/unsafeheader/unsafeheader.go
+type unsafeheader_Slice struct {
+ Data unsafe.Pointer
+ Len int
+ Cap int
+}
+
+// see: go/src/internal/unsafeheader/unsafeheader.go
+type unsafeheader_String struct {
+ Data unsafe.Pointer
+ Len int
+}