github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/link_reflect.go (about)

     1  package jzon
     2  
     3  import (
     4  	"unsafe"
     5  )
     6  
     7  /*
     8   * WARNING:
     9   * The linked functions in this file should be used with EXTREMELY careful
    10   */
    11  
    12  //go:linkname unsafe_New reflect.unsafe_New
    13  func unsafe_New(rtype rtype) unsafe.Pointer
    14  
    15  //go:linkname typedmemclrpartial reflect.typedmemclrpartial
    16  //go:noescape
    17  func typedmemclrpartial(t rtype, ptr unsafe.Pointer, off, size uintptr)
    18  
    19  //go:linkname unsafe_NewArray reflect.unsafe_NewArray
    20  func unsafe_NewArray(rtype rtype, length int) unsafe.Pointer
    21  
    22  //go:linkname typedslicecopy reflect.typedslicecopy
    23  //go:noescape
    24  func typedslicecopy(rtyp rtype, dst, src sliceHeader) int
    25  
    26  //go:linkname makemap reflect.makemap
    27  func makemap(rtype rtype, cap int) unsafe.Pointer
    28  
    29  //go:linkname typedmemmove reflect.typedmemmove
    30  //go:noescape
    31  func typedmemmove(rtype rtype, dst, src unsafe.Pointer)
    32  
    33  //go:linkname mapassign reflect.mapassign
    34  //go:noescape
    35  func mapassign(t rtype, m, key, val unsafe.Pointer)
    36  
    37  //go:linkname maplen reflect.maplen
    38  //go:noescape
    39  func maplen(m unsafe.Pointer) int
    40  
    41  //go:linkname ifaceIndir reflect.ifaceIndir
    42  func ifaceIndir(t rtype) bool
    43  
    44  type hiter struct {
    45  	key         unsafe.Pointer
    46  	elem        unsafe.Pointer
    47  	t           unsafe.Pointer
    48  	h           unsafe.Pointer
    49  	buckets     unsafe.Pointer
    50  	bptr        unsafe.Pointer
    51  	overflow    unsafe.Pointer
    52  	oldoverflow unsafe.Pointer
    53  	startBucket uintptr
    54  	offset      uint8
    55  	wrapped     bool
    56  	B           uint8
    57  	i           uint8
    58  	bucket      uintptr
    59  	checkBucket uintptr
    60  }
    61  
    62  //go:noescape
    63  //go:linkname mapiternext reflect.mapiternext
    64  func mapiternext(it *hiter)
    65  
    66  func unsafeMakeSlice(elemRType rtype, length, cap int) unsafe.Pointer {
    67  	return unsafe.Pointer(&sliceHeader{
    68  		Data: uintptr(unsafe_NewArray(elemRType, cap)),
    69  		Len:  length,
    70  		Cap:  cap,
    71  	})
    72  }
    73  
    74  func unsafeMakeMap(rtype rtype, cap int) unsafe.Pointer {
    75  	m := makemap(rtype, cap)
    76  	return unsafe.Pointer(&m)
    77  }
    78  
    79  // see reflect.add
    80  func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
    81  	return unsafe.Pointer(uintptr(p) + x)
    82  }
    83  
    84  // see reflect.grow
    85  func unsafeGrowSlice(elemRType rtype, ptr unsafe.Pointer, newLength int) unsafe.Pointer {
    86  	sh := (*sliceHeader)(ptr)
    87  	if newLength < sh.Cap {
    88  		sh.Len = newLength
    89  		return ptr
    90  	}
    91  	newCap := sh.Cap
    92  	if sh.Cap == 0 {
    93  		newCap = newLength
    94  	} else {
    95  		for newCap < newLength {
    96  			if newCap < 1024 {
    97  				newCap <<= 1
    98  			} else {
    99  				newCap += newCap >> 2
   100  			}
   101  		}
   102  	}
   103  	newHeader := (*sliceHeader)(unsafeMakeSlice(elemRType, newLength, newCap))
   104  	typedslicecopy(elemRType, *newHeader, *sh)
   105  	return unsafe.Pointer(newHeader)
   106  }
   107  
   108  func unsafeSliceChildPtr(ptr unsafe.Pointer, elemSize uintptr, index int) unsafe.Pointer {
   109  	sh := (*sliceHeader)(ptr)
   110  	return add(unsafe.Pointer(sh.Data), uintptr(index)*elemSize, "index < len")
   111  }
   112  
   113  //go:nosplit
   114  func noescape(p unsafe.Pointer) unsafe.Pointer {
   115  	x := uintptr(p)
   116  	return unsafe.Pointer(x ^ 0)
   117  }