typeinfo.mx raw

   1  package json
   2  
   3  import "unsafe"
   4  
   5  type jKind uint8
   6  
   7  const (
   8  	jkInvalid jKind = iota
   9  	jkBool
  10  	jkInt
  11  	jkInt8
  12  	jkInt16
  13  	jkInt32
  14  	jkInt64
  15  	jkUint
  16  	jkUint8
  17  	jkUint16
  18  	jkUint32
  19  	jkUint64
  20  	jkUintptr
  21  	jkFloat32
  22  	jkFloat64
  23  	jkComplex64
  24  	jkComplex128
  25  	jkBytes // 17: unified string=[]byte
  26  	jkUnsafePointer
  27  	jkChan
  28  	jkInterface
  29  	jkPointer
  30  	jkSlice
  31  	jkArray
  32  	jkFunc
  33  	jkMap
  34  	jkStruct
  35  )
  36  
  37  const (
  38  	_kindMask  = 31
  39  	_flagNamed = 32
  40  )
  41  
  42  const (
  43  	_sfAnonymous = 1 << iota
  44  	_sfHasTag
  45  	_sfExported
  46  )
  47  
  48  type _ifacePair struct {
  49  	typecode unsafe.Pointer
  50  	value    unsafe.Pointer
  51  }
  52  
  53  type _rawType struct {
  54  	meta uint8
  55  }
  56  
  57  type _elemType struct {
  58  	_rawType
  59  	numMethod uint16
  60  	ptrTo     *_rawType
  61  	elem      *_rawType
  62  }
  63  
  64  type _ptrType struct {
  65  	_rawType
  66  	numMethod uint16
  67  	elem      *_rawType
  68  }
  69  
  70  type _structType struct {
  71  	_rawType
  72  	numMethod uint16
  73  	ptrTo     *_rawType
  74  	pkgpath   *byte
  75  	size      uint32
  76  	numField  uint16
  77  	fields    [1]_structFieldDesc
  78  }
  79  
  80  type _structFieldDesc struct {
  81  	fieldType *_rawType
  82  	data      unsafe.Pointer
  83  }
  84  
  85  type _sliceHeader struct {
  86  	data unsafe.Pointer
  87  	len  int
  88  	cap  int
  89  }
  90  
  91  func (t *_rawType) kind() jKind {
  92  	if t == nil {
  93  		return jkInvalid
  94  	}
  95  	if uintptr(unsafe.Pointer(t))&0b11 != 0 {
  96  		return jkPointer
  97  	}
  98  	return jKind(t.meta & _kindMask)
  99  }
 100  
 101  func (t *_rawType) isNamed() bool {
 102  	if uintptr(unsafe.Pointer(t))&0b11 != 0 {
 103  		return false
 104  	}
 105  	return t.meta&_flagNamed != 0
 106  }
 107  
 108  func (t *_rawType) underlying() *_rawType {
 109  	if t.isNamed() {
 110  		return (*_elemType)(unsafe.Pointer(t)).elem
 111  	}
 112  	return t
 113  }
 114  
 115  func (t *_rawType) size() uintptr {
 116  	switch t.kind() {
 117  	case jkBool, jkInt8, jkUint8:
 118  		return 1
 119  	case jkInt16, jkUint16:
 120  		return 2
 121  	case jkInt32, jkUint32, jkFloat32:
 122  		return 4
 123  	case jkInt64, jkUint64, jkFloat64:
 124  		return 8
 125  	case jkInt, jkUint:
 126  		return unsafe.Sizeof(int(0))
 127  	case jkUintptr:
 128  		return unsafe.Sizeof(uintptr(0))
 129  	case jkBytes:
 130  		return unsafe.Sizeof("")
 131  	case jkUnsafePointer, jkChan, jkMap, jkPointer:
 132  		return unsafe.Sizeof(uintptr(0))
 133  	case jkSlice:
 134  		return unsafe.Sizeof([]int{})
 135  	case jkInterface:
 136  		return unsafe.Sizeof(interface{}(nil))
 137  	case jkStruct:
 138  		return uintptr((*_structType)(unsafe.Pointer(t.underlying())).size)
 139  	default:
 140  		return 0
 141  	}
 142  }
 143  
 144  func (t *_rawType) elem() *_rawType {
 145  	if tag := uintptr(unsafe.Pointer(t)) & 0b11; tag != 0 {
 146  		return (*_rawType)(unsafe.Pointer(uintptr(unsafe.Pointer(t)) - 1))
 147  	}
 148  	u := t.underlying()
 149  	if u.kind() == jkPointer {
 150  		return (*_ptrType)(unsafe.Pointer(u)).elem
 151  	}
 152  	return (*_elemType)(unsafe.Pointer(u)).elem
 153  }
 154  
 155  func (t *_rawType) numField() int {
 156  	return int((*_structType)(unsafe.Pointer(t.underlying())).numField)
 157  }
 158  
 159  func (t *_rawType) fieldDesc(i int) *_structFieldDesc {
 160  	st := (*_structType)(unsafe.Pointer(t.underlying()))
 161  	return (*_structFieldDesc)(unsafe.Add(
 162  		unsafe.Pointer(&st.fields[0]),
 163  		uintptr(i)*unsafe.Sizeof(_structFieldDesc{}),
 164  	))
 165  }
 166  
 167  func (t *_rawType) fieldType(i int) *_rawType {
 168  	return t.fieldDesc(i).fieldType
 169  }
 170  
 171  func (t *_rawType) fieldData(i int) (flags uint8, offset uintptr, name []byte, tag []byte) {
 172  	fd := t.fieldDesc(i)
 173  	p := (*byte)(fd.data)
 174  
 175  	flags = *p
 176  	p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 177  
 178  	var shift uint
 179  	for {
 180  		b := *p
 181  		offset |= uintptr(b&0x7f) << shift
 182  		if b&0x80 == 0 {
 183  			p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 184  			break
 185  		}
 186  		shift += 7
 187  		p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 188  	}
 189  
 190  	nameStart := unsafe.Pointer(p)
 191  	nameLen := 0
 192  	for *p != 0 {
 193  		nameLen++
 194  		p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 195  	}
 196  	name = unsafe.Slice((*byte)(nameStart), nameLen)
 197  	p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 198  
 199  	if flags&_sfHasTag != 0 {
 200  		tagLen := int(*p)
 201  		p = (*byte)(unsafe.Add(unsafe.Pointer(p), 1))
 202  		tag = unsafe.Slice((*byte)(unsafe.Pointer(p)), tagLen)
 203  	}
 204  	return
 205  }
 206  
 207  func (t *_rawType) fieldOffset(i int) uintptr {
 208  	_, off, _, _ := t.fieldData(i)
 209  	return off
 210  }
 211  
 212  func (t *_rawType) fieldTag(i int) []byte {
 213  	_, _, _, tag := t.fieldData(i)
 214  	return tag
 215  }
 216  
 217  func (t *_rawType) fieldExported(i int) bool {
 218  	flags, _, _, _ := t.fieldData(i)
 219  	return flags&_sfExported != 0
 220  }
 221  
 222  func (t *_rawType) fieldName(i int) []byte {
 223  	_, _, name, _ := t.fieldData(i)
 224  	return name
 225  }
 226  
 227  func (t *_rawType) typeName() []byte {
 228  	if !t.isNamed() {
 229  		return nil
 230  	}
 231  	type _namedType struct {
 232  		_rawType
 233  		numMethod uint16
 234  		ptrTo     *_rawType
 235  		elem      *_rawType
 236  		pkg       *byte
 237  		name      [1]byte
 238  	}
 239  	nt := (*_namedType)(unsafe.Pointer(t))
 240  	p := &nt.name[0]
 241  	n := 0
 242  	for *(*byte)(unsafe.Add(unsafe.Pointer(p), uintptr(n))) != 0 {
 243  		n++
 244  	}
 245  	return unsafe.Slice(p, n)
 246  }
 247  
 248  func typeCodeOf(val any) *_rawType {
 249  	return (*_rawType)((*_ifacePair)(unsafe.Pointer(&val)).typecode)
 250  }
 251  
 252  func dataOf(val any) unsafe.Pointer {
 253  	iface := (*_ifacePair)(unsafe.Pointer(&val))
 254  	t := (*_rawType)(iface.typecode)
 255  	if t.size() <= unsafe.Sizeof(uintptr(0)) {
 256  		return unsafe.Pointer(&iface.value)
 257  	}
 258  	return iface.value
 259  }
 260  
 261  func derefPtr(val any) (*_rawType, unsafe.Pointer) {
 262  	iface := (*_ifacePair)(unsafe.Pointer(&val))
 263  	t := (*_rawType)(iface.typecode)
 264  	if t.kind() != jkPointer {
 265  		return nil, nil
 266  	}
 267  	elemType := t.elem()
 268  	dataPtr := iface.value
 269  	return elemType, dataPtr
 270  }
 271  
 272  func ptrToIface(t *_rawType, ptr unsafe.Pointer) any {
 273  	var ptrType *_rawType
 274  	if t.isNamed() {
 275  		ptrType = (*_elemType)(unsafe.Pointer(t)).ptrTo
 276  	} else {
 277  		switch t.kind() {
 278  		case jkStruct:
 279  			ptrType = (*_structType)(unsafe.Pointer(t)).ptrTo
 280  		default:
 281  			ptrType = (*_elemType)(unsafe.Pointer(t)).ptrTo
 282  		}
 283  	}
 284  	if ptrType == nil {
 285  		return nil
 286  	}
 287  	iface := _ifacePair{typecode: unsafe.Pointer(ptrType), value: ptr}
 288  	return *(*any)(unsafe.Pointer(&iface))
 289  }
 290  
 291  func valToIface(t *_rawType, ptr unsafe.Pointer) any {
 292  	iface := _ifacePair{typecode: unsafe.Pointer(t), value: ptr}
 293  	if t.size() <= unsafe.Sizeof(uintptr(0)) {
 294  		iface.value = *(*unsafe.Pointer)(ptr)
 295  	}
 296  	return *(*any)(unsafe.Pointer(&iface))
 297  }
 298  
 299  func isZeroValue(typ *_rawType, ptr unsafe.Pointer) bool {
 300  	sz := typ.size()
 301  	for i := uintptr(0); i < sz; i++ {
 302  		if *(*byte)(unsafe.Add(ptr, i)) != 0 {
 303  			return false
 304  		}
 305  	}
 306  	return true
 307  }
 308  
 309  func makeSliceOf(elemType *_rawType, length, capacity int) unsafe.Pointer {
 310  	elemSize := elemType.size()
 311  	buf := []byte{:int(elemSize)*capacity}
 312  	var dataPtr unsafe.Pointer
 313  	if len(buf) > 0 {
 314  		dataPtr = unsafe.Pointer(&buf[0])
 315  	}
 316  	p := &_sliceHeader{data: dataPtr, len: length, cap: capacity}
 317  	return unsafe.Pointer(p)
 318  }
 319  
 320  func sliceAppend(slicePtr unsafe.Pointer, elemType *_rawType) unsafe.Pointer {
 321  	hdr := (*_sliceHeader)(slicePtr)
 322  	elemSize := elemType.size()
 323  	if hdr.len >= hdr.cap {
 324  		newCap := hdr.cap * 2
 325  		if newCap < 4 {
 326  			newCap = 4
 327  		}
 328  		newBuf := []byte{:int(elemSize)*newCap}
 329  		var newData unsafe.Pointer
 330  		if len(newBuf) > 0 {
 331  			newData = unsafe.Pointer(&newBuf[0])
 332  		}
 333  		if hdr.data != nil && hdr.len > 0 {
 334  			memcpy(newData, hdr.data, elemSize*uintptr(hdr.len))
 335  		}
 336  		hdr.data = newData
 337  		hdr.cap = newCap
 338  	}
 339  	hdr.len++
 340  	return slicePtr
 341  }
 342  
 343  func sliceIndex(slicePtr unsafe.Pointer, elemType *_rawType, i int) unsafe.Pointer {
 344  	hdr := (*_sliceHeader)(slicePtr)
 345  	return unsafe.Add(hdr.data, elemType.size()*uintptr(i))
 346  }
 347  
 348  //go:linkname memcpy runtime.memcpy
 349  func memcpy(dst, src unsafe.Pointer, n uintptr)
 350