compiler, reflect: replace package and name length with null-byte termination
Этот коммит содержится в:
родитель
2de64d3f4e
коммит
6a45b73fcb
3 изменённых файлов: 25 добавлений и 18 удалений
|
@ -112,10 +112,8 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
typeFieldTypes = append(typeFieldTypes,
|
||||
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "underlying", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "pkglen", types.Typ[types.Uintptr]),
|
||||
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "len", types.Typ[types.Uintptr]),
|
||||
types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], int64(len(typ.Obj().Name())))),
|
||||
types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], 1+int64(len(typ.Obj().Name())))),
|
||||
)
|
||||
case *types.Chan, *types.Slice:
|
||||
typeFieldTypes = append(typeFieldTypes,
|
||||
|
@ -183,7 +181,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
pkgpathName = "reflect/types.type.pkgpath:" + pkgpath
|
||||
}
|
||||
|
||||
pkgpathInitializer := c.ctx.ConstString(pkgpath, false)
|
||||
pkgpathInitializer := c.ctx.ConstString(pkgpath+"\x00", false)
|
||||
pkgpathGlobal := llvm.AddGlobal(c.mod, pkgpathInitializer.Type(), pkgpathName)
|
||||
pkgpathGlobal.SetInitializer(pkgpathInitializer)
|
||||
pkgpathGlobal.SetAlignment(1)
|
||||
|
@ -196,12 +194,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
})
|
||||
|
||||
typeFields = []llvm.Value{
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
c.getTypeCode(typ.Underlying()), // underlying
|
||||
llvm.ConstInt(c.uintptrType, uint64(len(pkgpath)), false), // pkgpath length
|
||||
pkgpathPtr, // pkgpath pointer
|
||||
llvm.ConstInt(c.uintptrType, uint64(len(name)), false), // length
|
||||
c.ctx.ConstString(name, false), // name
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
c.getTypeCode(typ.Underlying()), // underlying
|
||||
pkgpathPtr, // pkgpath pointer
|
||||
c.ctx.ConstString(name+"\x00", false), // name
|
||||
}
|
||||
metabyte |= 1 << 5 // "named" flag
|
||||
case *types.Chan:
|
||||
|
|
4
compiler/testdata/interface.ll
предоставленный
4
compiler/testdata/interface.ll
предоставленный
|
@ -9,8 +9,8 @@ target triple = "wasm32-unknown-wasi"
|
|||
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 2, ptr @"reflect/types.type:pointer:basic:int" }, align 4
|
||||
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, ptr } { i8 21, ptr @"reflect/types.type:basic:int" }, align 4
|
||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, ptr } { i8 21, ptr @"reflect/types.type:named:error" }, align 4
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, ptr, ptr, i32, ptr, i32, [5 x i8] } { i8 52, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i32 0, ptr @"reflect/types.type.pkgpath.empty", i32 5, [5 x i8] c"error" }, align 4
|
||||
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [0 x i8] zeroinitializer, align 1
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, ptr, ptr, ptr, [6 x i8] } { i8 52, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [6 x i8] c"error\00" }, align 4
|
||||
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 20, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 21, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 21, ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}" }, align 4
|
||||
|
|
|
@ -50,9 +50,7 @@
|
|||
// meta uint8
|
||||
// ptrTo *typeStruct
|
||||
// elem *typeStruct // underlying type
|
||||
// plen uintptr // length of pkgpath
|
||||
// pkg *byte // pkgpath
|
||||
// nlem uintptr // length of name
|
||||
// name [1]byte // actual name; length nlem
|
||||
//
|
||||
// The type struct is essentially a union of all the above types. Which it is,
|
||||
|
@ -430,9 +428,7 @@ type namedType struct {
|
|||
rawType
|
||||
ptrTo *rawType
|
||||
elem *rawType
|
||||
plen uintptr
|
||||
pkg *byte
|
||||
nlen uintptr
|
||||
name [1]byte
|
||||
}
|
||||
|
||||
|
@ -896,10 +892,25 @@ func (t *rawType) NumMethod() int {
|
|||
panic("unimplemented: (reflect.Type).NumMethod()")
|
||||
}
|
||||
|
||||
// Read and return a null terminated string starting from data.
|
||||
func readStringZ(data unsafe.Pointer) string {
|
||||
start := data
|
||||
var len uintptr
|
||||
for *(*byte)(data) != 0 {
|
||||
len++
|
||||
data = unsafe.Add(data, 1) // C: data++
|
||||
}
|
||||
|
||||
return *(*string)(unsafe.Pointer(&stringHeader{
|
||||
data: start,
|
||||
len: len,
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *rawType) Name() string {
|
||||
if t.isNamed() {
|
||||
ntype := (*namedType)(unsafe.Pointer(t))
|
||||
return unsafe.String(&ntype.name[0], ntype.nlen)
|
||||
return readStringZ(unsafe.Pointer(&ntype.name[0]))
|
||||
}
|
||||
|
||||
return t.Kind().String()
|
||||
|
@ -924,7 +935,7 @@ func (t rawType) MethodByName(name string) (Method, bool) {
|
|||
func (t *rawType) PkgPath() string {
|
||||
if t.isNamed() {
|
||||
ntype := (*namedType)(unsafe.Pointer(t))
|
||||
return unsafe.String(ntype.pkg, ntype.plen)
|
||||
return readStringZ(unsafe.Pointer(ntype.pkg))
|
||||
}
|
||||
|
||||
return ""
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче