aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2023-04-24 15:45:33 -0400
committerDavid Chase <drchase@google.com>2023-05-11 04:50:30 +0000
commita2838ec5f20b56e94a18c873ab4b68397355e214 (patch)
treee461b73e88af94584189441c48a436a2b0980339
parent48f8c5c0373886736d348acb1ce1601457da1d2e (diff)
downloadgo-a2838ec5f20b56e94a18c873ab4b68397355e214.tar.xz
runtime: redefine _type to abi.Type; add rtype for methods.
Change-Id: I1c478b704d84811caa209006c657dda82d9c4cf9 Reviewed-on: https://go-review.googlesource.com/c/go/+/488435 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
-rw-r--r--src/cmd/link/internal/ld/dwarf.go2
-rw-r--r--src/cmd/link/internal/ld/dwarf_test.go2
-rw-r--r--src/reflect/type.go3
-rw-r--r--src/runtime/alg.go12
-rw-r--r--src/runtime/cgocall.go4
-rw-r--r--src/runtime/cgocheck.go2
-rw-r--r--src/runtime/chan.go4
-rw-r--r--src/runtime/error.go10
-rw-r--r--src/runtime/heapdump.go9
-rw-r--r--src/runtime/iface.go17
-rw-r--r--src/runtime/mbarrier.go2
-rw-r--r--src/runtime/mbitmap.go4
-rw-r--r--src/runtime/mfinal.go12
-rw-r--r--src/runtime/mprof.go2
-rw-r--r--src/runtime/panic.go2
-rw-r--r--src/runtime/plugin.go2
-rw-r--r--src/runtime/runtime1.go6
-rw-r--r--src/runtime/syscall_windows.go2
-rw-r--r--src/runtime/type.go54
19 files changed, 76 insertions, 75 deletions
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index b9383e28b9..238262cffe 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -1802,7 +1802,7 @@ func dwarfGenerateDebugInfo(ctxt *Link) {
// Needed by the prettyprinter code for interface inspection.
for _, typ := range []string{
- "type:runtime._type",
+ "type:internal/abi.Type",
"type:internal/abi.ArrayType",
"type:internal/abi.ChanType",
"type:runtime.functype",
diff --git a/src/cmd/link/internal/ld/dwarf_test.go b/src/cmd/link/internal/ld/dwarf_test.go
index c8715922d8..15682dff3d 100644
--- a/src/cmd/link/internal/ld/dwarf_test.go
+++ b/src/cmd/link/internal/ld/dwarf_test.go
@@ -56,7 +56,7 @@ func TestRuntimeTypesPresent(t *testing.T) {
}
want := map[string]bool{
- "runtime._type": true,
+ "internal/abi.Type": true,
"internal/abi.ArrayType": true,
"internal/abi.ChanType": true,
"runtime.functype": true,
diff --git a/src/reflect/type.go b/src/reflect/type.go
index d2fde0b3ae..b817e811aa 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -279,8 +279,7 @@ const Ptr = Pointer
// to describe a non-defined type with no methods.
type uncommonType = abi.UncommonType
-// rtype is the common implementation of most values.
-// It is embedded in other struct types.
+// rtype is a wrapper that allows us to define exactly the type.Reflect methods.
type rtype struct {
t *abi.Type
}
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index e40eb9b47b..4eda9d4e75 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -106,7 +106,7 @@ func interhash(p unsafe.Pointer, h uintptr) uintptr {
// typehash, but we want to report the topmost type in
// the error text (e.g. in a struct with a field of slice type
// we want to report the struct, not the slice).
- panic(errorString("hash of unhashable type " + t.string()))
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if isDirectIface(t) {
return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
@@ -123,7 +123,7 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
}
if t.Equal == nil {
// See comment in interhash above.
- panic(errorString("hash of unhashable type " + t.string()))
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if isDirectIface(t) {
return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
@@ -174,7 +174,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
case kindArray:
a := (*arraytype)(unsafe.Pointer(t))
for i := uintptr(0); i < a.Len; i++ {
- h = typehash(toType(a.Elem), add(p, i*a.Elem.Size_), h)
+ h = typehash(a.Elem, add(p, i*a.Elem.Size_), h)
}
return h
case kindStruct:
@@ -189,7 +189,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
default:
// Should never happen, as typehash should only be called
// with comparable types.
- panic(errorString("hash of unhashable type " + t.string()))
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
}
}
@@ -247,7 +247,7 @@ func efaceeq(t *_type, x, y unsafe.Pointer) bool {
}
eq := t.Equal
if eq == nil {
- panic(errorString("comparing uncomparable type " + t.string()))
+ panic(errorString("comparing uncomparable type " + toRType(t).string()))
}
if isDirectIface(t) {
// Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof.
@@ -264,7 +264,7 @@ func ifaceeq(tab *itab, x, y unsafe.Pointer) bool {
t := tab._type
eq := t.Equal
if eq == nil {
- panic(errorString("comparing uncomparable type " + t.string()))
+ panic(errorString("comparing uncomparable type " + toRType(t).string()))
}
if isDirectIface(t) {
// See comment in efaceeq.
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index e2e37284a2..04ab9faa3d 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -466,11 +466,11 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if at.Len != 1 {
throw("can't happen")
}
- cgoCheckArg(toType(at.Elem), p, at.Elem.Kind_&kindDirectIface == 0, top, msg)
+ cgoCheckArg(at.Elem, p, at.Elem.Kind_&kindDirectIface == 0, top, msg)
return
}
for i := uintptr(0); i < at.Len; i++ {
- cgoCheckArg(toType(at.Elem), p, true, top, msg)
+ cgoCheckArg(at.Elem, p, true, top, msg)
p = add(p, at.Elem.Size_)
}
case kindChan, kindMap:
diff --git a/src/runtime/cgocheck.go b/src/runtime/cgocheck.go
index 1acf0f9233..2cfbdeebb5 100644
--- a/src/runtime/cgocheck.go
+++ b/src/runtime/cgocheck.go
@@ -249,7 +249,7 @@ func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
at := (*arraytype)(unsafe.Pointer(typ))
for i := uintptr(0); i < at.Len; i++ {
if off < at.Elem.Size_ {
- cgoCheckUsingType(toType(at.Elem), src, off, size)
+ cgoCheckUsingType(at.Elem, src, off, size)
}
src = add(src, at.Elem.Size_)
skipped := off
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
index 0a8578d435..98e0836670 100644
--- a/src/runtime/chan.go
+++ b/src/runtime/chan.go
@@ -104,11 +104,11 @@ func makechan(t *chantype, size int) *hchan {
default:
// Elements contain pointers.
c = new(hchan)
- c.buf = mallocgc(mem, toType(elem), true)
+ c.buf = mallocgc(mem, elem, true)
}
c.elemsize = uint16(elem.Size_)
- c.elemtype = toType(elem)
+ c.elemtype = elem
c.dataqsiz = uint(size)
lockInit(&c.lock, lockRankHchan)
diff --git a/src/runtime/error.go b/src/runtime/error.go
index 9bad50d90b..3590ccd965 100644
--- a/src/runtime/error.go
+++ b/src/runtime/error.go
@@ -30,18 +30,18 @@ func (*TypeAssertionError) RuntimeError() {}
func (e *TypeAssertionError) Error() string {
inter := "interface"
if e._interface != nil {
- inter = e._interface.string()
+ inter = toRType(e._interface).string()
}
- as := e.asserted.string()
+ as := toRType(e.asserted).string()
if e.concrete == nil {
return "interface conversion: " + inter + " is nil, not " + as
}
- cs := e.concrete.string()
+ cs := toRType(e.concrete).string()
if e.missingMethod == "" {
msg := "interface conversion: " + inter + " is " + cs + ", not " + as
if cs == as {
// provide slightly clearer error message
- if e.concrete.pkgpath() != e.asserted.pkgpath() {
+ if toRType(e.concrete).pkgpath() != toRType(e.asserted).pkgpath() {
msg += " (types from different packages)"
} else {
msg += " (types from different scopes)"
@@ -256,7 +256,7 @@ func printany(i any) {
func printanycustomtype(i any) {
eface := efaceOf(&i)
- typestring := eface._type.string()
+ typestring := toRType(eface._type).string()
switch eface._type.Kind_ {
case kindString:
diff --git a/src/runtime/heapdump.go b/src/runtime/heapdump.go
index d06ddfc0fe..6a042ea9cf 100644
--- a/src/runtime/heapdump.go
+++ b/src/runtime/heapdump.go
@@ -194,11 +194,12 @@ func dumptype(t *_type) {
dumpint(tagType)
dumpint(uint64(uintptr(unsafe.Pointer(t))))
dumpint(uint64(t.Size_))
- if x := t.uncommon(); x == nil || t.nameOff(x.PkgPath).name() == "" {
- dumpstr(t.string())
+ rt := toRType(t)
+ if x := t.Uncommon(); x == nil || rt.nameOff(x.PkgPath).name() == "" {
+ dumpstr(rt.string())
} else {
- pkgpath := t.nameOff(x.PkgPath).name()
- name := t.name()
+ pkgpath := rt.nameOff(x.PkgPath).name()
+ name := rt.name()
dumpint(uint64(uintptr(len(pkgpath)) + 1 + uintptr(len(name))))
dwrite(unsafe.Pointer(unsafe.StringData(pkgpath)), uintptr(len(pkgpath)))
dwritebyte('.')
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
index 67e98b08ce..34d223f7f1 100644
--- a/src/runtime/iface.go
+++ b/src/runtime/iface.go
@@ -41,7 +41,7 @@ func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
if canfail {
return nil
}
- name := inter.typ.nameOff(inter.mhdr[0].Name)
+ name := toRType(&inter.typ).nameOff(inter.mhdr[0].Name)
panic(&TypeAssertionError{nil, typ, &inter.typ, name.name()})
}
@@ -192,7 +192,7 @@ func (t *itabTableType) add(m *itab) {
func (m *itab) init() string {
inter := m.inter
typ := m._type
- x := typ.uncommon()
+ x := typ.Uncommon()
// both inter and typ have method sorted by name,
// and interface names are unique,
@@ -207,8 +207,8 @@ func (m *itab) init() string {
imethods:
for k := 0; k < ni; k++ {
i := &inter.mhdr[k]
- itype := inter.typ.typeOff(i.Typ)
- name := inter.typ.nameOff(i.Name)
+ itype := toRType(&inter.typ).typeOff(i.Typ)
+ name := toRType(&inter.typ).nameOff(i.Name)
iname := name.name()
ipkg := name.pkgPath()
if ipkg == "" {
@@ -216,15 +216,16 @@ imethods:
}
for ; j < nt; j++ {
t := &xmhdr[j]
- tname := typ.nameOff(t.Name)
- if typ.typeOff(t.Mtyp) == itype && tname.name() == iname {
+ rtyp := toRType(typ)
+ tname := rtyp.nameOff(t.Name)
+ if rtyp.typeOff(t.Mtyp) == itype && tname.name() == iname {
pkgPath := tname.pkgPath()
if pkgPath == "" {
- pkgPath = typ.nameOff(x.PkgPath).name()
+ pkgPath = rtyp.nameOff(x.PkgPath).name()
}
if tname.isExported() || pkgPath == ipkg {
if m != nil {
- ifn := typ.textOff(t.Ifn)
+ ifn := rtyp.textOff(t.Ifn)
if k == 0 {
fun0 = ifn // we'll set m.fun[0] at the end
} else {
diff --git a/src/runtime/mbarrier.go b/src/runtime/mbarrier.go
index ed6df2d55e..4bcc170ef9 100644
--- a/src/runtime/mbarrier.go
+++ b/src/runtime/mbarrier.go
@@ -155,7 +155,7 @@ import (
// anywhere in the bulk barrier or memmove.
//
//go:nosplit
-func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
+func typedmemmove(typ *abi.Type, dst, src unsafe.Pointer) {
if dst == src {
return
}
diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go
index f8ce5fd006..76f9a4eb9f 100644
--- a/src/runtime/mbitmap.go
+++ b/src/runtime/mbitmap.go
@@ -683,11 +683,11 @@ func typeBitsBulkBarrier(typ *_type, dst, src, size uintptr) {
throw("runtime: typeBitsBulkBarrier without type")
}
if typ.Size_ != size {
- println("runtime: typeBitsBulkBarrier with type ", typ.string(), " of size ", typ.Size_, " but memory size", size)
+ println("runtime: typeBitsBulkBarrier with type ", toRType(typ).string(), " of size ", typ.Size_, " but memory size", size)
throw("runtime: invalid typeBitsBulkBarrier")
}
if typ.Kind_&kindGCProg != 0 {
- println("runtime: typeBitsBulkBarrier with type ", typ.string(), " with GC prog")
+ println("runtime: typeBitsBulkBarrier with type ", toRType(typ).string(), " with GC prog")
throw("runtime: invalid typeBitsBulkBarrier")
}
if !writeBarrier.needed {
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index e25c06bcf8..d302d7fd97 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -372,7 +372,7 @@ func SetFinalizer(obj any, finalizer any) {
throw("runtime.SetFinalizer: first argument is nil")
}
if etyp.Kind_&kindMask != kindPtr {
- throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer")
+ throw("runtime.SetFinalizer: first argument is " + toRType(etyp).string() + ", not pointer")
}
ot := (*ptrtype)(unsafe.Pointer(etyp))
if ot.elem == nil {
@@ -431,14 +431,14 @@ func SetFinalizer(obj any, finalizer any) {
}
if ftyp.Kind_&kindMask != kindFunc {
- throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function")
+ throw("runtime.SetFinalizer: second argument is " + toRType(ftyp).string() + ", not a function")
}
ft := (*functype)(unsafe.Pointer(ftyp))
if ft.dotdotdot() {
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot")
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string() + " because dotdotdot")
}
if ft.inCount != 1 {
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string())
}
fint := ft.in()[0]
switch {
@@ -446,7 +446,7 @@ func SetFinalizer(obj any, finalizer any) {
// ok - same type
goto okarg
case fint.Kind_&kindMask == kindPtr:
- if (fint.uncommon() == nil || etyp.uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
+ if (fint.Uncommon() == nil || etyp.Uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
// ok - not same type, but both pointers,
// one or the other is unnamed, and same element type, so assignable.
goto okarg
@@ -461,7 +461,7 @@ func SetFinalizer(obj any, finalizer any) {
goto okarg
}
}
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string())
okarg:
// compute size needed for return parameters
nret := uintptr(0)
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go
index dfaa369740..174ceb0a1f 100644
--- a/src/runtime/mprof.go
+++ b/src/runtime/mprof.go
@@ -1230,7 +1230,7 @@ func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
if typ == nil {
print("tracealloc(", p, ", ", hex(size), ")\n")
} else {
- print("tracealloc(", p, ", ", hex(size), ", ", typ.string(), ")\n")
+ print("tracealloc(", p, ", ", hex(size), ", ", toRType(typ).string(), ")\n")
}
if gp.m.curg == nil || gp == gp.m.curg {
goroutineheader(gp)
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
index cefab56902..751ad998c9 100644
--- a/src/runtime/panic.go
+++ b/src/runtime/panic.go
@@ -573,7 +573,7 @@ func preprintpanics(p *_panic) {
case string:
throw(text + ": " + r)
default:
- throw(text + ": type " + efaceOf(&r)._type.string())
+ throw(text + ": type " + toRType(efaceOf(&r)._type).string())
}
}()
for p != nil {
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index d2ad1ed21c..690f85750b 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -79,7 +79,7 @@ func plugin_lastmoduleinit() (path string, syms map[string]any, initTasks []*ini
syms = make(map[string]any, len(md.ptab))
for _, ptab := range md.ptab {
symName := resolveNameOff(unsafe.Pointer(md.types), ptab.name)
- t := (*_type)(unsafe.Pointer(md.types)).typeOff(ptab.typ)
+ t := toRType((*_type)(unsafe.Pointer(md.types))).typeOff(ptab.typ) // TODO can this stack of conversions be simpler?
var val any
valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&val))
(*valp)[0] = unsafe.Pointer(t)
diff --git a/src/runtime/runtime1.go b/src/runtime/runtime1.go
index 65bed433c3..0fa34ba088 100644
--- a/src/runtime/runtime1.go
+++ b/src/runtime/runtime1.go
@@ -608,14 +608,14 @@ func reflect_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointe
//
//go:linkname reflect_resolveTypeOff reflect.resolveTypeOff
func reflect_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer((*_type)(rtype).typeOff(typeOff(off)))
+ return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
}
// reflect_resolveTextOff resolves a function pointer offset from a base type.
//
//go:linkname reflect_resolveTextOff reflect.resolveTextOff
func reflect_resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return (*_type)(rtype).textOff(textOff(off))
+ return toRType((*_type)(rtype)).textOff(textOff(off))
}
@@ -630,7 +630,7 @@ func reflectlite_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Po
//
//go:linkname reflectlite_resolveTypeOff internal/reflectlite.resolveTypeOff
func reflectlite_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer((*_type)(rtype).typeOff(typeOff(off)))
+ return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
}
// reflect_addReflectOff adds a pointer to the reflection offset lookup map.
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index 37f86d0d7f..352a007e32 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -200,7 +200,7 @@ func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
}
// Pointer-sized types such as maps and channels are currently
// not supported.
- panic("compileCallabck: type " + t.string() + " is currently not supported for use in system callbacks")
+ panic("compileCallback: type " + toRType(t).string() + " is currently not supported for use in system callbacks")
}
// assignReg attempts to assign a single register for an
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 3e86888ff6..8737284ddb 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -15,15 +15,14 @@ type nameOff = abi.NameOff
type typeOff = abi.TypeOff
type textOff = abi.TextOff
-// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
-// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
-// ../reflect/type.go:/^type.rtype.
-// ../internal/reflectlite/type.go:/^type.rtype.
-type _type struct {
- abi.Type
+type _type = abi.Type
+
+// rtype is a wrapper that allows us to define additional methods.
+type rtype struct {
+ *abi.Type // embedding is okay here (unlike reflect) because none of this is public
}
-func (t *_type) string() string {
+func (t rtype) string() string {
s := t.nameOff(t.Str).name()
if t.TFlag&abi.TFlagExtraStar != 0 {
return s[1:]
@@ -31,11 +30,11 @@ func (t *_type) string() string {
return s
}
-func (t *_type) uncommon() *uncommontype {
+func (t rtype) uncommon() *uncommontype {
return t.Uncommon()
}
-func (t *_type) name() string {
+func (t rtype) name() string {
if t.TFlag&abi.TFlagNamed == 0 {
return ""
}
@@ -58,16 +57,16 @@ func (t *_type) name() string {
// available. This is not the same as the reflect package's PkgPath
// method, in that it returns the package path for struct and interface
// types, not just named types.
-func (t *_type) pkgpath() string {
+func (t rtype) pkgpath() string {
if u := t.uncommon(); u != nil {
return t.nameOff(u.PkgPath).name()
}
switch t.Kind_ & kindMask {
case kindStruct:
- st := (*structtype)(unsafe.Pointer(t))
+ st := (*structtype)(unsafe.Pointer(t.Type))
return st.pkgPath.name()
case kindInterface:
- it := (*interfacetype)(unsafe.Pointer(t))
+ it := (*interfacetype)(unsafe.Pointer(t.Type))
return it.pkgpath.name()
}
return ""
@@ -137,8 +136,8 @@ func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
return name{(*byte)(res)}
}
-func (t *_type) nameOff(off nameOff) name {
- return resolveNameOff(unsafe.Pointer(t), off)
+func (t rtype) nameOff(off nameOff) name {
+ return resolveNameOff(unsafe.Pointer(t.Type), off)
}
func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type {
@@ -179,17 +178,17 @@ func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type {
return (*_type)(unsafe.Pointer(res))
}
-func (t *_type) typeOff(off typeOff) *_type {
- return resolveTypeOff(unsafe.Pointer(t), off)
+func (t rtype) typeOff(off typeOff) *_type {
+ return resolveTypeOff(unsafe.Pointer(t.Type), off)
}
-func (t *_type) textOff(off textOff) unsafe.Pointer {
+func (t rtype) textOff(off textOff) unsafe.Pointer {
if off == -1 {
// -1 is the sentinel value for unreachable code.
// See cmd/link/internal/ld/data.go:relocsym.
return unsafe.Pointer(abi.FuncPCABIInternal(unreachableMethod))
}
- base := uintptr(unsafe.Pointer(t))
+ base := uintptr(unsafe.Pointer(t.Type))
var md *moduledata
for next := &firstmoduledata; next != nil; next = next.next {
if base >= next.types && base < next.etypes {
@@ -440,8 +439,8 @@ type _typePair struct {
t2 *_type
}
-func toType(t *abi.Type) *_type {
- return (*_type)(unsafe.Pointer(t))
+func toRType(t *abi.Type) rtype {
+ return rtype{t}
}
// typesEqual reports whether two types are equal.
@@ -474,17 +473,18 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
if kind != v.Kind_&kindMask {
return false
}
- if t.string() != v.string() {
+ rt, rv := toRType(t), toRType(v)
+ if rt.string() != rv.string() {
return false
}
- ut := t.uncommon()
- uv := v.uncommon()
+ ut := t.Uncommon()
+ uv := v.Uncommon()
if ut != nil || uv != nil {
if ut == nil || uv == nil {
return false
}
- pkgpatht := t.nameOff(ut.PkgPath).name()
- pkgpathv := v.nameOff(uv.PkgPath).name()
+ pkgpatht := rt.nameOff(ut.PkgPath).name()
+ pkgpathv := rv.nameOff(uv.PkgPath).name()
if pkgpatht != pkgpathv {
return false
}
@@ -498,11 +498,11 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
case kindArray:
at := (*arraytype)(unsafe.Pointer(t))
av := (*arraytype)(unsafe.Pointer(v))
- return typesEqual(toType(at.Elem), toType(av.Elem), seen) && at.Len == av.Len
+ return typesEqual(at.Elem, av.Elem, seen) && at.Len == av.Len
case kindChan:
ct := (*chantype)(unsafe.Pointer(t))
cv := (*chantype)(unsafe.Pointer(v))
- return ct.Dir == cv.Dir && typesEqual(toType(ct.Elem), toType(cv.Elem), seen)
+ return ct.Dir == cv.Dir && typesEqual(ct.Elem, cv.Elem, seen)
case kindFunc:
ft := (*functype)(unsafe.Pointer(t))
fv := (*functype)(unsafe.Pointer(v))