mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-11-03 23:52:26 -06:00 
			
		
		
		
	
		
			
	
	
		
			110 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			110 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								//go:build go1.24 && !go1.26
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								package xunsafe
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"reflect"
							 | 
						||
| 
								 | 
							
									"unsafe"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func init() {
							 | 
						||
| 
								 | 
							
									// TypeOf(reflect.Type{}) == *struct{ abi.Type{} }
							 | 
						||
| 
								 | 
							
									t := reflect.TypeOf(reflect.TypeOf(0)).Elem()
							 | 
						||
| 
								 | 
							
									if t.Size() != unsafe.Sizeof(Abi_Type{}) {
							 | 
						||
| 
								 | 
							
										panic("Abi_Type{} not in sync with abi.Type{}")
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// PackIface packs a new reflect.nonEmptyInterface{} using shielded
							 | 
						||
| 
								 | 
							
								// itab and data pointer, returning a pointer for caller casting.
							 | 
						||
| 
								 | 
							
								func PackIface(itab uintptr, word unsafe.Pointer) unsafe.Pointer {
							 | 
						||
| 
								 | 
							
									return unsafe.Pointer(&Abi_NonEmptyInterface{
							 | 
						||
| 
								 | 
							
										ITab: itab,
							 | 
						||
| 
								 | 
							
										Data: word,
							 | 
						||
| 
								 | 
							
									})
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// GetIfaceITab generates a new value of given type,
							 | 
						||
| 
								 | 
							
								// casts it to the generic param interface type, and
							 | 
						||
| 
								 | 
							
								// returns the .itab portion of the abi.NonEmptyInterface{}.
							 | 
						||
| 
								 | 
							
								// this is useful for later calls to PackIface for known type.
							 | 
						||
| 
								 | 
							
								func GetIfaceITab[I any](t reflect.Type) uintptr {
							 | 
						||
| 
								 | 
							
									s := reflect.New(t).Elem().Interface().(I)
							 | 
						||
| 
								 | 
							
									i := (*Abi_NonEmptyInterface)(unsafe.Pointer(&s))
							 | 
						||
| 
								 | 
							
									return i.ITab
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// UnpackEface returns the .Data portion of an abi.EmptyInterface{}.
							 | 
						||
| 
								 | 
							
								func UnpackEface(a any) unsafe.Pointer {
							 | 
						||
| 
								 | 
							
									return (*Abi_EmptyInterface)(unsafe.Pointer((&a))).Data
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// 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
							 | 
						||
| 
								 | 
							
								}
							 |