//go:build go1.24 && !go1.26 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 } // abi_NonEmptyInterface is a copy of the memory layout of abi.NonEmptyInterface{}, // which is to say also the memory layout of any interface containing method(s). // // see: go/src/internal/abi/iface.go on 1.25+ // see: go/src/reflect/value.go on 1.24 type abi_NonEmptyInterface struct { ITab uintptr Data unsafe.Pointer } // see: go/src/internal/abi/type.go Type.Kind() func abi_Type_Kind(t reflect.Type) uint8 { iface := (*abi_NonEmptyInterface)(unsafe.Pointer(&t)) atype := (*abi_Type)(unsafe.Pointer(iface.Data)) return atype.Kind_ & abi_KindMask } // see: go/src/internal/abi/type.go Type.IfaceIndir() func abi_Type_IfaceIndir(t reflect.Type) bool { iface := (*abi_NonEmptyInterface)(unsafe.Pointer(&t)) atype := (*abi_Type)(unsafe.Pointer(iface.Data)) return atype.Kind_&abi_KindDirectIface == 0 } // pack_iface packs a new reflect.nonEmptyInterface{} using shielded // itab and data pointer, returning a pointer for caller casting. func pack_iface(itab uintptr, word unsafe.Pointer) unsafe.Pointer { return unsafe.Pointer(&abi_NonEmptyInterface{ ITab: itab, Data: 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 := (*abi_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<