github.com/goshafaq/sonic@v0.0.0-20231026082336-871835fb94c6/internal/rt/fastvalue.go (about)

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package rt
    18  
    19  import (
    20  	"reflect"
    21  	"unsafe"
    22  )
    23  
    24  var (
    25  	reflectRtypeItab = findReflectRtypeItab()
    26  )
    27  
    28  // GoType.KindFlags const
    29  const (
    30  	F_direct    = 1 << 5
    31  	F_kind_mask = (1 << 5) - 1
    32  )
    33  
    34  // GoType.Flags const
    35  const (
    36  	tflagUncommon      uint8 = 1 << 0
    37  	tflagExtraStar     uint8 = 1 << 1
    38  	tflagNamed         uint8 = 1 << 2
    39  	tflagRegularMemory uint8 = 1 << 3
    40  )
    41  
    42  type GoType struct {
    43  	Size       uintptr
    44  	PtrData    uintptr
    45  	Hash       uint32
    46  	Flags      uint8
    47  	Align      uint8
    48  	FieldAlign uint8
    49  	KindFlags  uint8
    50  	Traits     unsafe.Pointer
    51  	GCData     *byte
    52  	Str        int32
    53  	PtrToSelf  int32
    54  }
    55  
    56  func (self *GoType) IsNamed() bool {
    57  	return (self.Flags & tflagNamed) != 0
    58  }
    59  
    60  func (self *GoType) Kind() reflect.Kind {
    61  	return reflect.Kind(self.KindFlags & F_kind_mask)
    62  }
    63  
    64  func (self *GoType) Pack() (t reflect.Type) {
    65  	(*GoIface)(unsafe.Pointer(&t)).Itab = reflectRtypeItab
    66  	(*GoIface)(unsafe.Pointer(&t)).Value = unsafe.Pointer(self)
    67  	return
    68  }
    69  
    70  func (self *GoType) String() string {
    71  	return self.Pack().String()
    72  }
    73  
    74  func (self *GoType) Indirect() bool {
    75  	return self.KindFlags&F_direct == 0
    76  }
    77  
    78  type GoMap struct {
    79  	Count      int
    80  	Flags      uint8
    81  	B          uint8
    82  	Overflow   uint16
    83  	Hash0      uint32
    84  	Buckets    unsafe.Pointer
    85  	OldBuckets unsafe.Pointer
    86  	Evacuate   uintptr
    87  	Extra      unsafe.Pointer
    88  }
    89  
    90  type GoMapIterator struct {
    91  	K           unsafe.Pointer
    92  	V           unsafe.Pointer
    93  	T           *GoMapType
    94  	H           *GoMap
    95  	Buckets     unsafe.Pointer
    96  	Bptr        *unsafe.Pointer
    97  	Overflow    *[]unsafe.Pointer
    98  	OldOverflow *[]unsafe.Pointer
    99  	StartBucket uintptr
   100  	Offset      uint8
   101  	Wrapped     bool
   102  	B           uint8
   103  	I           uint8
   104  	Bucket      uintptr
   105  	CheckBucket uintptr
   106  }
   107  
   108  type GoItab struct {
   109  	it unsafe.Pointer
   110  	Vt *GoType
   111  	hv uint32
   112  	_  [4]byte
   113  	fn [1]uintptr
   114  }
   115  
   116  type GoIface struct {
   117  	Itab  *GoItab
   118  	Value unsafe.Pointer
   119  }
   120  
   121  type GoEface struct {
   122  	Type  *GoType
   123  	Value unsafe.Pointer
   124  }
   125  
   126  func (self GoEface) Pack() (v interface{}) {
   127  	*(*GoEface)(unsafe.Pointer(&v)) = self
   128  	return
   129  }
   130  
   131  type GoPtrType struct {
   132  	GoType
   133  	Elem *GoType
   134  }
   135  
   136  type GoMapType struct {
   137  	GoType
   138  	Key        *GoType
   139  	Elem       *GoType
   140  	Bucket     *GoType
   141  	Hasher     func(unsafe.Pointer, uintptr) uintptr
   142  	KeySize    uint8
   143  	ElemSize   uint8
   144  	BucketSize uint16
   145  	Flags      uint32
   146  }
   147  
   148  func (self *GoMapType) IndirectElem() bool {
   149  	return self.Flags&2 != 0
   150  }
   151  
   152  type GoStructType struct {
   153  	GoType
   154  	Pkg    *byte
   155  	Fields []GoStructField
   156  }
   157  
   158  type GoStructField struct {
   159  	Name     *byte
   160  	Type     *GoType
   161  	OffEmbed uintptr
   162  }
   163  
   164  type GoInterfaceType struct {
   165  	GoType
   166  	PkgPath *byte
   167  	Methods []GoInterfaceMethod
   168  }
   169  
   170  type GoInterfaceMethod struct {
   171  	Name int32
   172  	Type int32
   173  }
   174  
   175  type GoSlice struct {
   176  	Ptr unsafe.Pointer
   177  	Len int
   178  	Cap int
   179  }
   180  
   181  type GoString struct {
   182  	Ptr unsafe.Pointer
   183  	Len int
   184  }
   185  
   186  func PtrElem(t *GoType) *GoType {
   187  	return (*GoPtrType)(unsafe.Pointer(t)).Elem
   188  }
   189  
   190  func MapType(t *GoType) *GoMapType {
   191  	return (*GoMapType)(unsafe.Pointer(t))
   192  }
   193  
   194  func IfaceType(t *GoType) *GoInterfaceType {
   195  	return (*GoInterfaceType)(unsafe.Pointer(t))
   196  }
   197  
   198  func UnpackType(t reflect.Type) *GoType {
   199  	return (*GoType)((*GoIface)(unsafe.Pointer(&t)).Value)
   200  }
   201  
   202  func UnpackEface(v interface{}) GoEface {
   203  	return *(*GoEface)(unsafe.Pointer(&v))
   204  }
   205  
   206  func UnpackIface(v interface{}) GoIface {
   207  	return *(*GoIface)(unsafe.Pointer(&v))
   208  }
   209  
   210  func findReflectRtypeItab() *GoItab {
   211  	v := reflect.TypeOf(struct{}{})
   212  	return (*GoIface)(unsafe.Pointer(&v)).Itab
   213  }