summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-structr/runtime.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-structr/runtime.go')
-rw-r--r--vendor/codeberg.org/gruf/go-structr/runtime.go294
1 files changed, 0 insertions, 294 deletions
diff --git a/vendor/codeberg.org/gruf/go-structr/runtime.go b/vendor/codeberg.org/gruf/go-structr/runtime.go
deleted file mode 100644
index 508cd6e4c..000000000
--- a/vendor/codeberg.org/gruf/go-structr/runtime.go
+++ /dev/null
@@ -1,294 +0,0 @@
-package structr
-
-import (
- "fmt"
- "reflect"
- "runtime"
- "strings"
- "unicode"
- "unicode/utf8"
- "unsafe"
-
- "codeberg.org/gruf/go-mangler/v2"
- "codeberg.org/gruf/go-xunsafe"
-)
-
-// struct_field contains pre-prepared type
-// information about a struct's field member,
-// including memory offset and hash function.
-type struct_field struct {
-
- // struct field type mangling
- // (i.e. fast serializing) fn.
- mangle mangler.Mangler
-
- // zero value data, used when
- // nil encountered during ptr
- // offset following.
- zero unsafe.Pointer
-
- // mangled zero value string,
- // to check zero value keys.
- zerostr string
-
- // offsets defines whereabouts in
- // memory this field is located,
- // and after how many dereferences.
- offsets []next_offset
-}
-
-// next_offset defines a next offset location
-// in a struct_field, first by the number of
-// derefences required, then by offset from
-// that final memory location.
-type next_offset struct {
- derefs int
- offset uintptr
-}
-
-// get_type_iter returns a prepared xunsafe.TypeIter{} for generic parameter type,
-// with flagIndir specifically set as we always take a reference to value type.
-func get_type_iter[T any]() xunsafe.TypeIter {
- rtype := reflect.TypeOf((*T)(nil)).Elem()
- flags := xunsafe.Reflect_flag(xunsafe.Abi_Type_Kind(rtype))
- flags |= xunsafe.Reflect_flagIndir // always comes from unsafe ptr
- return xunsafe.ToTypeIter(rtype, flags)
-}
-
-// find_field will search for a struct field with given set of names,
-// where names is a len > 0 slice of names account for struct nesting.
-func find_field(t xunsafe.TypeIter, names []string) (sfield struct_field, ftype reflect.Type) {
- var (
- // is_exported returns whether name is exported
- // from a package; can be func or struct field.
- is_exported = func(name string) bool {
- r, _ := utf8.DecodeRuneInString(name)
- return unicode.IsUpper(r)
- }
-
- // pop_name pops the next name from
- // the provided slice of field names.
- pop_name = func() string {
- name := names[0]
- names = names[1:]
- if !is_exported(name) {
- panic(fmt.Sprintf("field is not exported: %s", name))
- }
- return name
- }
-
- // field is the iteratively searched
- // struct field value in below loop.
- field reflect.StructField
- )
-
- // Take reference
- // of parent iter.
- o := t
-
- for len(names) > 0 {
- // Pop next name.
- name := pop_name()
-
- var n int
- rtype := t.Type
- flags := t.Flag
-
- // Iteratively dereference pointer types.
- for rtype.Kind() == reflect.Pointer {
-
- // If this actual indirect memory,
- // increase dereferences counter.
- if flags&xunsafe.Reflect_flagIndir != 0 {
- n++
- }
-
- // Get next elem type.
- rtype = rtype.Elem()
-
- // Get next set of dereferenced element type flags.
- flags = xunsafe.ReflectPointerElemFlags(flags, rtype)
-
- // Update type iter info.
- t = t.Child(rtype, flags)
- }
-
- // Check for valid struct type.
- if rtype.Kind() != reflect.Struct {
- panic(fmt.Sprintf("field %s is not struct (or ptr-to): %s", rtype, name))
- }
-
- // Set offset info.
- var off next_offset
- off.derefs = n
-
- var ok bool
-
- // Look for the next field by name.
- field, ok = rtype.FieldByName(name)
- if !ok {
- panic(fmt.Sprintf("unknown field: %s", name))
- }
-
- // Set next offset value.
- off.offset = field.Offset
- sfield.offsets = append(sfield.offsets, off)
-
- // Calculate value flags, and set next nested field type.
- flags = xunsafe.ReflectStructFieldFlags(t.Flag, field.Type)
- t = t.Child(field.Type, flags)
- }
-
- // Set final field type.
- ftype = t.TypeInfo.Type
-
- // Get mangler from type info.
- sfield.mangle = mangler.Get(t)
-
- // Calculate zero value string.
- zptr := zero_value_ptr(o, sfield.offsets)
- zstr := string(sfield.mangle(nil, zptr))
- sfield.zerostr = zstr
- sfield.zero = zptr
-
- return
-}
-
-// zero_value iterates the type contained in TypeIter{} along the given
-// next_offset{} values, creating new ptrs where necessary, returning the
-// zero reflect.Value{} after fully iterating the next_offset{} slice.
-func zero_value(t xunsafe.TypeIter, offsets []next_offset) reflect.Value {
- v := reflect.New(t.Type).Elem()
- for _, offset := range offsets {
- for range offset.derefs {
- if v.IsNil() {
- new := reflect.New(v.Type().Elem())
- v.Set(new)
- }
- v = v.Elem()
- }
- for i := 0; i < v.NumField(); i++ {
- if v.Type().Field(i).Offset == offset.offset {
- v = v.Field(i)
- break
- }
- }
- }
- return v
-}
-
-// zero_value_ptr returns the unsafe pointer address of the result of zero_value().
-func zero_value_ptr(t xunsafe.TypeIter, offsets []next_offset) unsafe.Pointer {
- return zero_value(t, offsets).Addr().UnsafePointer()
-}
-
-// extract_fields extracts given structfields from the provided value type,
-// this is done using predetermined struct field memory offset locations.
-func extract_fields(ptr unsafe.Pointer, fields []struct_field) []unsafe.Pointer {
-
- // Prepare slice of field value pointers.
- ptrs := make([]unsafe.Pointer, len(fields))
- if len(ptrs) != len(fields) {
- panic(assert("BCE"))
- }
-
- for i, field := range fields {
- // loop scope.
- fptr := ptr
-
- for _, offset := range field.offsets {
- // Dereference any ptrs to offset.
- fptr = deref(fptr, offset.derefs)
- if fptr == nil {
- break
- }
-
- // Jump forward by offset to next ptr.
- fptr = unsafe.Pointer(uintptr(fptr) +
- offset.offset)
- }
-
- if fptr == nil {
- // Use zero value.
- fptr = field.zero
- }
-
- // Set field ptr.
- ptrs[i] = fptr
- }
-
- return ptrs
-}
-
-// pkey_field contains pre-prepared type
-// information about a primary key struct's
-// field member, including memory offset.
-type pkey_field struct {
-
- // zero value data, used when
- // nil encountered during ptr
- // offset following.
- zero unsafe.Pointer
-
- // offsets defines whereabouts in
- // memory this field is located.
- offsets []next_offset
-}
-
-// extract_pkey will extract a pointer from 'ptr', to
-// the primary key struct field defined by 'field'.
-func extract_pkey(ptr unsafe.Pointer, field pkey_field) unsafe.Pointer {
- for _, offset := range field.offsets {
-
- // Dereference any ptrs to offset.
- ptr = deref(ptr, offset.derefs)
- if ptr == nil {
- break
- }
-
- // Jump forward by offset to next ptr.
- ptr = unsafe.Pointer(uintptr(ptr) +
- offset.offset)
- }
-
- if ptr == nil {
- // Use zero value.
- ptr = field.zero
- }
-
- return ptr
-}
-
-// deref will dereference ptr 'n' times (or until nil).
-func deref(p unsafe.Pointer, n int) unsafe.Pointer {
- for ; n > 0; n-- {
- if p == nil {
- return nil
- }
- p = *(*unsafe.Pointer)(p)
- }
- return p
-}
-
-// assert can be called to indicated a block
-// of code should not be able to be reached,
-// it returns a BUG report with callsite.
-func assert(assert string) string {
- pcs := make([]uintptr, 1)
- _ = runtime.Callers(2, pcs)
- funcname := "go-structr" // by default use just our library name
- if frames := runtime.CallersFrames(pcs); frames != nil {
- frame, _ := frames.Next()
- funcname = frame.Function
- if i := strings.LastIndexByte(funcname, '/'); i != -1 {
- funcname = funcname[i+1:]
- }
- }
- var buf strings.Builder
- buf.Grow(32 + len(assert) + len(funcname))
- buf.WriteString("BUG: assertion \"")
- buf.WriteString(assert)
- buf.WriteString("\" failed in ")
- buf.WriteString(funcname)
- return buf.String()
-}