From 8ef19c7a8973158ade1ef8dfaec4cebc41826617 Mon Sep 17 00:00:00 2001 From: Mitkin Kirill Date: Mon, 17 Jul 2023 20:41:42 +0300 Subject: [PATCH 1/3] reflect lib and runtime interaction draft Signed-off-by: Mitkin Kirill --- plugins/ets/runtime/ets_libbase_runtime.yaml | 34 ++- .../ets/runtime/intrinsics/std_core_Type.cpp | 1 + plugins/ets/runtime/types/ets_reflect_field.h | 68 ++++++ plugins/ets/stdlib/std/core/Field.ets | 7 +- plugins/ets/stdlib/std/core/Type.ets | 225 +++++++++--------- 5 files changed, 214 insertions(+), 121 deletions(-) create mode 100644 plugins/ets/runtime/types/ets_reflect_field.h diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index 86427db28..34a7ef9be 100644 --- a/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -1291,7 +1291,7 @@ intrinsics: ret: void args: [ std.core.Object ] impl: panda::ets::intrinsics::StdGCUnpinObject - + - name: StdGetFreeHeapSize space: ets class_name: std.core.GC @@ -1301,7 +1301,7 @@ intrinsics: ret: i64 args: [ ] impl: panda::ets::intrinsics::StdGetFreeHeapSize - + - name: StdGetUsedHeapSize space: ets class_name: std.core.GC @@ -1311,7 +1311,7 @@ intrinsics: ret: i64 args: [ ] impl: panda::ets::intrinsics::StdGetUsedHeapSize - + - name: StdGetReservedHeapSize space: ets class_name: std.core.GC @@ -1407,6 +1407,30 @@ intrinsics: impl: panda::ets::intrinsics::StdCoreRuntimeEquals clear_flags: [ ] +################# +# std.core.Type # +################# + - name: StdCoreTypeGetDescriptor + space: ets + class_name: std.core.ETSGLOBAL + method_name: GetTypeDescriptor + static: false + signature: + ret: std.core.String + args: [ std.core.Object ] + impl: panda::ets::intrinsics::StdCoreTypeGetDescriptor + + + - name: StdCoreClassTypeGetFieldByName + space: ets + class_name: std.core.ClassType + method_name: getFieldByName + static: false + signature: + ret: std.core.Field + args: [ std.core.String ] + impl: panda::ets::intrinsics::StdCoreClassTypeGetFieldByName + ########################## # std.serialization.JSON # ########################## @@ -1694,7 +1718,7 @@ intrinsics: args: [ std.core.Object, i64 ] impl: panda::ets::intrinsics::ValueAPIGetFieldByte clear_flags: [ ] - + - name: ValueAPIGetFieldChar space: ets class_name: std.core.ETSGLOBAL @@ -1705,7 +1729,7 @@ intrinsics: args: [ std.core.Object, i64 ] impl: panda::ets::intrinsics::ValueAPIGetFieldChar clear_flags: [ ] - + - name: ValueAPIGetFieldShort space: ets class_name: std.core.ETSGLOBAL diff --git a/plugins/ets/runtime/intrinsics/std_core_Type.cpp b/plugins/ets/runtime/intrinsics/std_core_Type.cpp index 560c90368..8f8599d7c 100644 --- a/plugins/ets/runtime/intrinsics/std_core_Type.cpp +++ b/plugins/ets/runtime/intrinsics/std_core_Type.cpp @@ -351,4 +351,5 @@ EtsString *TypeAPIGetBaseType(EtsString *td) } return EtsString::CreateFromMUtf8(base_class->GetDescriptor()); } + } // namespace panda::ets::intrinsics diff --git a/plugins/ets/runtime/types/ets_reflect_field.h b/plugins/ets/runtime/types/ets_reflect_field.h new file mode 100644 index 000000000..193e9e17a --- /dev/null +++ b/plugins/ets/runtime/types/ets_reflect_field.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ +#define PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ + +namespace panda::ets { + +#include "plugins/ets/runtime/types/ets_object.h" + +class EtsReflectField : public ObjectHeader { +public: + + EtsReflectField() = delete; + ~EtsReflectField() = delete; + + NO_COPY_SEMANTIC(EtsReflectField); + NO_MOVE_SEMANTIC(EtsReflectField); + + EtsObject *AsObject() + { + return EtsObject::FromCoreType(this); + } + + const EtsObject *AsObject() const + { + return EtsObject::FromCoreType(this); + } + + static EtsReflectField *FromEtsObject(EtsObject *field) + { + return reinterpret_cast(field); + } + + void SetTypeDescriptor(const char * type_desc) { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsReflectField, type_descriptor), EtsString::CreateFromMUtf8(type_desc)->AsObject()->GetCoreType()); + } + + void SetName(EtsString * name) { + ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsReflectField, name_), name->AsObject()->GetCoreType()); + } + + void SetAttributes(uint32_t attr) { + ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsReflectField, attributes), attr); + } + +private: + ObjectPointer type_descriptor; + ObjectPointer name_; + FIELD_UNUSED uint32_t attributes; + +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ diff --git a/plugins/ets/stdlib/std/core/Field.ets b/plugins/ets/stdlib/std/core/Field.ets index 441dc2cd1..7b387d9bc 100644 --- a/plugins/ets/stdlib/std/core/Field.ets +++ b/plugins/ets/stdlib/std/core/Field.ets @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,8 +17,8 @@ package std.core; export final class Field extends Object { - private td: string - private name: string + private td: string + private name: string private accessMod: byte private attributes: int @@ -29,4 +30,4 @@ export final class Field extends Object { public getName(): String { return this.name } -} \ No newline at end of file +} diff --git a/plugins/ets/stdlib/std/core/Type.ets b/plugins/ets/stdlib/std/core/Type.ets index 2c022d53a..530bf810f 100644 --- a/plugins/ets/stdlib/std/core/Type.ets +++ b/plugins/ets/stdlib/std/core/Type.ets @@ -15,7 +15,7 @@ package std.core; -type TypeDesc = string +type TypeDesc = string native function TypeAPIGetTypeDescriptor(o: Object): string @@ -48,7 +48,7 @@ native function TypeAPIMakeArrayInstance(td: TypeDesc, len: long): Object native function TypeAPIGetBaseType(td: TypeDesc): TypeDesc // TODO(shumilov-petr): replace to enum, enum not available now -export type TypeKind = byte +export type TypeKind = byte const NoneKind: TypeKind = 0x0 const VoidKind: TypeKind = 0x1 @@ -61,10 +61,10 @@ const IntKind: TypeKind = 0x6 const LongKind: TypeKind = 0x7 const FloatKind: TypeKind = 0x8 const DoubleKind: TypeKind = 0x9 - + const ClassKind: TypeKind = 0xA const StringKind: TypeKind = 0xB -const InterfaceKind: TypeKind = 0xC +const InterfaceKind: TypeKind = 0xC const ArrayKind: TypeKind = 0xD const FunctionKind: TypeKind = 0xE const UnionKind: TypeKind = 0xF @@ -98,7 +98,7 @@ export abstract class Type extends Object { switch (kind) { case VoidKind: return VoidType.getInstance() - + case CharKind: return CharType.getInstance(td) case BooleanKind: @@ -174,7 +174,7 @@ export abstract class Type extends Object { } // ----- - + public static of(o: Object | null): Type { if (o == null) { return NullType.getInstance() @@ -184,7 +184,7 @@ export abstract class Type extends Object { } // ----- - + public static of(v: Boolean): Type { return BooleanType.getInstance(TypeAPIGetTypeDescriptor(v)) } @@ -262,24 +262,24 @@ export abstract class Type extends Object { public static of(v: Object[]): Type { return ArrayType.getInstance(TypeAPIGetTypeDescriptor(v)) } - + public abstract isPrimitive(): boolean // Or Composite public abstract isReference(): boolean // Or Value - public abstract hasName(): boolean + public abstract hasName(): boolean public getId(): long { return TypeAPIGetTypeId(this.td); } - public abstract getName(): string + public abstract getName(): string public abstract getLiteral(): string - + public override toString(): string { if (this.hasName()) { - return this.getName() + return this.getName() } return this.getLiteral() } @@ -287,28 +287,28 @@ export abstract class Type extends Object { export final class UndefinedType extends Type { private static instance: UndefinedType | null = null - + private constructor() { - this.td = UndefinedTD + this.td = UndefinedTD } public static getInstance(): UndefinedType { if (UndefinedType.instance == null) { UndefinedType.instance = new UndefinedType() - } + } return UndefinedType.instance } public override isPrimitive(): boolean { - return true + return true } public override isReference(): boolean { - return true + return true } public override hasName(): boolean { - return true + return true } public override getName(): string { @@ -327,15 +327,15 @@ export final class UndefinedType extends Type { export final class VoidType extends Type { private static instance: VoidType | null = null - + private constructor() { - this.td = VoidTD + this.td = VoidTD } public static getInstance(): VoidType { if (VoidType.instance == null) { VoidType.instance = new VoidType() - } + } return VoidType.instance } @@ -344,11 +344,11 @@ export final class VoidType extends Type { } public override isReference(): boolean { - return true + return true } public override hasName(): boolean { - return true + return true } public override getName(): string { @@ -368,25 +368,25 @@ export final class VoidType extends Type { export final class CharType extends Type { private static refInst: CharType | null = null private static valInst: CharType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): CharType { if (TypeAPIIsValueType(td)) { - CharType.valInst = (CharType.valInst == null) ? new CharType(td, true) : CharType.valInst + CharType.valInst = (CharType.valInst == null) ? new CharType(td, true) : CharType.valInst return CharType.valInst! - } + } CharType.refInst = (CharType.refInst == null) ? new CharType(td, false) : CharType.refInst return CharType.refInst! } public override isPrimitive(): boolean { - return true + return true } public override isReference(): boolean { @@ -394,7 +394,7 @@ export final class CharType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -412,7 +412,7 @@ export final class CharType extends Type { } public override equals(to: Object): boolean { - return to instanceof CharType && this.isValue != (to as CharType).isReference() + return to instanceof CharType && this.isValue != (to as CharType).isReference() } } @@ -420,19 +420,19 @@ export final class CharType extends Type { export final class BooleanType extends Type { private static refInst: BooleanType | null = null private static valInst: BooleanType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): BooleanType { if (TypeAPIIsValueType(td)) { - BooleanType.valInst = (BooleanType.valInst == null) ? new BooleanType(td, true) : BooleanType.valInst + BooleanType.valInst = (BooleanType.valInst == null) ? new BooleanType(td, true) : BooleanType.valInst return BooleanType.valInst! - } + } BooleanType.refInst =(BooleanType.refInst == null) ? new BooleanType(td, false) : BooleanType.refInst return BooleanType.refInst! } @@ -446,7 +446,7 @@ export final class BooleanType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -464,7 +464,7 @@ export final class BooleanType extends Type { } public override equals(to: Object): boolean { - return to instanceof BooleanType && this.isValue != (to as BooleanType).isReference() + return to instanceof BooleanType && this.isValue != (to as BooleanType).isReference() } } @@ -472,19 +472,19 @@ export final class BooleanType extends Type { export final class ByteType extends Type { private static refInst: ByteType | null = null private static valInst: ByteType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): ByteType { if (TypeAPIIsValueType(td)) { - ByteType.valInst = (ByteType.valInst == null) ? new ByteType(td, true) : ByteType.valInst + ByteType.valInst = (ByteType.valInst == null) ? new ByteType(td, true) : ByteType.valInst return ByteType.valInst! - } + } ByteType.refInst = (ByteType.refInst == null) ? new ByteType(td, false) : ByteType.refInst return ByteType.refInst! } @@ -498,7 +498,7 @@ export final class ByteType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -516,7 +516,7 @@ export final class ByteType extends Type { } public override equals(to: Object): boolean { - return to instanceof ByteType && this.isValue != (to as ByteType).isReference() + return to instanceof ByteType && this.isValue != (to as ByteType).isReference() } } @@ -524,19 +524,19 @@ export final class ByteType extends Type { export final class ShortType extends Type { private static refInst: ShortType | null = null private static valInst: ShortType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): ShortType { if (TypeAPIIsValueType(td)) { - ShortType.valInst = (ShortType.valInst == null) ? new ShortType(td, true) : ShortType.valInst + ShortType.valInst = (ShortType.valInst == null) ? new ShortType(td, true) : ShortType.valInst return ShortType.valInst! - } + } ShortType.refInst = (ShortType.refInst == null) ? new ShortType(td, false) : ShortType.refInst return ShortType.refInst! } @@ -550,7 +550,7 @@ export final class ShortType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -576,19 +576,19 @@ export final class ShortType extends Type { export final class IntType extends Type { private static refInst: IntType | null = null private static valInst: IntType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): IntType { if (TypeAPIIsValueType(td)) { - IntType.valInst = (IntType.valInst == null) ? new IntType(td, true) : IntType.valInst + IntType.valInst = (IntType.valInst == null) ? new IntType(td, true) : IntType.valInst return IntType.valInst! - } + } IntType.refInst = (IntType.refInst == null) ? new IntType(td, false) : IntType.refInst return IntType.refInst! } @@ -602,7 +602,7 @@ export final class IntType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -628,19 +628,19 @@ export final class IntType extends Type { export final class LongType extends Type { private static refInst: LongType | null = null private static valInst: LongType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): LongType { if (TypeAPIIsValueType(td)) { - LongType.valInst = (LongType.valInst == null) ? new LongType(td, true) : LongType.valInst + LongType.valInst = (LongType.valInst == null) ? new LongType(td, true) : LongType.valInst return LongType.valInst! - } + } LongType.refInst = (LongType.refInst == null) ? new LongType(td, false) : LongType.refInst return LongType.refInst! } @@ -654,7 +654,7 @@ export final class LongType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -680,19 +680,19 @@ export final class LongType extends Type { export final class FloatType extends Type { private static refInst: FloatType | null = null private static valInst: FloatType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): FloatType { if (TypeAPIIsValueType(td)) { - FloatType.valInst = (FloatType.valInst == null) ? new FloatType(td, true) : FloatType.valInst + FloatType.valInst = (FloatType.valInst == null) ? new FloatType(td, true) : FloatType.valInst return FloatType.valInst! - } + } FloatType.refInst = (FloatType.refInst == null) ? new FloatType(td, false) : FloatType.refInst return FloatType.refInst! } @@ -706,7 +706,7 @@ export final class FloatType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -732,19 +732,19 @@ export final class FloatType extends Type { export final class DoubleType extends Type { private static refInst: DoubleType | null = null private static valInst: DoubleType | null = null - - private isValue: boolean + + private isValue: boolean private constructor(td: TypeDesc, isValue: boolean) { this.td = td - this.isValue = isValue + this.isValue = isValue } public static getInstance(td: TypeDesc): DoubleType { if (TypeAPIIsValueType(td)) { - DoubleType.valInst = (DoubleType.valInst == null) ? new DoubleType(td, true) : DoubleType.valInst + DoubleType.valInst = (DoubleType.valInst == null) ? new DoubleType(td, true) : DoubleType.valInst return DoubleType.valInst! - } + } DoubleType.refInst = (DoubleType.refInst == null) ? new DoubleType(td, false) : DoubleType.refInst return DoubleType.refInst! } @@ -758,7 +758,7 @@ export final class DoubleType extends Type { } public override hasName(): boolean { - return !this.isValue + return !this.isValue } public override getName(): string { @@ -783,7 +783,7 @@ export final class DoubleType extends Type { export final class ClassType extends Type { public constructor(td: TypeDesc) { - this.td = td + this.td = td } public override isPrimitive(): boolean { @@ -795,7 +795,7 @@ export final class ClassType extends Type { } public override hasName(): boolean { - return true + return true } public override getName(): string { @@ -809,7 +809,7 @@ export final class ClassType extends Type { public override equals(to: Object): boolean { // TODO(shumilov-petr): not implemented - return false + return false } public hasEmptyConstructor(): boolean { @@ -824,7 +824,7 @@ export final class ClassType extends Type { } public getBaseType(): Type { - // TODO(mitkin-kirill): discuss necessity of getBaseTypes + // TODO(mitkin-kirill): discuss necessity of getBaseTypes return Type.resolve(TypeAPIGetBaseType(this.td)) } @@ -919,7 +919,7 @@ export final class ClassType extends Type { export final class InterfaceType extends Type { public constructor(td: TypeDesc) { - this.td = td + this.td = td } public override isPrimitive(): boolean { @@ -931,7 +931,7 @@ export final class InterfaceType extends Type { } public override hasName(): boolean { - return true + return true } public override getName(): string { @@ -945,7 +945,7 @@ export final class InterfaceType extends Type { public override equals(to: Object): boolean { // TODO(shumilov-petr): not implemented - return false + return false } public getBaseTypesNum(): long { @@ -1017,7 +1017,7 @@ export final class InterfaceType extends Type { export final class ArrayType extends Type { private elemTD: TypeDesc - + private static booleanInst: ArrayType | null = null private static charInst: ArrayType | null = null private static byteInst: ArrayType | null = null @@ -1026,7 +1026,7 @@ export final class ArrayType extends Type { private static longInst: ArrayType | null = null private static floatInst: ArrayType | null = null private static doubleInst: ArrayType | null = null - + private constructor(td: TypeDesc, elemTD: TypeDesc) { this.td = td this.elemTD = elemTD @@ -1036,28 +1036,28 @@ export final class ArrayType extends Type { let ek = TypeAPIGetTypeKind(elemTD) & TypeKindMask switch (ek) { case BooleanKind: - ArrayType.booleanInst = (ArrayType.booleanInst == null) ? new ArrayType(td, elemTD) : ArrayType.booleanInst + ArrayType.booleanInst = (ArrayType.booleanInst == null) ? new ArrayType(td, elemTD) : ArrayType.booleanInst return ArrayType.booleanInst! case CharKind: - ArrayType.charInst = (ArrayType.charInst == null) ? new ArrayType(td, elemTD) : ArrayType.charInst + ArrayType.charInst = (ArrayType.charInst == null) ? new ArrayType(td, elemTD) : ArrayType.charInst return ArrayType.charInst! case ByteKind: - ArrayType.byteInst = (ArrayType.byteInst == null) ? new ArrayType(td, elemTD) : ArrayType.byteInst + ArrayType.byteInst = (ArrayType.byteInst == null) ? new ArrayType(td, elemTD) : ArrayType.byteInst return ArrayType.byteInst! case ShortKind: - ArrayType.shortInst = (ArrayType.shortInst == null) ? new ArrayType(td, elemTD) : ArrayType.shortInst + ArrayType.shortInst = (ArrayType.shortInst == null) ? new ArrayType(td, elemTD) : ArrayType.shortInst return ArrayType.shortInst! case IntKind: - ArrayType.intInst = (ArrayType.intInst == null) ? new ArrayType(td, elemTD) : ArrayType.intInst + ArrayType.intInst = (ArrayType.intInst == null) ? new ArrayType(td, elemTD) : ArrayType.intInst return ArrayType.intInst! case LongKind: - ArrayType.longInst = (ArrayType.longInst == null) ? new ArrayType(td, elemTD) : ArrayType.longInst + ArrayType.longInst = (ArrayType.longInst == null) ? new ArrayType(td, elemTD) : ArrayType.longInst return ArrayType.longInst! case FloatKind: - ArrayType.floatInst = (ArrayType.floatInst == null) ? new ArrayType(td, elemTD) : ArrayType.floatInst + ArrayType.floatInst = (ArrayType.floatInst == null) ? new ArrayType(td, elemTD) : ArrayType.floatInst return ArrayType.floatInst! case DoubleKind: - ArrayType.doubleInst = (ArrayType.doubleInst == null) ? new ArrayType(td, elemTD) : ArrayType.doubleInst + ArrayType.doubleInst = (ArrayType.doubleInst == null) ? new ArrayType(td, elemTD) : ArrayType.doubleInst return ArrayType.doubleInst! case ClassKind: case StringKind: @@ -1067,7 +1067,7 @@ export final class ArrayType extends Type { case UnionKind: return new ArrayType(td, elemTD) default: - // TODO(shumilov-petr): need throw exception + // TODO(shumilov-petr): need throw exception assert(false) } } @@ -1085,7 +1085,7 @@ export final class ArrayType extends Type { } public override hasName(): boolean { - return false + return false } public override getName(): string { @@ -1098,7 +1098,7 @@ export final class ArrayType extends Type { public override equals(to: Object): boolean { // TODO(shumilov-petr): not implemented - return false + return false } public getElementType(): Type { @@ -1122,16 +1122,16 @@ export final class ArrayType extends Type { export final class FunctionType extends Type { - private isThrowabl: boolean - private isNativ: boolean - private isAsyn: boolean - + private isThrowabl: boolean + private isNativ: boolean + private isAsyn: boolean + constructor(td: TypeDesc) { this.td = td // TODO(shumilov-petr): not implemented - this.isThrowabl = false + this.isThrowabl = false this.isNativ = false - this.isAsyn = false + this.isAsyn = false } public override isPrimitive(): boolean { @@ -1143,7 +1143,7 @@ export final class FunctionType extends Type { } public override hasName(): boolean { - return false + return false } public isThrowable(): boolean { @@ -1196,7 +1196,7 @@ export final class FunctionType extends Type { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") } - + public static create(): FunctionType { // TODO(shumilov-petr): not implemented throw new Error("Not implemented") @@ -1233,7 +1233,7 @@ export final class StringType extends Type { private static inst: StringType | null = null constructor() { - this.td = TypeAPIGetTypeDescriptor("") + this.td = TypeAPIGetTypeDescriptor("") } public static getInstance(): StringType { @@ -1250,7 +1250,7 @@ export final class StringType extends Type { } public override hasName(): boolean { - return false + return false } public override getName(): string { @@ -1272,7 +1272,7 @@ export final class StringType extends Type { export final class EnumType extends Type { constructor(td: TypeDesc) { - this.td = td + this.td = td } public override isPrimitive(): boolean { @@ -1284,7 +1284,7 @@ export final class EnumType extends Type { } public override hasName(): boolean { - return false + return false } public override getName(): string { @@ -1306,7 +1306,7 @@ export final class EnumType extends Type { export final class UnionType extends Type { constructor(td: TypeDesc) { - this.td = td + this.td = td } public override isPrimitive(): boolean { @@ -1318,7 +1318,7 @@ export final class UnionType extends Type { } public override hasName(): boolean { - return false + return false } public override getName(): string { @@ -1339,15 +1339,15 @@ export final class UnionType extends Type { export final class NullType extends Type { private static instance: NullType | null = null - + private constructor() { - this.td = NullTD + this.td = NullTD } public static getInstance(): NullType { if (NullType.instance == null) { NullType.instance = new NullType() - } + } return NullType.instance! } @@ -1375,4 +1375,3 @@ export final class NullType extends Type { return (to instanceof NullType); } } - -- Gitee From 9ee9e9b3e57de9a6eaa2a8dd9e3d211fcc730ab5 Mon Sep 17 00:00:00 2001 From: Mitkin Kirill Date: Thu, 20 Jul 2023 20:02:57 +0300 Subject: [PATCH 2/3] add makeInstance intrinsic Signed-off-by: Mitkin Kirill --- plugins/ets/runtime/ets_libbase_runtime.yaml | 10 ++++++++++ .../ets/runtime/intrinsics/std_core_Type.cpp | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index 34a7ef9be..e1848c495 100644 --- a/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -1431,6 +1431,16 @@ intrinsics: args: [ std.core.String ] impl: panda::ets::intrinsics::StdCoreClassTypeGetFieldByName + - name: StdCoreClassTypeMakeInstance + space: ets + class_name: std.core.ClassType + method_name: makeInstance + static: false + signature: + ret: std.core.Object + args: [ ] + impl: panda::ets::intrinsics::StdCoreClassTypeMakeInstance + ########################## # std.serialization.JSON # ########################## diff --git a/plugins/ets/runtime/intrinsics/std_core_Type.cpp b/plugins/ets/runtime/intrinsics/std_core_Type.cpp index 8f8599d7c..412e89c6c 100644 --- a/plugins/ets/runtime/intrinsics/std_core_Type.cpp +++ b/plugins/ets/runtime/intrinsics/std_core_Type.cpp @@ -352,4 +352,24 @@ EtsString *TypeAPIGetBaseType(EtsString *td) return EtsString::CreateFromMUtf8(base_class->GetDescriptor()); } + extern "C" EtsObject* StdCoreClassTypeMakeInstance(EtsObject * obj) { + auto class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); + + auto td_field = obj->GetClass()->GetBase()->GetDeclaredFieldIDByName("td"); + auto td_string = EtsString::FromEtsObject(obj->GetFieldObject(td_field)); + auto type_class = class_linker->GetClass(reinterpret_cast(td_string->GetDataMUtf8())); + + auto object = EtsObject::Create(type_class); + type_class->EnumerateMethods([&](EtsMethod *method) { + if (method->IsConstructor() && method->GetNumArgs() == 1) { + std::cout << (method->GetFullName(true)) << "\n"; + std::array args {Value(object->GetCoreType())}; + method->GetPandaMethod()->InvokeVoid(EtsCoroutine::GetCurrent(), args.data()); + return true; + } + return false; + }); + return object; + } + } // namespace panda::ets::intrinsics -- Gitee From 2c198bbd56edacbd1bef4f849972f0afe6489418 Mon Sep 17 00:00:00 2001 From: Mitkin Kirill Date: Mon, 24 Jul 2023 20:25:55 +0300 Subject: [PATCH 3/3] implement generic type info prototype Signed-off-by: Mitkin Kirill add generic type info Signed-off-by: Mitkin Kirill add rethrowing generic context Signed-off-by: Mitkin Kirill remove reflect type from runtime Signed-off-by: Mitkin Kirill refactor code Signed-off-by: Mitkin Kirill --- plugins/ets/runtime/ets_coroutine.h | 11 +++ plugins/ets/runtime/ets_libbase_runtime.yaml | 68 +++++++++---------- .../ets/runtime/intrinsics/std_core_Type.cpp | 46 +++++++------ plugins/ets/runtime/types/ets_reflect_field.h | 68 ------------------- plugins/ets/stdlib/std/core/Field.ets | 4 +- plugins/ets/stdlib/std/core/Type.ets | 11 ++- 6 files changed, 83 insertions(+), 125 deletions(-) delete mode 100644 plugins/ets/runtime/types/ets_reflect_field.h diff --git a/plugins/ets/runtime/ets_coroutine.h b/plugins/ets/runtime/ets_coroutine.h index 778d8445d..103d9bfd2 100644 --- a/plugins/ets/runtime/ets_coroutine.h +++ b/plugins/ets/runtime/ets_coroutine.h @@ -21,6 +21,7 @@ namespace panda::ets { class PandaEtsVM; +class EtsObjectArray; /** * \brief The eTS coroutine. It is aware of the native interface and reference storage existance. @@ -70,6 +71,11 @@ public: promise_class_ptr_ = promise_class; } + void SetTypeParams(EtsObjectArray * type_class) + { + type_params_ = type_class; + } + static constexpr uint32_t GetTlsPromiseClassPointerOffset() { return MEMBER_OFFSET(EtsCoroutine, promise_class_ptr_); @@ -82,6 +88,10 @@ public: return ets_napi_env_.get(); } + EtsObjectArray * GetTypeParams() const { + return type_params_; + } + void Initialize() override; void RequestCompletion(Value return_value) override; void FreeInternalMemory() override; @@ -97,6 +107,7 @@ private: std::unique_ptr ets_napi_env_; void *promise_class_ptr_ {nullptr}; + EtsObjectArray* type_params_; // Allocator calls our protected ctor friend class mem::Allocator; diff --git a/plugins/ets/runtime/ets_libbase_runtime.yaml b/plugins/ets/runtime/ets_libbase_runtime.yaml index e1848c495..57d2cac98 100644 --- a/plugins/ets/runtime/ets_libbase_runtime.yaml +++ b/plugins/ets/runtime/ets_libbase_runtime.yaml @@ -1407,40 +1407,6 @@ intrinsics: impl: panda::ets::intrinsics::StdCoreRuntimeEquals clear_flags: [ ] -################# -# std.core.Type # -################# - - name: StdCoreTypeGetDescriptor - space: ets - class_name: std.core.ETSGLOBAL - method_name: GetTypeDescriptor - static: false - signature: - ret: std.core.String - args: [ std.core.Object ] - impl: panda::ets::intrinsics::StdCoreTypeGetDescriptor - - - - name: StdCoreClassTypeGetFieldByName - space: ets - class_name: std.core.ClassType - method_name: getFieldByName - static: false - signature: - ret: std.core.Field - args: [ std.core.String ] - impl: panda::ets::intrinsics::StdCoreClassTypeGetFieldByName - - - name: StdCoreClassTypeMakeInstance - space: ets - class_name: std.core.ClassType - method_name: makeInstance - static: false - signature: - ret: std.core.Object - args: [ ] - impl: panda::ets::intrinsics::StdCoreClassTypeMakeInstance - ########################## # std.serialization.JSON # ########################## @@ -1645,6 +1611,40 @@ intrinsics: ret: std.core.String args: [ std.core.String ] impl: panda::ets::intrinsics::TypeAPIGetBaseType + clear_flags: [ ] + + - name: StdCoreTypeStoreTypeParamDescriptors + space: ets + class_name: std.core.ETSGLOBAL + method_name: StoreTypeParamDescriptors + static: true + signature: + ret: void + args: [ 'std.core.String[]' ] + impl: panda::ets::intrinsics::TypeAPIStoreTypeParamDescriptors + clear_flags: [ ] + + - name: StdCoreTypeLoadTypeParamDescriptors + space: ets + class_name: std.core.ETSGLOBAL + method_name: LoadTypeParamDescriptors + static: true + signature: + ret: std.core.String[] + args: [] + impl: panda::ets::intrinsics::TypeAPILoadTypeParamDescriptors + clear_flags: [ ] + + - name: StdCoreTypeGetGenericTypeDesc + space: ets + class_name: std.core.ETSGLOBAL + method_name: GetGenericTypeDesc + static: true + signature: + ret: std.core.String + args: [] + impl: panda::ets::intrinsics::TypeAPIGetGenericTypeDesc + clear_flags: [ ] ################# # std.core.Char # diff --git a/plugins/ets/runtime/intrinsics/std_core_Type.cpp b/plugins/ets/runtime/intrinsics/std_core_Type.cpp index 412e89c6c..5ea23a79a 100644 --- a/plugins/ets/runtime/intrinsics/std_core_Type.cpp +++ b/plugins/ets/runtime/intrinsics/std_core_Type.cpp @@ -22,6 +22,9 @@ #include "intrinsics.h" #include "mem/mem.h" #include "mem/vm_handle.h" +#include "ets_coroutine.h" +#include "ets_vm.h" +#include "macros.h" #include "plugins/ets/runtime/types/ets_object.h" #include "plugins/ets/runtime/types/ets_string.h" #include "plugins/ets/runtime/ets_panda_file_items.h" @@ -34,6 +37,8 @@ #include "types/ets_typeapi_feature.h" #include "types/ets_typeapi_field.h" #include "types/ets_typeapi_method.h" +#include "plugins/ets/runtime/napi/ets_scoped_objects_fix.h" +#include "runtime/handle_scope-inl.h" namespace panda::ets::intrinsics { @@ -352,24 +357,27 @@ EtsString *TypeAPIGetBaseType(EtsString *td) return EtsString::CreateFromMUtf8(base_class->GetDescriptor()); } - extern "C" EtsObject* StdCoreClassTypeMakeInstance(EtsObject * obj) { - auto class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); - - auto td_field = obj->GetClass()->GetBase()->GetDeclaredFieldIDByName("td"); - auto td_string = EtsString::FromEtsObject(obj->GetFieldObject(td_field)); - auto type_class = class_linker->GetClass(reinterpret_cast(td_string->GetDataMUtf8())); - - auto object = EtsObject::Create(type_class); - type_class->EnumerateMethods([&](EtsMethod *method) { - if (method->IsConstructor() && method->GetNumArgs() == 1) { - std::cout << (method->GetFullName(true)) << "\n"; - std::array args {Value(object->GetCoreType())}; - method->GetPandaMethod()->InvokeVoid(EtsCoroutine::GetCurrent(), args.data()); - return true; - } - return false; - }); - return object; - } +void TypeAPIStoreTypeParamDescriptors(ObjectHeader *obj) +{ + auto arr = EtsObjectArray::FromCoreType(obj); + EtsCoroutine::GetCurrent()->SetTypeParams(arr); +} + +ObjectHeader *TypeAPILoadTypeParamDescriptors() +{ + return EtsCoroutine::GetCurrent()->GetTypeParams()->GetCoreType(); +} + +EtsString *TypeAPIGetGenericTypeDesc() +{ + auto params = EtsCoroutine::GetCurrent()->GetTypeParams(); + ASSERT(params->GetLength() == 1); + PandaString assembler_type; + auto type = EtsString::FromEtsObject(params->Get(0)); + assembler_type += CLASS_TYPE_PREFIX; + assembler_type += type->GetMutf8(); + assembler_type += TYPE_DESC_DELIMITER; + return EtsString::CreateFromMUtf8(assembler_type.c_str()); +} } // namespace panda::ets::intrinsics diff --git a/plugins/ets/runtime/types/ets_reflect_field.h b/plugins/ets/runtime/types/ets_reflect_field.h deleted file mode 100644 index 193e9e17a..000000000 --- a/plugins/ets/runtime/types/ets_reflect_field.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ -#define PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ - -namespace panda::ets { - -#include "plugins/ets/runtime/types/ets_object.h" - -class EtsReflectField : public ObjectHeader { -public: - - EtsReflectField() = delete; - ~EtsReflectField() = delete; - - NO_COPY_SEMANTIC(EtsReflectField); - NO_MOVE_SEMANTIC(EtsReflectField); - - EtsObject *AsObject() - { - return EtsObject::FromCoreType(this); - } - - const EtsObject *AsObject() const - { - return EtsObject::FromCoreType(this); - } - - static EtsReflectField *FromEtsObject(EtsObject *field) - { - return reinterpret_cast(field); - } - - void SetTypeDescriptor(const char * type_desc) { - ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsReflectField, type_descriptor), EtsString::CreateFromMUtf8(type_desc)->AsObject()->GetCoreType()); - } - - void SetName(EtsString * name) { - ObjectAccessor::SetObject(this, MEMBER_OFFSET(EtsReflectField, name_), name->AsObject()->GetCoreType()); - } - - void SetAttributes(uint32_t attr) { - ObjectAccessor::SetPrimitive(this, MEMBER_OFFSET(EtsReflectField, attributes), attr); - } - -private: - ObjectPointer type_descriptor; - ObjectPointer name_; - FIELD_UNUSED uint32_t attributes; - -}; - -} // namespace panda::ets - -#endif // PANDA_PLUGINS_ETS_REFLECT_ETS_FIELD_H_ diff --git a/plugins/ets/stdlib/std/core/Field.ets b/plugins/ets/stdlib/std/core/Field.ets index 7b387d9bc..bb101b70d 100644 --- a/plugins/ets/stdlib/std/core/Field.ets +++ b/plugins/ets/stdlib/std/core/Field.ets @@ -1,4 +1,3 @@ -<<<<<<< HEAD /* * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,9 +18,8 @@ package std.core; export final class Field extends Object { private td: string private name: string - private accessMod: byte private attributes: int - + private accessMod: byte public getType(): Type { return Type.resolve(this.td) diff --git a/plugins/ets/stdlib/std/core/Type.ets b/plugins/ets/stdlib/std/core/Type.ets index 530bf810f..f7f888bea 100644 --- a/plugins/ets/stdlib/std/core/Type.ets +++ b/plugins/ets/stdlib/std/core/Type.ets @@ -47,6 +47,16 @@ native function TypeAPIMakeArrayInstance(td: TypeDesc, len: long): Object native function TypeAPIGetBaseType(td: TypeDesc): TypeDesc +native function StoreTypeParamDescriptors(typ: string[]): void + +native function LoadTypeParamDescriptors(): TypeDesc[] + +native function GetGenericTypeDesc(): TypeDesc + +export function GetGenericType(): Type { + return Type.resolve(GetGenericTypeDesc()) +} + // TODO(shumilov-petr): replace to enum, enum not available now export type TypeKind = byte @@ -1228,7 +1238,6 @@ export final class FunctionType extends Type { } } - export final class StringType extends Type { private static inst: StringType | null = null -- Gitee