214 lines
4.2 KiB
Go
214 lines
4.2 KiB
Go
/*
|
|
* Copyright 2021 ByteDance Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package rt
|
|
|
|
import (
|
|
`reflect`
|
|
`unsafe`
|
|
)
|
|
|
|
var (
|
|
reflectRtypeItab = findReflectRtypeItab()
|
|
)
|
|
|
|
// GoType.KindFlags const
|
|
const (
|
|
F_direct = 1 << 5
|
|
F_kind_mask = (1 << 5) - 1
|
|
)
|
|
|
|
// GoType.Flags const
|
|
const (
|
|
tflagUncommon uint8 = 1 << 0
|
|
tflagExtraStar uint8 = 1 << 1
|
|
tflagNamed uint8 = 1 << 2
|
|
tflagRegularMemory uint8 = 1 << 3
|
|
)
|
|
|
|
type GoType struct {
|
|
Size uintptr
|
|
PtrData uintptr
|
|
Hash uint32
|
|
Flags uint8
|
|
Align uint8
|
|
FieldAlign uint8
|
|
KindFlags uint8
|
|
Traits unsafe.Pointer
|
|
GCData *byte
|
|
Str int32
|
|
PtrToSelf int32
|
|
}
|
|
|
|
func (self *GoType) IsNamed() bool {
|
|
return (self.Flags & tflagNamed) != 0
|
|
}
|
|
|
|
func (self *GoType) Kind() reflect.Kind {
|
|
return reflect.Kind(self.KindFlags & F_kind_mask)
|
|
}
|
|
|
|
func (self *GoType) Pack() (t reflect.Type) {
|
|
(*GoIface)(unsafe.Pointer(&t)).Itab = reflectRtypeItab
|
|
(*GoIface)(unsafe.Pointer(&t)).Value = unsafe.Pointer(self)
|
|
return
|
|
}
|
|
|
|
func (self *GoType) String() string {
|
|
return self.Pack().String()
|
|
}
|
|
|
|
func (self *GoType) Indirect() bool {
|
|
return self.KindFlags & F_direct == 0
|
|
}
|
|
|
|
type GoMap struct {
|
|
Count int
|
|
Flags uint8
|
|
B uint8
|
|
Overflow uint16
|
|
Hash0 uint32
|
|
Buckets unsafe.Pointer
|
|
OldBuckets unsafe.Pointer
|
|
Evacuate uintptr
|
|
Extra unsafe.Pointer
|
|
}
|
|
|
|
type GoMapIterator struct {
|
|
K unsafe.Pointer
|
|
V unsafe.Pointer
|
|
T *GoMapType
|
|
H *GoMap
|
|
Buckets unsafe.Pointer
|
|
Bptr *unsafe.Pointer
|
|
Overflow *[]unsafe.Pointer
|
|
OldOverflow *[]unsafe.Pointer
|
|
StartBucket uintptr
|
|
Offset uint8
|
|
Wrapped bool
|
|
B uint8
|
|
I uint8
|
|
Bucket uintptr
|
|
CheckBucket uintptr
|
|
}
|
|
|
|
type GoItab struct {
|
|
it unsafe.Pointer
|
|
Vt *GoType
|
|
hv uint32
|
|
_ [4]byte
|
|
fn [1]uintptr
|
|
}
|
|
|
|
type GoIface struct {
|
|
Itab *GoItab
|
|
Value unsafe.Pointer
|
|
}
|
|
|
|
type GoEface struct {
|
|
Type *GoType
|
|
Value unsafe.Pointer
|
|
}
|
|
|
|
func (self GoEface) Pack() (v interface{}) {
|
|
*(*GoEface)(unsafe.Pointer(&v)) = self
|
|
return
|
|
}
|
|
|
|
type GoPtrType struct {
|
|
GoType
|
|
Elem *GoType
|
|
}
|
|
|
|
type GoMapType struct {
|
|
GoType
|
|
Key *GoType
|
|
Elem *GoType
|
|
Bucket *GoType
|
|
Hasher func(unsafe.Pointer, uintptr) uintptr
|
|
KeySize uint8
|
|
ElemSize uint8
|
|
BucketSize uint16
|
|
Flags uint32
|
|
}
|
|
|
|
func (self *GoMapType) IndirectElem() bool {
|
|
return self.Flags & 2 != 0
|
|
}
|
|
|
|
type GoStructType struct {
|
|
GoType
|
|
Pkg *byte
|
|
Fields []GoStructField
|
|
}
|
|
|
|
type GoStructField struct {
|
|
Name *byte
|
|
Type *GoType
|
|
OffEmbed uintptr
|
|
}
|
|
|
|
type GoInterfaceType struct {
|
|
GoType
|
|
PkgPath *byte
|
|
Methods []GoInterfaceMethod
|
|
}
|
|
|
|
type GoInterfaceMethod struct {
|
|
Name int32
|
|
Type int32
|
|
}
|
|
|
|
type GoSlice struct {
|
|
Ptr unsafe.Pointer
|
|
Len int
|
|
Cap int
|
|
}
|
|
|
|
type GoString struct {
|
|
Ptr unsafe.Pointer
|
|
Len int
|
|
}
|
|
|
|
func PtrElem(t *GoType) *GoType {
|
|
return (*GoPtrType)(unsafe.Pointer(t)).Elem
|
|
}
|
|
|
|
func MapType(t *GoType) *GoMapType {
|
|
return (*GoMapType)(unsafe.Pointer(t))
|
|
}
|
|
|
|
func IfaceType(t *GoType) *GoInterfaceType {
|
|
return (*GoInterfaceType)(unsafe.Pointer(t))
|
|
}
|
|
|
|
func UnpackType(t reflect.Type) *GoType {
|
|
return (*GoType)((*GoIface)(unsafe.Pointer(&t)).Value)
|
|
}
|
|
|
|
func UnpackEface(v interface{}) GoEface {
|
|
return *(*GoEface)(unsafe.Pointer(&v))
|
|
}
|
|
|
|
func UnpackIface(v interface{}) GoIface {
|
|
return *(*GoIface)(unsafe.Pointer(&v))
|
|
}
|
|
|
|
func findReflectRtypeItab() *GoItab {
|
|
v := reflect.TypeOf(struct{}{})
|
|
return (*GoIface)(unsafe.Pointer(&v)).Itab
|
|
}
|