aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2021-05-09 11:06:17 -0700
committerKeith Randall <khr@golang.org>2021-05-10 13:16:56 +0000
commit287025925f66f90ad9b30aea2e533928026a8376 (patch)
treed1d08af3e2dbb39ee461a3d9bc821b406e6a384b /src/runtime
parentc14ecaca8182314efd2ef7280feffc2242644887 (diff)
downloadgo-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.go53
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