gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

unsafe_slice.go (5294B)


      1 package reflect2
      2 
      3 import (
      4 	"reflect"
      5 	"unsafe"
      6 )
      7 
      8 // sliceHeader is a safe version of SliceHeader used within this package.
      9 type sliceHeader struct {
     10 	Data unsafe.Pointer
     11 	Len  int
     12 	Cap  int
     13 }
     14 
     15 type UnsafeSliceType struct {
     16 	unsafeType
     17 	elemRType  unsafe.Pointer
     18 	pElemRType unsafe.Pointer
     19 	elemSize   uintptr
     20 }
     21 
     22 func newUnsafeSliceType(cfg *frozenConfig, type1 reflect.Type) SliceType {
     23 	elemType := type1.Elem()
     24 	return &UnsafeSliceType{
     25 		unsafeType: *newUnsafeType(cfg, type1),
     26 		pElemRType: unpackEFace(reflect.PtrTo(elemType)).data,
     27 		elemRType:  unpackEFace(elemType).data,
     28 		elemSize:   elemType.Size(),
     29 	}
     30 }
     31 
     32 func (type2 *UnsafeSliceType) Set(obj interface{}, val interface{}) {
     33 	objEFace := unpackEFace(obj)
     34 	assertType("Type.Set argument 1", type2.ptrRType, objEFace.rtype)
     35 	valEFace := unpackEFace(val)
     36 	assertType("Type.Set argument 2", type2.ptrRType, valEFace.rtype)
     37 	type2.UnsafeSet(objEFace.data, valEFace.data)
     38 }
     39 
     40 func (type2 *UnsafeSliceType) UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer) {
     41 	*(*sliceHeader)(ptr) = *(*sliceHeader)(val)
     42 }
     43 
     44 func (type2 *UnsafeSliceType) IsNil(obj interface{}) bool {
     45 	if obj == nil {
     46 		return true
     47 	}
     48 	objEFace := unpackEFace(obj)
     49 	assertType("Type.IsNil argument 1", type2.ptrRType, objEFace.rtype)
     50 	return type2.UnsafeIsNil(objEFace.data)
     51 }
     52 
     53 func (type2 *UnsafeSliceType) UnsafeIsNil(ptr unsafe.Pointer) bool {
     54 	if ptr == nil {
     55 		return true
     56 	}
     57 	return (*sliceHeader)(ptr).Data == nil
     58 }
     59 
     60 func (type2 *UnsafeSliceType) SetNil(obj interface{}) {
     61 	objEFace := unpackEFace(obj)
     62 	assertType("SliceType.SetNil argument 1", type2.ptrRType, objEFace.rtype)
     63 	type2.UnsafeSetNil(objEFace.data)
     64 }
     65 
     66 func (type2 *UnsafeSliceType) UnsafeSetNil(ptr unsafe.Pointer) {
     67 	header := (*sliceHeader)(ptr)
     68 	header.Len = 0
     69 	header.Cap = 0
     70 	header.Data = nil
     71 }
     72 
     73 func (type2 *UnsafeSliceType) MakeSlice(length int, cap int) interface{} {
     74 	return packEFace(type2.ptrRType, type2.UnsafeMakeSlice(length, cap))
     75 }
     76 
     77 func (type2 *UnsafeSliceType) UnsafeMakeSlice(length int, cap int) unsafe.Pointer {
     78 	header := &sliceHeader{unsafe_NewArray(type2.elemRType, cap), length, cap}
     79 	return unsafe.Pointer(header)
     80 }
     81 
     82 func (type2 *UnsafeSliceType) LengthOf(obj interface{}) int {
     83 	objEFace := unpackEFace(obj)
     84 	assertType("SliceType.Len argument 1", type2.ptrRType, objEFace.rtype)
     85 	return type2.UnsafeLengthOf(objEFace.data)
     86 }
     87 
     88 func (type2 *UnsafeSliceType) UnsafeLengthOf(obj unsafe.Pointer) int {
     89 	header := (*sliceHeader)(obj)
     90 	return header.Len
     91 }
     92 
     93 func (type2 *UnsafeSliceType) SetIndex(obj interface{}, index int, elem interface{}) {
     94 	objEFace := unpackEFace(obj)
     95 	assertType("SliceType.SetIndex argument 1", type2.ptrRType, objEFace.rtype)
     96 	elemEFace := unpackEFace(elem)
     97 	assertType("SliceType.SetIndex argument 3", type2.pElemRType, elemEFace.rtype)
     98 	type2.UnsafeSetIndex(objEFace.data, index, elemEFace.data)
     99 }
    100 
    101 func (type2 *UnsafeSliceType) UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer) {
    102 	header := (*sliceHeader)(obj)
    103 	elemPtr := arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
    104 	typedmemmove(type2.elemRType, elemPtr, elem)
    105 }
    106 
    107 func (type2 *UnsafeSliceType) GetIndex(obj interface{}, index int) interface{} {
    108 	objEFace := unpackEFace(obj)
    109 	assertType("SliceType.GetIndex argument 1", type2.ptrRType, objEFace.rtype)
    110 	elemPtr := type2.UnsafeGetIndex(objEFace.data, index)
    111 	return packEFace(type2.pElemRType, elemPtr)
    112 }
    113 
    114 func (type2 *UnsafeSliceType) UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer {
    115 	header := (*sliceHeader)(obj)
    116 	return arrayAt(header.Data, index, type2.elemSize, "i < s.Len")
    117 }
    118 
    119 func (type2 *UnsafeSliceType) Append(obj interface{}, elem interface{}) {
    120 	objEFace := unpackEFace(obj)
    121 	assertType("SliceType.Append argument 1", type2.ptrRType, objEFace.rtype)
    122 	elemEFace := unpackEFace(elem)
    123 	assertType("SliceType.Append argument 2", type2.pElemRType, elemEFace.rtype)
    124 	type2.UnsafeAppend(objEFace.data, elemEFace.data)
    125 }
    126 
    127 func (type2 *UnsafeSliceType) UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer) {
    128 	header := (*sliceHeader)(obj)
    129 	oldLen := header.Len
    130 	type2.UnsafeGrow(obj, oldLen+1)
    131 	type2.UnsafeSetIndex(obj, oldLen, elem)
    132 }
    133 
    134 func (type2 *UnsafeSliceType) Cap(obj interface{}) int {
    135 	objEFace := unpackEFace(obj)
    136 	assertType("SliceType.Cap argument 1", type2.ptrRType, objEFace.rtype)
    137 	return type2.UnsafeCap(objEFace.data)
    138 }
    139 
    140 func (type2 *UnsafeSliceType) UnsafeCap(ptr unsafe.Pointer) int {
    141 	return (*sliceHeader)(ptr).Cap
    142 }
    143 
    144 func (type2 *UnsafeSliceType) Grow(obj interface{}, newLength int) {
    145 	objEFace := unpackEFace(obj)
    146 	assertType("SliceType.Grow argument 1", type2.ptrRType, objEFace.rtype)
    147 	type2.UnsafeGrow(objEFace.data, newLength)
    148 }
    149 
    150 func (type2 *UnsafeSliceType) UnsafeGrow(obj unsafe.Pointer, newLength int) {
    151 	header := (*sliceHeader)(obj)
    152 	if newLength <= header.Cap {
    153 		header.Len = newLength
    154 		return
    155 	}
    156 	newCap := calcNewCap(header.Cap, newLength)
    157 	newHeader := (*sliceHeader)(type2.UnsafeMakeSlice(header.Len, newCap))
    158 	typedslicecopy(type2.elemRType, *newHeader, *header)
    159 	header.Data = newHeader.Data
    160 	header.Cap = newHeader.Cap
    161 	header.Len = newLength
    162 }
    163 
    164 func calcNewCap(cap int, expectedCap int) int {
    165 	if cap == 0 {
    166 		cap = expectedCap
    167 	} else {
    168 		for cap < expectedCap {
    169 			if cap < 1024 {
    170 				cap += cap
    171 			} else {
    172 				cap += cap / 4
    173 			}
    174 		}
    175 	}
    176 	return cap
    177 }