diff --git a/creflect/ae1.17.go b/creflect/ae1.17.go new file mode 100644 index 0000000..68a7e75 --- /dev/null +++ b/creflect/ae1.17.go @@ -0,0 +1,39 @@ +//go:build go1.17 +// +build go1.17 + +package creflect + +import ( + "unsafe" +) + +// name is an encoded type name with optional extra data. +type name struct { + bytes *byte +} + +func (n name) data(off int, whySafe string) *byte { + return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe)) +} + +func (n name) readVarint(off int) (int, int) { + v := 0 + for i := 0; ; i++ { + x := *n.data(off+i, "read varint") + v += int(x&0x7f) << (7 * i) + if x&0x80 == 0 { + return i + 1, v + } + } +} + +func (n name) name() (s string) { + if n.bytes == nil { + return + } + i, l := n.readVarint(1) + hdr := (*String)(unsafe.Pointer(&s)) + hdr.Data = unsafe.Pointer(n.data(1+i, "non-empty string")) + hdr.Len = l + return +} diff --git a/creflect/be1.16.go b/creflect/be1.16.go new file mode 100644 index 0000000..1fb6988 --- /dev/null +++ b/creflect/be1.16.go @@ -0,0 +1,25 @@ +//go:build !go1.17 +// +build !go1.17 + +package creflect + +import ( + "unsafe" +) + +// name is an encoded type name with optional extra data. +type name struct { + bytes *byte +} + +func (n name) name() (s string) { + if n.bytes == nil { + return + } + b := (*[4]byte)(unsafe.Pointer(n.bytes)) + + hdr := (*String)(unsafe.Pointer(&s)) + hdr.Data = unsafe.Pointer(&b[3]) + hdr.Len = int(b[1])<<8 | int(b[2]) + return s +} diff --git a/creflect/type.go b/creflect/type.go index 048319c..7df1f09 100644 --- a/creflect/type.go +++ b/creflect/type.go @@ -35,6 +35,7 @@ type funcValue struct { _ uintptr p unsafe.Pointer } + func funcPointer(v reflect.Method, ok bool) (unsafe.Pointer, bool) { return (*funcValue)(unsafe.Pointer(&v.Func)).p, ok } @@ -84,6 +85,7 @@ func (t *rtype) nameOff(off nameOff) name { const ( tflagUncommon tflag = 1 << 0 ) + // uncommonType is present only for defined types or types with methods type uncommonType struct { pkgPath nameOff // import path; empty for built-in types like int, string @@ -122,28 +124,11 @@ type imethod struct { typ typeOff // .(*FuncType) underneath } -// name is an encoded type name with optional extra data. -type name struct { - bytes *byte -} - type String struct { Data unsafe.Pointer Len int } -func (n name) name() (s string) { - if n.bytes == nil { - return - } - b := (*[4]byte)(unsafe.Pointer(n.bytes)) - - hdr := (*String)(unsafe.Pointer(&s)) - hdr.Data = unsafe.Pointer(&b[3]) - hdr.Len = int(b[1])<<8 | int(b[2]) - return s -} - func (t *rtype) uncommon(r reflect.Type) *uncommonType { if t.tflag&tflagUncommon == 0 { return nil @@ -191,4 +176,4 @@ func (t *uncommonType) methods() []method { return nil } return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount] -} \ No newline at end of file +}