compiler,reflect: add reflect.Type.NumMethods()
Этот коммит содержится в:
родитель
821227a03b
коммит
7a96f0f609
4 изменённых файлов: 46 добавлений и 19 удалений
|
@ -134,6 +134,7 @@ 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, "numMethods", types.Typ[types.Uint16]),
|
||||
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "name", types.NewArray(types.Typ[types.Int8], 1+int64(len(typ.Obj().Name())))),
|
||||
)
|
||||
|
@ -145,6 +146,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
case *types.Pointer:
|
||||
typeFieldTypes = append(typeFieldTypes,
|
||||
types.NewVar(token.NoPos, nil, "elementType", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "numMethods", types.Typ[types.Uint16]),
|
||||
)
|
||||
case *types.Array:
|
||||
typeFieldTypes = append(typeFieldTypes,
|
||||
|
@ -161,6 +163,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
case *types.Struct:
|
||||
typeFieldTypes = append(typeFieldTypes,
|
||||
types.NewVar(token.NoPos, nil, "numFields", types.Typ[types.Uint16]),
|
||||
types.NewVar(token.NoPos, nil, "numMethods", types.Typ[types.Uint16]),
|
||||
types.NewVar(token.NoPos, nil, "ptrTo", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "pkgpath", types.Typ[types.UnsafePointer]),
|
||||
types.NewVar(token.NoPos, nil, "fields", types.NewArray(c.getRuntimeType("structField"), int64(typ.NumFields()))),
|
||||
|
@ -201,8 +204,9 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
}
|
||||
pkgPathPtr := c.pkgPathPtr(pkgpath)
|
||||
typeFields = []llvm.Value{
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
c.getTypeCode(typ.Underlying()), // underlying
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
c.getTypeCode(typ.Underlying()), // underlying
|
||||
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
|
||||
pkgPathPtr, // pkgpath pointer
|
||||
c.ctx.ConstString(name+"\x00", false), // name
|
||||
}
|
||||
|
@ -218,7 +222,10 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
c.getTypeCode(typ.Elem()), // elementType
|
||||
}
|
||||
case *types.Pointer:
|
||||
typeFields = []llvm.Value{c.getTypeCode(typ.Elem())}
|
||||
typeFields = []llvm.Value{
|
||||
c.getTypeCode(typ.Elem()),
|
||||
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
|
||||
}
|
||||
case *types.Array:
|
||||
typeFields = []llvm.Value{
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
|
@ -242,6 +249,7 @@ func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
|||
|
||||
typeFields = []llvm.Value{
|
||||
llvm.ConstInt(c.ctx.Int16Type(), uint64(typ.NumFields()), false), // numFields
|
||||
llvm.ConstInt(c.ctx.Int16Type(), uint64(ms.Len()), false), // numMethods
|
||||
c.getTypeCode(types.NewPointer(typ)), // ptrTo
|
||||
pkgPathPtr,
|
||||
}
|
||||
|
|
2
compiler/testdata/gc.ll
предоставленный
2
compiler/testdata/gc.ll
предоставленный
|
@ -22,7 +22,7 @@ target triple = "wasm32-unknown-wasi"
|
|||
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
|
||||
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
|
||||
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 16, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
|
||||
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 21, ptr @"reflect/types.type:basic:complex128" }, align 4
|
||||
@"reflect/types.type:pointer:basic:complex128" = linkonce_odr constant { i8, ptr, i16 } { i8 21, ptr @"reflect/types.type:basic:complex128", i16 0 }, align 4
|
||||
|
||||
declare noalias nonnull ptr @runtime.alloc(i32, ptr, ptr) #0
|
||||
|
||||
|
|
10
compiler/testdata/interface.ll
предоставленный
10
compiler/testdata/interface.ll
предоставленный
|
@ -7,13 +7,13 @@ target triple = "wasm32-unknown-wasi"
|
|||
%runtime._string = type { ptr, i32 }
|
||||
|
||||
@"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, 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:pointer:basic:int" = linkonce_odr constant { i8, ptr, i16 } { i8 21, ptr @"reflect/types.type:basic:int", i16 0 }, align 4
|
||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, ptr, i16 } { i8 21, ptr @"reflect/types.type:named:error", i16 0 }, align 4
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, ptr, ptr, i16, ptr, [6 x i8] } { i8 52, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i16 1, 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
|
||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr, i16 } { i8 21, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", i16 0 }, align 4
|
||||
@"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr, i16 } { i8 21, ptr @"reflect/types.type:interface:{String:func:{}{basic:string}}", i16 0 }, align 4
|
||||
@"reflect/types.type:interface:{String:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 20, ptr @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" }, align 4
|
||||
@"reflect/types.typeid:basic:int" = external constant i8
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
// - pointer types (see ptrType, this doesn't include chan, map, etc):
|
||||
// meta uint8
|
||||
// elementType *typeStruct
|
||||
// nmethods uint16
|
||||
// - array types (see arrayType)
|
||||
// meta uint8
|
||||
// ptrTo *typeStruct
|
||||
|
@ -38,6 +39,7 @@
|
|||
// - struct types (see structType):
|
||||
// meta uint8
|
||||
// numField uint16
|
||||
// nmethods uint16
|
||||
// ptrTo *typeStruct
|
||||
// pkgpath *byte
|
||||
// fields [...]structField // the remaining fields are all of type structField
|
||||
|
@ -51,6 +53,7 @@
|
|||
// meta uint8
|
||||
// ptrTo *typeStruct
|
||||
// elem *typeStruct // underlying type
|
||||
// nmethods uint16 // number of methods
|
||||
// pkg *byte // pkgpath
|
||||
// name [1]byte // actual name; length nlem
|
||||
//
|
||||
|
@ -409,7 +412,8 @@ type elemType struct {
|
|||
|
||||
type ptrType struct {
|
||||
rawType
|
||||
elem *rawType
|
||||
elem *rawType
|
||||
numMethod uint16
|
||||
}
|
||||
|
||||
type arrayType struct {
|
||||
|
@ -428,10 +432,11 @@ type mapType struct {
|
|||
|
||||
type namedType struct {
|
||||
rawType
|
||||
ptrTo *rawType
|
||||
elem *rawType
|
||||
pkg *byte
|
||||
name [1]byte
|
||||
ptrTo *rawType
|
||||
elem *rawType
|
||||
numMethod uint16
|
||||
pkg *byte
|
||||
name [1]byte
|
||||
}
|
||||
|
||||
// Type for struct types. The numField value is intentionally put before ptrTo
|
||||
|
@ -443,10 +448,11 @@ type namedType struct {
|
|||
// checker.
|
||||
type structType struct {
|
||||
rawType
|
||||
numField uint16
|
||||
ptrTo *rawType
|
||||
pkgpath *byte
|
||||
fields [1]structField // the remaining fields are all of type structField
|
||||
numField uint16
|
||||
numMethod uint16
|
||||
ptrTo *rawType
|
||||
pkgpath *byte
|
||||
fields [1]structField // the remaining fields are all of type structField
|
||||
}
|
||||
|
||||
type structField struct {
|
||||
|
@ -992,7 +998,20 @@ func (t *rawType) NumOut() int {
|
|||
}
|
||||
|
||||
func (t *rawType) NumMethod() int {
|
||||
panic("unimplemented: (reflect.Type).NumMethod()")
|
||||
|
||||
if t.isNamed() {
|
||||
return int((*namedType)(unsafe.Pointer(t)).numMethod)
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
case Pointer:
|
||||
return int((*ptrType)(unsafe.Pointer(t)).numMethod)
|
||||
case Struct:
|
||||
return int((*structType)(unsafe.Pointer(t)).numMethod)
|
||||
}
|
||||
|
||||
// Other types have no methods attached. Note we don't panic here.
|
||||
return 0
|
||||
}
|
||||
|
||||
// Read and return a null terminated string starting from data.
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче