summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-mangler/v2/load.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mangler/v2/load.go')
-rw-r--r--vendor/codeberg.org/gruf/go-mangler/v2/load.go150
1 files changed, 150 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-mangler/v2/load.go b/vendor/codeberg.org/gruf/go-mangler/v2/load.go
new file mode 100644
index 000000000..8355c5f3c
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mangler/v2/load.go
@@ -0,0 +1,150 @@
+package mangler
+
+import (
+ "reflect"
+ "unsafe"
+
+ "codeberg.org/gruf/go-xunsafe"
+)
+
+// loadOrStore first checks the cache for a Mangler
+// function, else generates one by calling get().
+// note: this does store generated funcs in cache.
+func loadOrStore(t xunsafe.TypeIter) Mangler {
+
+ // Get cache key.
+ key := t.TypeInfo
+
+ // Check cache for func.
+ fn := manglers.Get(key)
+
+ if fn == nil {
+ // Generate new mangler
+ // func for this type.
+ fn = get(t)
+ if fn == nil {
+ return nil
+ }
+
+ // Store func in cache.
+ manglers.Put(key, fn)
+ }
+
+ return fn
+}
+
+// loadOrGet first checks the cache for a Mangler
+// function, else generates one by calling get().
+// note: it does not store the function in cache.
+func loadOrGet(t xunsafe.TypeIter) Mangler {
+
+ // Check cache for mangler func.
+ fn := manglers.Get(t.TypeInfo)
+
+ if fn == nil {
+ // Generate new mangler
+ // func for this type.
+ fn = get(t)
+ }
+
+ return fn
+}
+
+var (
+ // reflectTypeType is the reflected type of the reflect type,
+ // used in fmt.get() to prevent iter of internal ABI structs.
+ reflectTypeType = reflect.TypeOf(reflect.TypeOf(0))
+)
+
+// get attempts to generate a new Mangler function
+// capable of mangling a ptr of given type information.
+func get(t xunsafe.TypeIter) (fn Mangler) {
+ defer func() {
+ if fn == nil {
+ // nothing more
+ // we can do.
+ return
+ }
+
+ if t.Parent != nil {
+ // We're only interested
+ // in wrapping top-level.
+ return
+ }
+
+ // Get reflected type ptr for prefix.
+ ptr := xunsafe.ReflectTypeData(t.Type)
+ uptr := uintptr(ptr)
+
+ // Outer fn.
+ mng := fn
+
+ // Wrap the mangler func to prepend type pointer.
+ fn = func(buf []byte, ptr unsafe.Pointer) []byte {
+ buf = append_uint64(buf, uint64(uptr))
+ return mng(buf, ptr)
+ }
+ }()
+
+ if t.Type == nil {
+ // nil type.
+ return nil
+ }
+
+ if t.Type == reflectTypeType {
+ // DO NOT iterate down internal ABI
+ // types, some are in non-GC memory.
+ return nil
+ }
+
+ // Check supports known method receiver.
+ if fn := getMethodType(t); fn != nil {
+ return fn
+ }
+
+ if !visit(t) {
+ // On type recursion simply
+ // mangle as raw pointer.
+ return mangle_int
+ }
+
+ // Get func for type kind.
+ switch t.Type.Kind() {
+ case reflect.Pointer:
+ return derefPointerType(t)
+ case reflect.Struct:
+ return iterStructType(t)
+ case reflect.Array:
+ return iterArrayType(t)
+ case reflect.Slice:
+ return iterSliceType(t)
+ case reflect.Map:
+ return iterMapType(t)
+ case reflect.String:
+ return mangle_string
+ case reflect.Bool:
+ return mangle_bool
+ case reflect.Int,
+ reflect.Uint,
+ reflect.Uintptr:
+ return mangle_int
+ case reflect.Int8, reflect.Uint8:
+ return mangle_8bit
+ case reflect.Int16, reflect.Uint16:
+ return mangle_16bit
+ case reflect.Int32, reflect.Uint32:
+ return mangle_32bit
+ case reflect.Int64, reflect.Uint64:
+ return mangle_64bit
+ case reflect.Float32:
+ return mangle_32bit
+ case reflect.Float64:
+ return mangle_64bit
+ case reflect.Complex64:
+ return mangle_64bit
+ case reflect.Complex128:
+ return mangle_128bit
+ default:
+ return nil
+ }
+}