aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/reflectdata/reflect.go33
-rw-r--r--src/cmd/link/internal/ld/decodesym.go17
-rw-r--r--src/cmd/link/internal/ld/dwarf.go6
-rw-r--r--src/internal/reflectlite/export_test.go2
-rw-r--r--src/internal/reflectlite/type.go21
-rw-r--r--src/reflect/abi.go2
-rw-r--r--src/reflect/export_test.go2
-rw-r--r--src/reflect/type.go76
-rw-r--r--src/reflect/value.go2
-rw-r--r--src/runtime/alg.go2
-rw-r--r--src/runtime/cgocall.go2
-rw-r--r--src/runtime/syscall_windows.go2
-rw-r--r--src/runtime/type.go19
13 files changed, 104 insertions, 82 deletions
diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go
index 3ffb7dcefa..21301ab149 100644
--- a/src/cmd/compile/internal/reflectdata/reflect.go
+++ b/src/cmd/compile/internal/reflectdata/reflect.go
@@ -412,7 +412,7 @@ func dimportpath(p *types.Pkg) {
}
s := base.Ctxt.Lookup("type..importpath." + p.Prefix + ".")
- ot := dnameData(s, 0, p.Path, "", nil, false)
+ ot := dnameData(s, 0, p.Path, "", nil, false, false)
objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
s.Set(obj.AttrContentAddressable, true)
p.Pathsym = s
@@ -461,12 +461,12 @@ func dnameField(lsym *obj.LSym, ot int, spkg *types.Pkg, ft *types.Field) int {
if !types.IsExported(ft.Sym.Name) && ft.Sym.Pkg != spkg {
base.Fatalf("package mismatch for %v", ft.Sym)
}
- nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name))
+ nsym := dname(ft.Sym.Name, ft.Note, nil, types.IsExported(ft.Sym.Name), ft.Embedded != 0)
return objw.SymPtr(lsym, ot, nsym, 0)
}
// dnameData writes the contents of a reflect.name into s at offset ot.
-func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported bool) int {
+func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported, embedded bool) int {
if len(name) >= 1<<29 {
base.Fatalf("name too long: %d %s...", len(name), name[:1024])
}
@@ -491,6 +491,9 @@ func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported b
if pkg != nil {
bits |= 1 << 2
}
+ if embedded {
+ bits |= 1 << 3
+ }
b := make([]byte, l)
b[0] = bits
copy(b[1:], nameLen[:nameLenLen])
@@ -513,7 +516,7 @@ func dnameData(s *obj.LSym, ot int, name, tag string, pkg *types.Pkg, exported b
var dnameCount int
// dname creates a reflect.name for a struct field or method.
-func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
+func dname(name, tag string, pkg *types.Pkg, exported, embedded bool) *obj.LSym {
// Write out data as "type.." to signal two things to the
// linker, first that when dynamically linking, the symbol
// should be moved to a relro section, and second that the
@@ -538,11 +541,14 @@ func dname(name, tag string, pkg *types.Pkg, exported bool) *obj.LSym {
sname = fmt.Sprintf(`%s"".%d`, sname, dnameCount)
dnameCount++
}
+ if embedded {
+ sname += ".embedded"
+ }
s := base.Ctxt.Lookup(sname)
if len(s.P) > 0 {
return s
}
- ot := dnameData(s, 0, name, tag, pkg, exported)
+ ot := dnameData(s, 0, name, tag, pkg, exported, embedded)
objw.Global(s, int32(ot), obj.DUPOK|obj.RODATA)
s.Set(obj.AttrContentAddressable, true)
return s
@@ -610,7 +616,7 @@ func dextratypeData(lsym *obj.LSym, ot int, t *types.Type) int {
if !exported && a.name.Pkg != typePkg(t) {
pkg = a.name.Pkg
}
- nsym := dname(a.name.Name, "", pkg, exported)
+ nsym := dname(a.name.Name, "", pkg, exported, false)
ot = objw.SymPtrOff(lsym, ot, nsym)
ot = dmethodptrOff(lsym, ot, writeType(a.mtype))
@@ -775,7 +781,7 @@ func dcommontype(lsym *obj.LSym, t *types.Type) int {
}
ot = objw.SymPtr(lsym, ot, gcsym, 0) // gcdata
- nsym := dname(p, "", nil, exported)
+ nsym := dname(p, "", nil, exported, false)
ot = objw.SymPtrOff(lsym, ot, nsym) // str
// ptrToThis
if sptr == nil {
@@ -1074,7 +1080,7 @@ func writeType(t *types.Type) *obj.LSym {
if !exported && a.name.Pkg != tpkg {
pkg = a.name.Pkg
}
- nsym := dname(a.name.Name, "", pkg, exported)
+ nsym := dname(a.name.Name, "", pkg, exported, false)
ot = objw.SymPtrOff(lsym, ot, nsym)
ot = objw.SymPtrOff(lsym, ot, writeType(a.type_))
@@ -1180,14 +1186,7 @@ func writeType(t *types.Type) *obj.LSym {
// ../../../../runtime/type.go:/structField
ot = dnameField(lsym, ot, spkg, f)
ot = objw.SymPtr(lsym, ot, writeType(f.Type), 0)
- offsetAnon := uint64(f.Offset) << 1
- if offsetAnon>>1 != uint64(f.Offset) {
- base.Fatalf("%v: bad field offset for %s", t, f.Sym.Name)
- }
- if f.Embedded != 0 {
- offsetAnon |= 1
- }
- ot = objw.Uintptr(lsym, ot, offsetAnon)
+ ot = objw.Uintptr(lsym, ot, uint64(f.Offset))
}
}
@@ -1356,7 +1355,7 @@ func WriteTabs() {
// name nameOff
// typ typeOff // pointer to symbol
// }
- nsym := dname(p.Sym().Name, "", nil, true)
+ nsym := dname(p.Sym().Name, "", nil, true, false)
t := p.Type()
if p.Class != ir.PFUNC {
t = types.NewPtr(t)
diff --git a/src/cmd/link/internal/ld/decodesym.go b/src/cmd/link/internal/ld/decodesym.go
index a6ae202859..b0f4b87563 100644
--- a/src/cmd/link/internal/ld/decodesym.go
+++ b/src/cmd/link/internal/ld/decodesym.go
@@ -132,6 +132,15 @@ func decodetypeName(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs
return string(data[1+nameLenLen : 1+nameLenLen+int(nameLen)])
}
+func decodetypeNameEmbedded(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) bool {
+ r := decodeRelocSym(ldr, symIdx, relocs, int32(off))
+ if r == 0 {
+ return false
+ }
+ data := ldr.Data(r)
+ return data[0]&(1<<3) != 0
+}
+
func decodetypeFuncInType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
uadd := commonsize(arch) + 4
if arch.PtrSize == 8 {
@@ -204,12 +213,18 @@ func decodetypeStructFieldType(ldr *loader.Loader, arch *sys.Arch, symIdx loader
return decodeRelocSym(ldr, symIdx, &relocs, int32(off+arch.PtrSize))
}
-func decodetypeStructFieldOffsAnon(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int64 {
+func decodetypeStructFieldOffset(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int64 {
off := decodetypeStructFieldArrayOff(ldr, arch, symIdx, i)
data := ldr.Data(symIdx)
return int64(decodeInuxi(arch, data[off+2*arch.PtrSize:], arch.PtrSize))
}
+func decodetypeStructFieldEmbedded(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) bool {
+ off := decodetypeStructFieldArrayOff(ldr, arch, symIdx, i)
+ relocs := ldr.Relocs(symIdx)
+ return decodetypeNameEmbedded(ldr, symIdx, &relocs, off)
+}
+
// decodetypeStr returns the contents of an rtype's str field (a nameOff).
func decodetypeStr(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) string {
relocs := ldr.Relocs(symIdx)
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 6ed9697aec..c42511ea3f 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -682,9 +682,9 @@ func (d *dwctxt) newtype(gotype loader.Sym) *dwarf.DWDie {
}
fld := d.newdie(die, dwarf.DW_ABRV_STRUCTFIELD, f)
d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
- offsetAnon := decodetypeStructFieldOffsAnon(d.ldr, d.arch, gotype, i)
- newmemberoffsetattr(fld, int32(offsetAnon>>1))
- if offsetAnon&1 != 0 { // is embedded field
+ offset := decodetypeStructFieldOffset(d.ldr, d.arch, gotype, i)
+ newmemberoffsetattr(fld, int32(offset))
+ if decodetypeStructFieldEmbedded(d.ldr, d.arch, gotype, i) {
newattr(fld, dwarf.DW_AT_go_embedded_field, dwarf.DW_CLS_FLAG, 1, 0)
}
}
diff --git a/src/internal/reflectlite/export_test.go b/src/internal/reflectlite/export_test.go
index 3e5c258fb1..e9a928bdc6 100644
--- a/src/internal/reflectlite/export_test.go
+++ b/src/internal/reflectlite/export_test.go
@@ -36,7 +36,7 @@ func Field(v Value, i int) Value {
// In the former case, we want v.ptr + offset.
// In the latter case, we must have field.offset = 0,
// so v.ptr + field.offset is still the correct address.
- ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
+ ptr := add(v.ptr, field.offset, "same as non-reflect &v.field")
return Value{typ, ptr, fl}
}
diff --git a/src/internal/reflectlite/type.go b/src/internal/reflectlite/type.go
index bc6fc94773..21e3c1278d 100644
--- a/src/internal/reflectlite/type.go
+++ b/src/internal/reflectlite/type.go
@@ -269,17 +269,13 @@ type sliceType struct {
// Struct field
type structField struct {
- name name // name is always non-empty
- typ *rtype // type of field
- offsetEmbed uintptr // byte offset of field<<1 | isEmbedded
-}
-
-func (f *structField) offset() uintptr {
- return f.offsetEmbed >> 1
+ name name // name is always non-empty
+ typ *rtype // type of field
+ offset uintptr // byte offset of field
}
func (f *structField) embedded() bool {
- return f.offsetEmbed&1 != 0
+ return f.name.embedded()
}
// structType represents a struct type.
@@ -328,6 +324,10 @@ func (n name) hasTag() bool {
return (*n.bytes)&(1<<1) != 0
}
+func (n name) embedded() bool {
+ return (*n.bytes)&(1<<3) != 0
+}
+
// readVarint parses a varint as encoded by encoding/binary.
// It returns the number of encoded bytes and the encoded value.
func (n name) readVarint(off int) (int, int) {
@@ -947,7 +947,10 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
if cmpTags && tf.name.tag() != vf.name.tag() {
return false
}
- if tf.offsetEmbed != vf.offsetEmbed {
+ if tf.offset != vf.offset {
+ return false
+ }
+ if tf.embedded() != vf.embedded() {
return false
}
}
diff --git a/src/reflect/abi.go b/src/reflect/abi.go
index 9957d23768..32cb314188 100644
--- a/src/reflect/abi.go
+++ b/src/reflect/abi.go
@@ -237,7 +237,7 @@ func (a *abiSeq) regAssign(t *rtype, offset uintptr) bool {
st := (*structType)(unsafe.Pointer(t))
for i := range st.fields {
f := &st.fields[i]
- if !a.regAssign(f.typ, offset+f.offset()) {
+ if !a.regAssign(f.typ, offset+f.offset) {
return false
}
}
diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go
index a5a3c1c271..f7d2cc362d 100644
--- a/src/reflect/export_test.go
+++ b/src/reflect/export_test.go
@@ -140,7 +140,7 @@ func IsExported(t Type) bool {
}
func ResolveReflectName(s string) {
- resolveReflectName(newName(s, "", false))
+ resolveReflectName(newName(s, "", false, false))
}
type Buffer struct {
diff --git a/src/reflect/type.go b/src/reflect/type.go
index 97040b5188..7b8cf0ee62 100644
--- a/src/reflect/type.go
+++ b/src/reflect/type.go
@@ -433,17 +433,13 @@ type sliceType struct {
// Struct field
type structField struct {
- name name // name is always non-empty
- typ *rtype // type of field
- offsetEmbed uintptr // byte offset of field<<1 | isEmbedded
-}
-
-func (f *structField) offset() uintptr {
- return f.offsetEmbed >> 1
+ name name // name is always non-empty
+ typ *rtype // type of field
+ offset uintptr // byte offset of field
}
func (f *structField) embedded() bool {
- return f.offsetEmbed&1 != 0
+ return f.name.embedded()
}
// structType represents a struct type.
@@ -460,6 +456,7 @@ type structType struct {
// 1<<0 the name is exported
// 1<<1 tag data follows the name
// 1<<2 pkgPath nameOff follows the name and tag
+// 1<<3 the name is of an embedded (a.k.a. anonymous) field
//
// Following that, there is a varint-encoded length of the name,
// followed by the name itself.
@@ -496,6 +493,10 @@ func (n name) hasTag() bool {
return (*n.bytes)&(1<<1) != 0
}
+func (n name) embedded() bool {
+ return (*n.bytes)&(1<<3) != 0
+}
+
// readVarint parses a varint as encoded by encoding/binary.
// It returns the number of encoded bytes and the encoded value.
func (n name) readVarint(off int) (int, int) {
@@ -565,7 +566,7 @@ func (n name) pkgPath() string {
return pkgPathName.name()
}
-func newName(n, tag string, exported bool) name {
+func newName(n, tag string, exported, embedded bool) name {
if len(n) >= 1<<29 {
panic("reflect.nameFrom: name too long: " + n[:1024] + "...")
}
@@ -586,6 +587,9 @@ func newName(n, tag string, exported bool) name {
l += tagLenLen + len(tag)
bits |= 1 << 1
}
+ if embedded {
+ bits |= 1 << 3
+ }
b := make([]byte, l)
b[0] = bits
@@ -1256,7 +1260,7 @@ func (t *structType) Field(i int) (f StructField) {
if tag := p.name.tag(); tag != "" {
f.Tag = StructTag(tag)
}
- f.Offset = p.offset()
+ f.Offset = p.offset
// NOTE(rsc): This is the only allocation in the interface
// presented by a reflect.Type. It would be nice to avoid,
@@ -1472,7 +1476,7 @@ func (t *rtype) ptrTo() *rtype {
prototype := *(**ptrType)(unsafe.Pointer(&iptr))
pp := *prototype
- pp.str = resolveReflectName(newName(s, "", false))
+ pp.str = resolveReflectName(newName(s, "", false, false))
pp.ptrToThis = 0
// For the type structures linked into the binary, the
@@ -1739,7 +1743,10 @@ func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
if cmpTags && tf.name.tag() != vf.name.tag() {
return false
}
- if tf.offsetEmbed != vf.offsetEmbed {
+ if tf.offset != vf.offset {
+ return false
+ }
+ if tf.embedded() != vf.embedded() {
return false
}
}
@@ -1891,7 +1898,7 @@ func ChanOf(dir ChanDir, t Type) Type {
ch := *prototype
ch.tflag = tflagRegularMemory
ch.dir = uintptr(dir)
- ch.str = resolveReflectName(newName(s, "", false))
+ ch.str = resolveReflectName(newName(s, "", false, false))
ch.hash = fnv1(typ.hash, 'c', byte(dir))
ch.elem = typ
@@ -1934,7 +1941,7 @@ func MapOf(key, elem Type) Type {
// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
mt := **(**mapType)(unsafe.Pointer(&imap))
- mt.str = resolveReflectName(newName(s, "", false))
+ mt.str = resolveReflectName(newName(s, "", false, false))
mt.tflag = 0
mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
mt.key = ktyp
@@ -2113,7 +2120,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
}
// Populate the remaining fields of ft and store in cache.
- ft.str = resolveReflectName(newName(str, "", false))
+ ft.str = resolveReflectName(newName(str, "", false, false))
ft.ptrToThis = 0
return addToCache(&ft.rtype)
}
@@ -2290,7 +2297,7 @@ func bucketOf(ktyp, etyp *rtype) *rtype {
gcdata: gcdata,
}
s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
- b.str = resolveReflectName(newName(s, "", false))
+ b.str = resolveReflectName(newName(s, "", false, false))
return b
}
@@ -2369,7 +2376,7 @@ func SliceOf(t Type) Type {
prototype := *(**sliceType)(unsafe.Pointer(&islice))
slice := *prototype
slice.tflag = 0
- slice.str = resolveReflectName(newName(s, "", false))
+ slice.str = resolveReflectName(newName(s, "", false, false))
slice.hash = fnv1(typ.hash, '[')
slice.elem = typ
slice.ptrToThis = 0
@@ -2632,7 +2639,7 @@ func StructOf(fields []StructField) Type {
typalign = ft.align
}
size = offset + ft.size
- f.offsetEmbed |= offset << 1
+ f.offset = offset
if ft.size == 0 {
lastzero = size
@@ -2698,7 +2705,7 @@ func StructOf(fields []StructField) Type {
*typ = *prototype
typ.fields = fs
if pkgpath != "" {
- typ.pkgPath = newName(pkgpath, "", false)
+ typ.pkgPath = newName(pkgpath, "", false, false)
}
// Look in cache.
@@ -2742,7 +2749,7 @@ func StructOf(fields []StructField) Type {
}
}
- typ.str = resolveReflectName(newName(str, "", false))
+ typ.str = resolveReflectName(newName(str, "", false, false))
typ.tflag = 0 // TODO: set tflagRegularMemory
typ.hash = hash
typ.size = size
@@ -2774,14 +2781,14 @@ func StructOf(fields []StructField) Type {
continue
}
// Pad to start of this field with zeros.
- if ft.offset() > off {
- n := (ft.offset() - off) / goarch.PtrSize
+ if ft.offset > off {
+ n := (ft.offset - off) / goarch.PtrSize
prog = append(prog, 0x01, 0x00) // emit a 0 bit
if n > 1 {
prog = append(prog, 0x81) // repeat previous bit
prog = appendVarint(prog, n-1) // n-1 times
}
- off = ft.offset()
+ off = ft.offset
}
prog = appendGCProg(prog, ft.typ)
@@ -2803,8 +2810,8 @@ func StructOf(fields []StructField) Type {
if comparable {
typ.equal = func(p, q unsafe.Pointer) bool {
for _, ft := range typ.fields {
- pi := add(p, ft.offset(), "&x.field safe")
- qi := add(q, ft.offset(), "&x.field safe")
+ pi := add(p, ft.offset, "&x.field safe")
+ qi := add(q, ft.offset, "&x.field safe")
if !ft.typ.equal(pi, qi) {
return false
}
@@ -2841,16 +2848,11 @@ func runtimeStructField(field StructField) (structField, string) {
}
}
- offsetEmbed := uintptr(0)
- if field.Anonymous {
- offsetEmbed |= 1
- }
-
resolveReflectType(field.Type.common()) // install in runtime
f := structField{
- name: newName(field.Name, string(field.Tag), field.IsExported()),
- typ: field.Type.common(),
- offsetEmbed: offsetEmbed,
+ name: newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous),
+ typ: field.Type.common(),
+ offset: 0,
}
return f, field.PkgPath
}
@@ -2874,7 +2876,7 @@ func typeptrdata(t *rtype) uintptr {
return 0
}
f := st.fields[field]
- return f.offset() + f.typ.ptrdata
+ return f.offset + f.typ.ptrdata
default:
panic("reflect.typeptrdata: unexpected type, " + t.String())
@@ -2917,7 +2919,7 @@ func ArrayOf(length int, elem Type) Type {
prototype := *(**arrayType)(unsafe.Pointer(&iarray))
array := *prototype
array.tflag = typ.tflag & tflagRegularMemory
- array.str = resolveReflectName(newName(s, "", false))
+ array.str = resolveReflectName(newName(s, "", false, false))
array.hash = fnv1(typ.hash, '[')
for n := uint32(length); n > 0; n >>= 8 {
array.hash = fnv1(array.hash, byte(n))
@@ -3097,7 +3099,7 @@ func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Poo
} else {
s = "funcargs(" + t.String() + ")"
}
- x.str = resolveReflectName(newName(s, "", false))
+ x.str = resolveReflectName(newName(s, "", false, false))
// cache result for future callers
framePool = &sync.Pool{New: func() any {
@@ -3165,7 +3167,7 @@ func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
tt := (*structType)(unsafe.Pointer(t))
for i := range tt.fields {
f := &tt.fields[i]
- addTypeBits(bv, offset+f.offset(), f.typ)
+ addTypeBits(bv, offset+f.offset, f.typ)
}
}
}
diff --git a/src/reflect/value.go b/src/reflect/value.go
index 5abdca2820..74554a3ac8 100644
--- a/src/reflect/value.go
+++ b/src/reflect/value.go
@@ -1287,7 +1287,7 @@ func (v Value) Field(i int) Value {
// In the former case, we want v.ptr + offset.
// In the latter case, we must have field.offset = 0,
// so v.ptr + field.offset is still the correct address.
- ptr := add(v.ptr, field.offset(), "same as non-reflect &v.field")
+ ptr := add(v.ptr, field.offset, "same as non-reflect &v.field")
return Value{typ, ptr, fl}
}
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index 5d7d1c77f4..2a413eeef3 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -182,7 +182,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
if f.name.isBlank() {
continue
}
- h = typehash(f.typ, add(p, f.offset()), h)
+ h = typehash(f.typ, add(p, f.offset), h)
}
return h
default:
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
index 977d049378..892654ed5b 100644
--- a/src/runtime/cgocall.go
+++ b/src/runtime/cgocall.go
@@ -536,7 +536,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if f.typ.ptrdata == 0 {
continue
}
- cgoCheckArg(f.typ, add(p, f.offset()), true, top, msg)
+ cgoCheckArg(f.typ, add(p, f.offset), true, top, msg)
}
case kindPtr, kindUnsafePointer:
if indir {
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index a841a31a27..e42d71ad65 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -174,7 +174,7 @@ func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
st := (*structtype)(unsafe.Pointer(t))
for i := range st.fields {
f := &st.fields[i]
- if !p.tryRegAssignArg(f.typ, offset+f.offset()) {
+ if !p.tryRegAssignArg(f.typ, offset+f.offset) {
return false
}
}
diff --git a/src/runtime/type.go b/src/runtime/type.go
index b650d6d795..e8e7819ecf 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -414,13 +414,9 @@ type ptrtype struct {
}
type structfield struct {
- name name
- typ *_type
- offsetAnon uintptr
-}
-
-func (f *structfield) offset() uintptr {
- return f.offsetAnon >> 1
+ name name
+ typ *_type
+ offset uintptr
}
type structtype struct {
@@ -443,6 +439,10 @@ func (n name) isExported() bool {
return (*n.bytes)&(1<<0) != 0
}
+func (n name) isEmbedded() bool {
+ return (*n.bytes)&(1<<3) != 0
+}
+
func (n name) readvarint(off int) (int, int) {
v := 0
for i := 0; ; i++ {
@@ -703,7 +703,10 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
if tf.name.tag() != vf.name.tag() {
return false
}
- if tf.offsetAnon != vf.offsetAnon {
+ if tf.offset != vf.offset {
+ return false
+ }
+ if tf.name.isEmbedded() != vf.name.isEmbedded() {
return false
}
}