fastvalue.go raw

   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 GoItab struct {
  79      it unsafe.Pointer
  80      Vt *GoType
  81      hv uint32
  82      _  [4]byte
  83      fn [1]uintptr
  84  }
  85  
  86  type GoIface struct {
  87      Itab  *GoItab
  88      Value unsafe.Pointer
  89  }
  90  
  91  type GoEface struct {
  92      Type  *GoType
  93      Value unsafe.Pointer
  94  }
  95  
  96  func (self GoEface) Pack() (v interface{}) {
  97      *(*GoEface)(unsafe.Pointer(&v)) = self
  98      return
  99  }
 100  
 101  type GoPtrType struct {
 102      GoType
 103      Elem *GoType
 104  }
 105  
 106  type GoMapType struct {
 107      GoType
 108      Key        *GoType
 109      Elem       *GoType
 110      Bucket     *GoType
 111      Hasher     func(unsafe.Pointer, uintptr) uintptr
 112      KeySize    uint8
 113      ElemSize   uint8
 114      BucketSize uint16
 115      Flags      uint32
 116  }
 117  
 118  func (self *GoMapType) IndirectElem() bool {
 119      return self.Flags & 2 != 0
 120  }
 121  
 122  type GoStructType struct {
 123      GoType
 124      Pkg    *byte
 125      Fields []GoStructField
 126  }
 127  
 128  type GoStructField struct {
 129      Name     *byte
 130      Type     *GoType
 131      OffEmbed uintptr
 132  }
 133  
 134  type GoInterfaceType struct {
 135      GoType
 136      PkgPath *byte
 137      Methods []GoInterfaceMethod
 138  }
 139  
 140  type GoInterfaceMethod struct {
 141      Name int32
 142      Type int32
 143  }
 144  
 145  type GoSlice struct {
 146      Ptr unsafe.Pointer
 147      Len int
 148      Cap int
 149  }
 150  
 151  type GoString struct {
 152      Ptr unsafe.Pointer
 153      Len int
 154  }
 155  
 156  func PtrElem(t *GoType) *GoType {
 157      return (*GoPtrType)(unsafe.Pointer(t)).Elem
 158  }
 159  
 160  func MapType(t *GoType) *GoMapType {
 161      return (*GoMapType)(unsafe.Pointer(t))
 162  }
 163  
 164  func IfaceType(t *GoType) *GoInterfaceType {
 165      return (*GoInterfaceType)(unsafe.Pointer(t))
 166  }
 167  
 168  func UnpackType(t reflect.Type) *GoType {
 169      return (*GoType)((*GoIface)(unsafe.Pointer(&t)).Value)
 170  }
 171  
 172  func UnpackEface(v interface{}) GoEface {
 173      return *(*GoEface)(unsafe.Pointer(&v))
 174  }
 175  
 176  func UnpackIface(v interface{}) GoIface {
 177      return *(*GoIface)(unsafe.Pointer(&v))
 178  }
 179  
 180  func findReflectRtypeItab() *GoItab {
 181      v := reflect.TypeOf(struct{}{})
 182      return (*GoIface)(unsafe.Pointer(&v)).Itab
 183  }
 184