diff options
author | Keith Randall <khr@golang.org> | 2021-05-09 11:06:17 -0700 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2021-05-10 13:16:56 +0000 |
commit | 287025925f66f90ad9b30aea2e533928026a8376 (patch) | |
tree | d1d08af3e2dbb39ee461a3d9bc821b406e6a384b /src/runtime | |
parent | c14ecaca8182314efd2ef7280feffc2242644887 (diff) | |
download | go-287025925f66f90ad9b30aea2e533928026a8376.tar.gz go-287025925f66f90ad9b30aea2e533928026a8376.zip |
cmd/compile,reflect: allow longer type names
Encode the length of type names and tags in a varint encoding
instead of a fixed 2-byte encoding. This allows lengths longer
than 65535 (which can happen for large unnamed structs).
Removed the alignment check for #14962, it isn't relevant any more
since we're no longer reading pointers directly out of this data
(it is encoded as an offset which is copied out bytewise).
Fixes #44155
Update #14962
Change-Id: I6084f6027e5955dc16777c87b0dd5ea2baa49629
Reviewed-on: https://go-review.googlesource.com/c/go/+/318249
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime')
-rw-r--r-- | src/runtime/type.go | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/src/runtime/type.go b/src/runtime/type.go index c0911b1dcb..335fc57f4b 100644 --- a/src/runtime/type.go +++ b/src/runtime/type.go @@ -459,51 +459,52 @@ func (n name) isExported() bool { return (*n.bytes)&(1<<0) != 0 } -func (n name) nameLen() int { - return int(uint16(*n.data(1))<<8 | uint16(*n.data(2))) -} - -func (n name) tagLen() int { - if *n.data(0)&(1<<1) == 0 { - return 0 +func (n name) readvarint(off int) (int, int) { + v := 0 + for i := 0; ; i++ { + x := *n.data(off + i) + v += int(x&0x7f) << (7 * i) + if x&0x80 == 0 { + return i + 1, v + } } - off := 3 + n.nameLen() - return int(uint16(*n.data(off))<<8 | uint16(*n.data(off + 1))) } func (n name) name() (s string) { if n.bytes == nil { return "" } - nl := n.nameLen() - if nl == 0 { + i, l := n.readvarint(1) + if l == 0 { return "" } hdr := (*stringStruct)(unsafe.Pointer(&s)) - hdr.str = unsafe.Pointer(n.data(3)) - hdr.len = nl - return s + hdr.str = unsafe.Pointer(n.data(1 + i)) + hdr.len = l + return } func (n name) tag() (s string) { - tl := n.tagLen() - if tl == 0 { + if *n.data(0)&(1<<1) == 0 { return "" } - nl := n.nameLen() + i, l := n.readvarint(1) + i2, l2 := n.readvarint(1 + i + l) hdr := (*stringStruct)(unsafe.Pointer(&s)) - hdr.str = unsafe.Pointer(n.data(3 + nl + 2)) - hdr.len = tl - return s + hdr.str = unsafe.Pointer(n.data(1 + i + l + i2)) + hdr.len = l2 + return } func (n name) pkgPath() string { if n.bytes == nil || *n.data(0)&(1<<2) == 0 { return "" } - off := 3 + n.nameLen() - if tl := n.tagLen(); tl > 0 { - off += 2 + tl + i, l := n.readvarint(1) + off := 1 + i + l + if *n.data(0)&(1<<1) != 0 { + i2, l2 := n.readvarint(off) + off += i2 + l2 } var nameOff nameOff copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off)))[:]) @@ -515,10 +516,8 @@ func (n name) isBlank() bool { if n.bytes == nil { return false } - if n.nameLen() != 1 { - return false - } - return *n.data(3) == '_' + _, l := n.readvarint(1) + return l == 1 && *n.data(2) == '_' } // typelinksinit scans the types from extra modules and builds the |