diff --git a/binder/ETSBinder.cpp b/binder/ETSBinder.cpp index 4f836b128bf9433373161d64d8be62a9b4a62151..5e1d1bd50ae980c7500a63536883449734af97cf 100644 --- a/binder/ETSBinder.cpp +++ b/binder/ETSBinder.cpp @@ -83,11 +83,7 @@ void ETSBinder::LookupTypeArgumentReferences(ir::ETSTypeReference *typeRef) } for (auto *it : iter->TypeParams()->Params()) { - if (!it->IsETSTypeReference()) { - continue; - } - - ResolveReference(it); + ResolveReferences(it); } iter = iter->Previous(); diff --git a/checker/ets/helpers.cpp b/checker/ets/helpers.cpp index 9bdff68ab82632c0dbf7d65606b086efc3d7e3f8..b5845116dac32addfca0b1ebbe6117f30828d59b 100644 --- a/checker/ets/helpers.cpp +++ b/checker/ets/helpers.cpp @@ -509,7 +509,10 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(binder::Variable *var) return var->TsType(); } - auto *aliasedType = var->Declaration()->Node()->AsTSTypeAliasDeclaration()->TypeAnnotation()->GetType(this); + auto aliasTypeNode = var->Declaration()->Node()->AsTSTypeAliasDeclaration(); + TypeStackElement tse(this, aliasTypeNode, "Circular type alias reference", aliasTypeNode->Start()); + auto *aliasedType = aliasTypeNode->TypeAnnotation()->GetType(this); + var->SetTsType(aliasedType); return aliasedType; } diff --git a/compiler/core/ETSGen.cpp b/compiler/core/ETSGen.cpp index 8226e9740303bc6361dc73ee21633cecdff5e98f..378388d9f83cc6eae6a24bc09aa9ec84c1c3ea9b 100644 --- a/compiler/core/ETSGen.cpp +++ b/compiler/core/ETSGen.cpp @@ -37,6 +37,16 @@ namespace panda::es2panda::compiler { +void ETSGen::SetAccumulatorType(const checker::Type *type) +{ + SetVRegType(acc_, type); +} + +const checker::Type *ETSGen::GetAccumulatorType() const +{ + return GetVRegType(acc_); +} + const checker::ETSChecker *ETSGen::Checker() const { return Context()->Checker()->AsETSChecker(); @@ -58,48 +68,51 @@ VReg ETSGen::StoreException(const ir::AstNode *node) VReg exception = AllocReg(); Ra().Emit(node, exception); - acc_.SetType(Checker()->GlobalBuiltinExceptionType()); - exception.SetType(acc_.GetType()); + SetAccumulatorType(Checker()->GlobalBuiltinExceptionType()); + SetVRegType(exception, GetAccumulatorType()); return exception; } void ETSGen::StoreAccumulator(const ir::AstNode *node, VReg &vreg) { - if (acc_.GetType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + const auto *accType = GetAccumulatorType(); + if (accType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Ra().Emit(node, vreg); - } else if (acc_.GetType()->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + } else if (accType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vreg); } else { Ra().Emit(node, vreg); } - vreg.SetType(acc_.GetType()); + SetVRegType(vreg, accType); } void ETSGen::LoadAccumulator(const ir::AstNode *node, VReg vreg) { - if (vreg.GetType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + const auto *vregType = GetVRegType(vreg); + if (vregType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Ra().Emit(node, vreg); - } else if (vreg.GetType()->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + } else if (vregType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vreg); } else { Ra().Emit(node, vreg); } - acc_.SetType(vreg.GetType()); + SetAccumulatorType(vregType); } void ETSGen::MoveVreg(const ir::AstNode *node, VReg &vd, VReg vs) { - if (vs.GetType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + const auto *sourceType = GetVRegType(vs); + if (sourceType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Ra().Emit(node, vd, vs); - } else if (vs.GetType()->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + } else if (sourceType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Ra().Emit(node, vd, vs); } else { Ra().Emit(node, vd, vs); } - vd.SetType(vs.GetType()); + SetVRegType(vd, sourceType); } void ETSGen::LoadVar(const ir::AstNode *node, binder::Variable *var) @@ -120,7 +133,7 @@ void ETSGen::LoadVar(const ir::AstNode *node, binder::Variable *var) case ReferenceKind::STATIC_METHOD: case ReferenceKind::CLASS: case ReferenceKind::STATIC_CLASS: { - acc_.SetType(var->TsType()); + SetAccumulatorType(var->TsType()); break; } case ReferenceKind::LOCAL: { @@ -207,13 +220,13 @@ void ETSGen::LoadStaticProperty(const ir::AstNode *node, const checker::Type *pr Sa().Emit(node, fullName); } - acc_.SetType(propType); + SetAccumulatorType(propType); } void ETSGen::StoreProperty(const ir::AstNode *node, const checker::Type *propType, VReg objReg, const util::StringView &name) { - util::StringView fullName = FormClassPropReference(objReg.GetType()->AsETSObjectType(), name); + util::StringView fullName = FormClassPropReference(GetVRegType(objReg)->AsETSObjectType(), name); if (propType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Ra().Emit(node, objReg, fullName); @@ -227,7 +240,7 @@ void ETSGen::StoreProperty(const ir::AstNode *node, const checker::Type *propTyp void ETSGen::LoadProperty(const ir::AstNode *node, const checker::Type *propType, VReg objReg, const util::StringView &name) { - util::StringView fullName = FormClassPropReference(objReg.GetType()->AsETSObjectType(), name); + util::StringView fullName = FormClassPropReference(GetVRegType(objReg)->AsETSObjectType(), name); if (propType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Ra().Emit(node, objReg, fullName); @@ -237,7 +250,7 @@ void ETSGen::LoadProperty(const ir::AstNode *node, const checker::Type *propType Ra().Emit(node, objReg, fullName); } - acc_.SetType(propType); + SetAccumulatorType(propType); } void ETSGen::LoadThis(const ir::AstNode *node) @@ -270,9 +283,10 @@ void ETSGen::EmitReturnVoid(const ir::AstNode *node) void ETSGen::ReturnAcc(const ir::AstNode *node) { - if (acc_.GetType()->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { + const auto *accType = GetAccumulatorType(); + if (accType->HasTypeFlag(checker::TypeFlag::ETS_ARRAY_OR_OBJECT)) { Sa().Emit(node); - } else if (acc_.GetType()->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + } else if (accType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { Sa().Emit(node); } else { Sa().Emit(node); @@ -340,7 +354,7 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe auto typeKind = checker::ETSChecker::TypeKind(targetType); - auto sourceType = acc_.GetType(); + const auto *sourceType = GetAccumulatorType(); if (sourceType->IsETSObjectType() && sourceType->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::UNBOXABLE_TYPE) && @@ -377,45 +391,46 @@ void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targe void ETSGen::EmitUnboxingConversion(const ir::AstNode *node, const checker::Type *targetType, checker::TypeFlag typeKind) { + RegScope rs(this); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: { - Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_BOOLEAN_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_BOOLEAN_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::BYTE: { - Ra().Emit(node, Signatures::BUILTIN_BYTE_BYTE_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_BYTE_BYTE_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::CHAR: { - Ra().Emit(node, Signatures::BUILTIN_CHAR_CHAR_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_CHAR_CHAR_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::SHORT: { - Ra().Emit(node, Signatures::BUILTIN_SHORT_SHORT_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_SHORT_SHORT_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::INT: { - Ra().Emit(node, Signatures::BUILTIN_INT_INT_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_INT_INT_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::LONG: { - Ra().Emit(node, Signatures::BUILTIN_LONG_LONG_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_LONG_LONG_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::FLOAT: { - Ra().Emit(node, Signatures::BUILTIN_FLOAT_FLOAT_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_FLOAT_FLOAT_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::DOUBLE: { - Ra().Emit(node, Signatures::BUILTIN_DOUBLE_DOUBLE_VALUE, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_DOUBLE_DOUBLE_VALUE, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } default: { @@ -427,46 +442,47 @@ void ETSGen::EmitUnboxingConversion(const ir::AstNode *node, const checker::Type void ETSGen::EmitBoxingConversion(const ir::AstNode *node, const checker::Type *targetType, const checker::Type *sourceType) { + RegScope rs(this); auto sourceTypeKind = checker::ETSChecker::TypeKind(sourceType); switch (sourceTypeKind) { case checker::TypeFlag::ETS_BOOLEAN: { - Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::BYTE: { - Ra().Emit(node, Signatures::BUILTIN_BYTE_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_BYTE_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::CHAR: { - Ra().Emit(node, Signatures::BUILTIN_CHAR_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_CHAR_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::SHORT: { - Ra().Emit(node, Signatures::BUILTIN_SHORT_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_SHORT_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::INT: { - Ra().Emit(node, Signatures::BUILTIN_INT_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_INT_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::LONG: { - Ra().Emit(node, Signatures::BUILTIN_LONG_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_LONG_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::FLOAT: { - Ra().Emit(node, Signatures::BUILTIN_FLOAT_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_FLOAT_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } case checker::TypeFlag::DOUBLE: { - Ra().Emit(node, Signatures::BUILTIN_DOUBLE_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType); + Ra().Emit(node, Signatures::BUILTIN_DOUBLE_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType); break; } default: { @@ -487,7 +503,7 @@ void ETSGen::SwapBinaryOpArgs(const ir::AstNode *node, VReg &lhs) void ETSGen::CastToBoolean([[maybe_unused]] const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -516,12 +532,12 @@ void ETSGen::CastToBoolean([[maybe_unused]] const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } void ETSGen::CastToByte([[maybe_unused]] const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: { @@ -553,12 +569,12 @@ void ETSGen::CastToByte([[maybe_unused]] const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalByteType()); + SetAccumulatorType(Checker()->GlobalByteType()); } void ETSGen::CastToChar([[maybe_unused]] const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -591,12 +607,12 @@ void ETSGen::CastToChar([[maybe_unused]] const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalCharType()); + SetAccumulatorType(Checker()->GlobalCharType()); } void ETSGen::CastToShort([[maybe_unused]] const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -628,12 +644,12 @@ void ETSGen::CastToShort([[maybe_unused]] const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalShortType()); + SetAccumulatorType(Checker()->GlobalShortType()); } void ETSGen::CastToDouble(const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -659,12 +675,12 @@ void ETSGen::CastToDouble(const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalDoubleType()); + SetAccumulatorType(Checker()->GlobalDoubleType()); } void ETSGen::CastToFloat(const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -690,12 +706,12 @@ void ETSGen::CastToFloat(const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalFloatType()); + SetAccumulatorType(Checker()->GlobalFloatType()); } void ETSGen::CastToLong(const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -721,12 +737,12 @@ void ETSGen::CastToLong(const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalLongType()); + SetAccumulatorType(Checker()->GlobalLongType()); } void ETSGen::CastToInt(const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: @@ -752,7 +768,7 @@ void ETSGen::CastToInt(const ir::AstNode *node) } } - acc_.SetType(Checker()->GlobalIntType()); + SetAccumulatorType(Checker()->GlobalIntType()); } void ETSGen::ToBinaryResult(const ir::AstNode *node, Label *ifFalse) @@ -865,7 +881,7 @@ void ETSGen::Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs) } case lexer::TokenType::KEYW_INSTANCEOF: { SwapBinaryOpArgs(node, lhs); - IsInstance(node, lhs.GetType()->AsETSObjectType()->AssemblerName()); + IsInstance(node, GetVRegType(lhs)->AsETSObjectType()->AssemblerName()); break; } default: { @@ -905,9 +921,9 @@ void ETSGen::Condition(const ir::AstNode *node, lexer::TokenType op, VReg lhs, L } case lexer::TokenType::KEYW_INSTANCEOF: { SwapBinaryOpArgs(node, lhs); - Sa().Emit(node, lhs.GetType()->AsETSObjectType()->AssemblerName()); + Sa().Emit(node, GetVRegType(lhs)->AsETSObjectType()->AssemblerName()); BranchIfFalse(node, ifFalse); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); break; } default: { @@ -970,7 +986,7 @@ void ETSGen::CompileStatementList(const ArenaVector &statements void ETSGen::Negate(const ir::AstNode *node) { - auto typeKind = checker::ETSChecker::TypeKind(acc_.GetType()); + auto typeKind = checker::ETSChecker::TypeKind(GetAccumulatorType()); switch (typeKind) { case checker::TypeFlag::BYTE: @@ -1000,7 +1016,7 @@ void ETSGen::Negate(const ir::AstNode *node) void ETSGen::LogicalNot(const ir::AstNode *node) { - ASSERT(acc_.GetType()->IsETSBooleanType()); + ASSERT(GetAccumulatorType()->IsETSBooleanType()); Sa().Emit(node); Sa().Emit(node, 1); } @@ -1031,7 +1047,7 @@ void ETSGen::Unary(const ir::AstNode *node, lexer::TokenType op) void ETSGen::UnaryMinus(const ir::AstNode *node) { - switch (checker::ETSChecker::ETSType(acc_.GetType())) { + switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { case checker::TypeFlag::LONG: { Sa().Emit(node); break; @@ -1059,7 +1075,7 @@ void ETSGen::UnaryMinus(const ir::AstNode *node) void ETSGen::UnaryTilde(const ir::AstNode *node) { - switch (checker::ETSChecker::ETSType(acc_.GetType())) { + switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { case checker::TypeFlag::LONG: { Sa().Emit(node); break; @@ -1101,7 +1117,7 @@ void ETSGen::StringBuilderAppend(const ir::AstNode *node, VReg builder) node->Compile(this); - switch (checker::ETSChecker::ETSType(acc_.GetType())) { + switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { case checker::TypeFlag::ETS_BOOLEAN: { signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BOOLEAN; break; @@ -1134,14 +1150,15 @@ void ETSGen::StringBuilderAppend(const ir::AstNode *node, VReg builder) } } - if (acc_.GetType()->IsETSObjectType() && !acc_.GetType()->IsETSStringType()) { - Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, VReg::RegStart(), 0); + if (GetAccumulatorType()->IsETSObjectType() && !GetAccumulatorType()->IsETSStringType()) { + Ra().Emit(node, Signatures::BUILTIN_OBJECT_TO_STRING, DUMMY_REG, 0); } VReg arg0 = AllocReg(); StoreAccumulator(node, arg0); CallThisStatic1(node, builder, signature, arg0); + SetAccumulatorType(Checker()->GetGlobalTypesHolder()->GlobalStringBuilderBuiltinType()); } void ETSGen::AppendString(const ir::Expression *expr, VReg &builder) @@ -1172,16 +1189,17 @@ void ETSGen::StringBuilder(const ir::Expression *left, const ir::Expression *rig void ETSGen::BuildString(const ir::Expression *node) { RegScope rs(this); - VReg builder = AllocReg(); - Sa().Emit(node, Signatures::BUILTIN_STRING_BUILDER_CTOR, VReg::RegStart(), VReg::RegStart()); - acc_.SetType(Checker()->GlobalStringBuilderBuiltinType()); + Ra().Emit(node, Signatures::BUILTIN_STRING_BUILDER_CTOR, DUMMY_REG, DUMMY_REG); + SetAccumulatorType(Checker()->GlobalStringBuilderBuiltinType()); + + auto builder = AllocReg(); StoreAccumulator(node, builder); AppendString(node, builder); CallThisStatic0(node, builder, Signatures::BUILTIN_STRING_BUILDER_TO_STRING); - acc_.SetType(Checker()->GlobalETSStringLiteralType()); + SetAccumulatorType(Checker()->GlobalBuiltinETSStringType()); } void ETSGen::NewObject(const ir::AstNode *node, VReg &ctor, util::StringView name) @@ -1201,24 +1219,27 @@ void ETSGen::NewArray(const ir::AstNode *node, VReg &arr, VReg dim, const checke void ETSGen::LoadArrayLength(const ir::AstNode *node, VReg arrayReg) { Ra().Emit(node, arrayReg); - acc_.SetType(Checker()->GlobalIntType()); + SetAccumulatorType(Checker()->GlobalIntType()); } void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg objectReg) { - auto *elementType = objectReg.GetType()->AsETSArrayType()->ElementType(); + auto *elementType = GetVRegType(objectReg)->AsETSArrayType()->ElementType(); switch (checker::ETSChecker::ETSType(elementType)) { + case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: { Ra().Emit(node, objectReg); break; } - case checker::TypeFlag::CHAR: + case checker::TypeFlag::CHAR: { + Ra().Emit(node, objectReg); + break; + } case checker::TypeFlag::SHORT: { Ra().Emit(node, objectReg); break; } - case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::INT: { Ra().Emit(node, objectReg); break; @@ -1246,14 +1267,15 @@ void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg objectReg) } } - acc_.SetType(elementType); + SetAccumulatorType(elementType); } void ETSGen::StoreArrayElement(const ir::AstNode *node, VReg objectReg, VReg index) { - auto *elementType = objectReg.GetType()->AsETSArrayType()->ElementType(); + auto *elementType = GetVRegType(objectReg)->AsETSArrayType()->ElementType(); switch (checker::ETSChecker::ETSType(elementType)) { + case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::BYTE: { Ra().Emit(node, objectReg, index); break; @@ -1263,7 +1285,6 @@ void ETSGen::StoreArrayElement(const ir::AstNode *node, VReg objectReg, VReg ind Ra().Emit(node, objectReg, index); break; } - case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::INT: { Ra().Emit(node, objectReg, index); break; @@ -1291,7 +1312,7 @@ void ETSGen::StoreArrayElement(const ir::AstNode *node, VReg objectReg, VReg ind } } - acc_.SetType(elementType); + SetAccumulatorType(elementType); } void ETSGen::ThrowException(const ir::Expression *expr) diff --git a/compiler/core/ETSGen.h b/compiler/core/ETSGen.h index 43f72693fbfe0ddd3515a18f466dae967c4c8a15..a3e7cd24e88ee34237649c605ae341db84a5e2db 100644 --- a/compiler/core/ETSGen.h +++ b/compiler/core/ETSGen.h @@ -54,6 +54,9 @@ public: return acc_; } + void SetAccumulatorType(const checker::Type *type); + const checker::Type *GetAccumulatorType() const; + VReg StoreException(const ir::AstNode *node); void ApplyConversionAndStoreAccumulator(const ir::AstNode *node, VReg &vreg, const checker::Type *targetType); void StoreAccumulator(const ir::AstNode *node, VReg &vreg); @@ -84,7 +87,7 @@ public: void IsInstance(const ir::AstNode *node, util::StringView name) { Sa().Emit(node, name); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } void Binary(const ir::AstNode *node, lexer::TokenType op, VReg lhs); @@ -153,23 +156,23 @@ public: Sa().Emit(node, value ? 1 : 0); if (typeKind == checker::TypeFlag::ETS_OBJECT && targetType_->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN)) { - Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType_); + Ra().Emit(node, Signatures::BUILTIN_BOOLEAN_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType_); } else { - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } } void LoadAccumulatorString(const ir::AstNode *node, util::StringView str) { Sa().Emit(node, str); - acc_.SetType(Checker()->GlobalETSStringLiteralType()); + SetAccumulatorType(Checker()->GlobalETSStringLiteralType()); } void LoadAccumulatorNull(const ir::AstNode *node, const checker::Type *type) { Sa().Emit(node); - acc_.SetType(type); + SetAccumulatorType(type); } void LoadAccumulatorChar(const ir::AstNode *node, char16_t value) @@ -178,10 +181,10 @@ public: Sa().Emit(node, value); if (typeKind == checker::TypeFlag::ETS_OBJECT && targetType_->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_CHAR)) { - Ra().Emit(node, Signatures::BUILTIN_CHAR_VALUE_OF, VReg::RegStart(), 0); - acc_.SetType(targetType_); + Ra().Emit(node, Signatures::BUILTIN_CHAR_VALUE_OF, DUMMY_REG, 0); + SetAccumulatorType(targetType_); } else { - acc_.SetType(Checker()->GlobalCharType()); + SetAccumulatorType(Checker()->GlobalCharType()); } } @@ -243,7 +246,7 @@ public: void CallThisStatic0(const ir::AstNode *node, VReg &ctor, util::StringView name) { - Ra().Emit(node, name, ctor, VReg::RegStart()); + Ra().Emit(node, name, ctor, DUMMY_REG); } void CallThisStatic1(const ir::AstNode *node, VReg &ctor, util::StringView name, VReg &arg0) @@ -253,7 +256,7 @@ public: void CallThisStatic2(const ir::AstNode *node, VReg &ctor, util::StringView name, VReg &arg0, VReg &arg1) { - Ra().Emit(node, name, ctor, arg0, arg1, VReg::RegStart()); + Ra().Emit(node, name, ctor, arg0, arg1, DUMMY_REG); } void GetType(const ir::AstNode *node, bool isETSPrimitive) @@ -261,7 +264,7 @@ public: if (isETSPrimitive) { // TODO(SzD) LoadStaticProperty if ETS stdlib has static TYPE constants otherwise fallback to LdaType } else { - auto classRef = acc_.GetType()->AsETSObjectType()->AssemblerName(); + auto classRef = GetAccumulatorType()->AsETSObjectType()->AssemblerName(); Sa().Emit(node, classRef); } } @@ -271,6 +274,8 @@ public: NO_MOVE_SEMANTIC(ETSGen); private: + const VReg DUMMY_REG = VReg::RegStart(); + void StringBuilderAppend(const ir::AstNode *node, VReg builder); void AppendString(const ir::Expression *binExpr, VReg &builder); void StringBuilder(const ir::Expression *left, const ir::Expression *right, VReg &builder); @@ -289,7 +294,7 @@ private: template void UpdateOperator(const ir::AstNode *node) { - switch (checker::ETSChecker::ETSType(acc_.GetType())) { + switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { case checker::TypeFlag::LONG: { RegScope scope(this); VReg reg = AllocReg(); @@ -342,7 +347,7 @@ private: { BinaryEqualityCondition(node, lhs, ifFalse); ToBinaryResult(node, ifFalse); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } template @@ -352,13 +357,13 @@ private: switch (typeKind) { case checker::TypeFlag::ETS_OBJECT: { - ASSERT(lhs.GetType()->IsETSObjectType()); - if (lhs.GetType()->IsETSStringType()) { + ASSERT(GetVRegType(lhs)->IsETSObjectType()); + if (GetVRegType(lhs)->IsETSStringType()) { RegScope rs(this); VReg arg0 = AllocReg(); StoreAccumulator(node, arg0); CallThisStatic1(node, lhs, Signatures::BUILTIN_STRING_EQUALS, arg0); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); if constexpr (std::is_same_v) { LogicalNot(node); } @@ -395,7 +400,7 @@ private: } } - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } template @@ -403,7 +408,7 @@ private: { BinaryRelationCondition(node, lhs, ifFalse); ToBinaryResult(node, ifFalse); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } template @@ -436,7 +441,7 @@ private: } } - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); } template @@ -447,12 +452,12 @@ private: switch (typeKind) { case checker::TypeFlag::DOUBLE: { Ra().Emit(node, lhs); - acc_.SetType(Checker()->GlobalDoubleType()); + SetAccumulatorType(Checker()->GlobalDoubleType()); break; } case checker::TypeFlag::FLOAT: { Ra().Emit(node, lhs); - acc_.SetType(Checker()->GlobalFloatType()); + SetAccumulatorType(Checker()->GlobalFloatType()); break; } default: { @@ -469,19 +474,19 @@ private: switch (typeKind) { case checker::TypeFlag::LONG: { Ra().Emit(node, lhs); - acc_.SetType(Checker()->GlobalLongType()); + SetAccumulatorType(Checker()->GlobalLongType()); break; } case checker::TypeFlag::BYTE: case checker::TypeFlag::SHORT: case checker::TypeFlag::INT: { Ra().Emit(node, lhs); - acc_.SetType(Checker()->GlobalIntType()); + SetAccumulatorType(Checker()->GlobalIntType()); break; } case checker::TypeFlag::ETS_BOOLEAN: { Ra().Emit(node, lhs); - acc_.SetType(Checker()->GlobalETSBooleanType()); + SetAccumulatorType(Checker()->GlobalETSBooleanType()); break; } default: { @@ -503,11 +508,11 @@ private: const ArenaVector &arguments) { RegScope rs(this); - util::StringView name = signature->InternalName(); + const auto name = signature->InternalName(); switch (arguments.size()) { case 0: { - Ra().Emit(node, name, ctor, VReg::RegStart()); + Ra().Emit(node, name, ctor, DUMMY_REG); break; } case 1: { @@ -518,7 +523,7 @@ private: case 2: { COMPILE_ARG(0); COMPILE_ARG(1); - Ra().Emit(node, name, ctor, arg0, arg1, VReg::RegStart()); + Ra().Emit(node, name, ctor, arg0, arg1, DUMMY_REG); break; } case 3: { @@ -547,16 +552,16 @@ private: const ArenaVector &arguments) { RegScope rs(this); - util::StringView name = signature->InternalName(); + const auto name = signature->InternalName(); switch (arguments.size()) { case 0: { - Ra().Emit(node, name, VReg::RegStart(), VReg::RegStart()); + Ra().Emit(node, name, DUMMY_REG, DUMMY_REG); break; } case 1: { COMPILE_ARG(0); - Ra().Emit(node, name, arg0, VReg::RegStart()); + Ra().Emit(node, name, arg0, DUMMY_REG); break; } case 2: { @@ -569,7 +574,7 @@ private: COMPILE_ARG(0); COMPILE_ARG(1); COMPILE_ARG(2); - Ra().Emit(node, name, arg0, arg1, arg2, VReg::RegStart()); + Ra().Emit(node, name, arg0, arg1, arg2, DUMMY_REG); break; } case 4: { @@ -621,37 +626,37 @@ void ETSGen::LoadAccumulatorNumber(const ir::AstNode *node, T number, checker::T switch (typeKind) { case checker::TypeFlag::BYTE: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalByteType()); + SetAccumulatorType(Checker()->GlobalByteType()); break; } case checker::TypeFlag::CHAR: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalCharType()); + SetAccumulatorType(Checker()->GlobalCharType()); break; } case checker::TypeFlag::SHORT: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalShortType()); + SetAccumulatorType(Checker()->GlobalShortType()); break; } case checker::TypeFlag::INT: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalIntType()); + SetAccumulatorType(Checker()->GlobalIntType()); break; } case checker::TypeFlag::LONG: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalLongType()); + SetAccumulatorType(Checker()->GlobalLongType()); break; } case checker::TypeFlag::FLOAT: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalFloatType()); + SetAccumulatorType(Checker()->GlobalFloatType()); break; } case checker::TypeFlag::DOUBLE: { Sa().Emit(node, static_cast(number)); - acc_.SetType(Checker()->GlobalDoubleType()); + SetAccumulatorType(Checker()->GlobalDoubleType()); break; } default: { @@ -661,7 +666,7 @@ void ETSGen::LoadAccumulatorNumber(const ir::AstNode *node, T number, checker::T if (targetType_ && targetType_->IsETSObjectType()) { ApplyConversion(node, targetType_); - acc_.SetType(targetType_); + SetAccumulatorType(targetType_); } } diff --git a/compiler/core/codeGen.h b/compiler/core/codeGen.h index e56b67fe10b4b799ba65e7ea894285bb7219b2ee..e3dec74dbe3aa04f2af52185e3a2da219a5ceba4 100644 --- a/compiler/core/codeGen.h +++ b/compiler/core/codeGen.h @@ -67,6 +67,8 @@ private: class CodeGen { public: + using TypeMap = ArenaUnorderedMap; + explicit CodeGen(ArenaAllocator *allocator, RegSpiller *spiller, CompilerContext *context, binder::FunctionScope *scope, ProgramElement *programElement) : allocator_(allocator), @@ -77,6 +79,7 @@ public: rootNode_(scope->Node()), insns_(allocator_->Adapter()), catchList_(allocator_->Adapter()), + typeMap_(allocator_->Adapter()), programElement_(programElement), sa_(this), ra_(this, spiller), @@ -112,12 +115,12 @@ public: return rootNode_; } - ArenaList &Insns() + ArenaVector &Insns() { return insns_; } - const ArenaList &Insns() const + const ArenaVector &Insns() const { return insns_; } @@ -129,7 +132,9 @@ public: VReg AllocReg(const checker::Type *type) { - return VReg(usedRegs_--, type); + VReg vreg(usedRegs_--); + SetVRegType(vreg, type); + return vreg; } VReg NextReg() const @@ -191,6 +196,17 @@ public: throw Error(ErrorType::GENERIC, "", "Unimplemented code path"); } + void SetVRegType(VReg vreg, const checker::Type *type) + { + typeMap_.insert_or_assign(vreg.GetIndex(), type); + } + + const checker::Type *GetVRegType(VReg vreg) const + { + const auto it = typeMap_.find(vreg.GetIndex()); + return it != typeMap_.end() ? it->second : nullptr; + } + protected: SimpleAllocator &Sa() { @@ -232,6 +248,16 @@ protected: return programElement_; } + TypeMap &GetTypeMap() + { + return typeMap_; + } + + const TypeMap &GetTypeMap() const + { + return typeMap_; + } + private: ArenaAllocator *allocator_; CompilerContext *context_; @@ -239,8 +265,9 @@ private: binder::FunctionScope *topScope_; binder::Scope *scope_; const ir::AstNode *rootNode_; - ArenaList insns_; + ArenaVector insns_; ArenaVector catchList_; + TypeMap typeMap_; ProgramElement *programElement_; DynamicContext *dynamicContext_ {}; diff --git a/compiler/core/regAllocator.cpp b/compiler/core/regAllocator.cpp index e95c6c7d48447dcd5cfc0fa0d236b3f10bc5987f..1e0beff71fb4992d4744d164a8a2c6bbe23124a7 100644 --- a/compiler/core/regAllocator.cpp +++ b/compiler/core/regAllocator.cpp @@ -40,30 +40,23 @@ Label *SimpleAllocator::AllocLabel(std::string &&id) return Alloc