File size: 3,599 Bytes
e36aeda | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package reflect
import (
"internal/abi"
"internal/goarch"
"sync"
"unsafe"
)
// MakeRO returns a copy of v with the read-only flag set.
func MakeRO(v Value) Value {
v.flag |= flagStickyRO
return v
}
// IsRO reports whether v's read-only flag is set.
func IsRO(v Value) bool {
return v.flag&flagStickyRO != 0
}
var CallGC = &callGC
// FuncLayout calls funcLayout and returns a subset of the results for testing.
//
// Bitmaps like stack, gc, inReg, and outReg are expanded such that each bit
// takes up one byte, so that writing out test cases is a little clearer.
// If ptrs is false, gc will be nil.
func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack, gc, inReg, outReg []byte, ptrs bool) {
var ft *abi.Type
var abid abiDesc
if rcvr != nil {
ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.common())), rcvr.common())
} else {
ft, _, abid = funcLayout((*funcType)(unsafe.Pointer(t.(*rtype))), nil)
}
// Extract size information.
argSize = abid.stackCallArgsSize
retOffset = abid.retOffset
frametype = toType(ft)
// Expand stack pointer bitmap into byte-map.
for i := uint32(0); i < abid.stackPtrs.n; i++ {
stack = append(stack, abid.stackPtrs.data[i/8]>>(i%8)&1)
}
// Expand register pointer bitmaps into byte-maps.
bool2byte := func(b bool) byte {
if b {
return 1
}
return 0
}
for i := 0; i < intArgRegs; i++ {
inReg = append(inReg, bool2byte(abid.inRegPtrs.Get(i)))
outReg = append(outReg, bool2byte(abid.outRegPtrs.Get(i)))
}
// Expand frame type's GC bitmap into byte-map.
ptrs = ft.Pointers()
if ptrs {
nptrs := ft.PtrBytes / goarch.PtrSize
gcdata := ft.GcSlice(0, (nptrs+7)/8)
for i := uintptr(0); i < nptrs; i++ {
gc = append(gc, gcdata[i/8]>>(i%8)&1)
}
}
return
}
func TypeLinks() []string {
var r []string
sections, offset := typelinks()
for i, offs := range offset {
rodata := sections[i]
for _, off := range offs {
typ := (*rtype)(resolveTypeOff(rodata, off))
r = append(r, typ.String())
}
}
return r
}
var GCBits = gcbits
func gcbits(any) []byte // provided by runtime
type EmbedWithUnexpMeth struct{}
func (EmbedWithUnexpMeth) f() {}
type pinUnexpMeth interface {
f()
}
var pinUnexpMethI = pinUnexpMeth(EmbedWithUnexpMeth{})
func FirstMethodNameBytes(t Type) *byte {
_ = pinUnexpMethI
ut := t.uncommon()
if ut == nil {
panic("type has no methods")
}
m := ut.Methods()[0]
mname := t.(*rtype).nameOff(m.Name)
if *mname.DataChecked(0, "name flag field")&(1<<2) == 0 {
panic("method name does not have pkgPath *string")
}
return mname.Bytes
}
type OtherPkgFields struct {
OtherExported int
otherUnexported int
}
func IsExported(t Type) bool {
typ := t.(*rtype)
n := typ.nameOff(typ.t.Str)
return n.IsExported()
}
func ResolveReflectName(s string) {
resolveReflectName(newName(s, "", false, false))
}
type Buffer struct {
buf []byte
}
func clearLayoutCache() {
layoutCache = sync.Map{}
}
func SetArgRegs(ints, floats int, floatSize uintptr) (oldInts, oldFloats int, oldFloatSize uintptr) {
oldInts = intArgRegs
oldFloats = floatArgRegs
oldFloatSize = floatRegSize
intArgRegs = ints
floatArgRegs = floats
floatRegSize = floatSize
clearLayoutCache()
return
}
var MethodValueCallCodePtr = methodValueCallCodePtr
var InternalIsZero = isZero
var IsRegularMemory = isRegularMemory
func MapGroupOf(x, y Type) Type {
grp, _ := groupAndSlotOf(x, y)
return grp
}
|