diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 0a418ecf30dc060364de4119a4223cc3b877f2b1..23d2dad9186457dd90b7bb544233e8545b1d4a08 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -205,7 +205,6 @@ libes2panda_sources = [ "compiler/lowering/ets/arrayLiteralLowering.cpp", "compiler/lowering/ets/asyncMethodLowering.cpp", "compiler/lowering/ets/bigintLowering.cpp", - "compiler/lowering/ets/boxedTypeLowering.cpp", "compiler/lowering/ets/boxingForLocals.cpp", "compiler/lowering/ets/capturedVariables.cpp", "compiler/lowering/ets/cfgBuilderPhase.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 0335a6f30b74cc93f53a73944890a15e6ac49790..52a1bb8dcc8a6df39dd29caf3369b1427cec49bf 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -273,7 +273,6 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/extensionAccessorLowering.cpp compiler/lowering/ets/genericBridgesLowering.cpp compiler/lowering/ets/arrayLiteralLowering.cpp - compiler/lowering/ets/boxedTypeLowering.cpp compiler/lowering/ets/boxingForLocals.cpp compiler/lowering/ets/capturedVariables.cpp compiler/lowering/ets/cfgBuilderPhase.cpp diff --git a/ets2panda/ast_verifier/helpers.cpp b/ets2panda/ast_verifier/helpers.cpp index 13d55e496cb3a1ff72fa56415462b0b8b08664a9..d8a9998848ce9a4f5d6124d41c6587f385abb866 100644 --- a/ets2panda/ast_verifier/helpers.cpp +++ b/ets2panda/ast_verifier/helpers.cpp @@ -55,8 +55,7 @@ bool IsBooleanType(const ir::AstNode *ast) return false; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); } @@ -89,8 +88,7 @@ bool IsValidTypeForBinaryOp(const ir::AstNode *ast, bool isBitwise) return true; } - if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT) && - ast->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { + if (typedAst->TsType()->HasTypeFlag(checker::TypeFlag::ETS_OBJECT)) { return typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_TYPE) && !typedAst->TsType()->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::BUILTIN_BOOLEAN); } diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index ebd8d729fcf86da261bea482c228a247857062b2..9a57cf555d92cc1998eadda66f1c06d8f7370b9b 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2811,9 +2811,7 @@ checker::Type *ETSAnalyzer::Check(ir::SwitchStatement *st) const auto *comparedExprType = checker->CheckSwitchDiscriminant(st->Discriminant()); // may have no meaning to unbox comparedExprType - auto unboxedDiscType = (st->Discriminant()->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U - ? checker->MaybeUnboxInRelation(comparedExprType) - : comparedExprType; + auto unboxedDiscType = checker->MaybeUnboxType(comparedExprType); SmartCastArray smartCasts = checker->Context().CloneSmartCasts(); bool hasDefaultCase = false; diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 80480b78372dc933c6d2652f0dbe99143d9bda66..5c71f739627fbade90bbf2a47965b98c57c5a6b3 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -392,9 +392,8 @@ public: bool AdjustNumberLiteralType(ir::NumberLiteral *literal, Type *literalType, Type *otherType); Type *HandleArithmeticOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); - void SetUnboxingFlagsForBinaryExpression(std::tuple types, - std::tuple nodes, bool isBoxed); - void FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression); + void SetGenerateValueOfFlags(std::tuple types, + std::tuple nodes); template Type *PerformRelationOperationOnTypes(Type *left, Type *right, lexer::TokenType operationType); @@ -597,8 +596,7 @@ public: bool HandleLogicalPotentialResult(ir::Expression *left, ir::Expression *right, ir::BinaryExpression *expr, checker::Type *leftType); - checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags, - ir::Expression *init); + checker::Type *FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags); void CheckEnumType(ir::Expression *init, checker::Type *initType, const util::StringView &varName); checker::Type *CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, ir::ModifierFlags flags); @@ -630,11 +628,7 @@ public: Type *MaybeUnboxInRelation(Type *objectType); Type *MaybeUnboxConditionalInRelation(Type *objectType); Type *MaybeBoxInRelation(Type *objectType); - void AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType); - ir::BoxingUnboxingFlags GetBoxingFlag(Type *boxingType); - ir::BoxingUnboxingFlags GetUnboxingFlag(Type const *unboxingType) const; Type *MaybeBoxExpression(ir::Expression *expr); - Type *MaybeUnboxExpression(ir::Expression *expr); Type *MaybeBoxType(Type *type) const; Type *MaybeUnboxType(Type *type) const; Type const *MaybeBoxType(Type const *type) const; @@ -656,8 +650,6 @@ public: bool IsSameDeclarationType(varbinder::LocalVariable *target, varbinder::LocalVariable *compare); void SaveCapturedVariable(varbinder::Variable *var, ir::Identifier *ident); bool SaveCapturedVariableInLocalClass(varbinder::Variable *var, ir::Identifier *ident); - void MaybeAddBoxingFlagInRelation(TypeRelation *relation, Type *target); - void MaybeAddUnboxingFlagInRelation(TypeRelation *relation, Type *source, Type *self); void CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self); void CheckUnboxedTypesAssignable(TypeRelation *relation, Type *source, Type *target); void CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target); diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 4cdfc01c8aa6bc0bdc1edf7ec5010ff132195152..03f6ff04bd01765fe483b3d8b8350422143cb121 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -235,17 +235,16 @@ bool ETSChecker::CheckBinaryPlusMultDivOperandsForUnionType(const Type *leftType return true; } -void ETSChecker::SetUnboxingFlagsForBinaryExpression(std::tuple types, - std::tuple nodes, bool isBoxed) +void ETSChecker::SetGenerateValueOfFlags(std::tuple types, + std::tuple nodes) { - auto [leftType, rightType, unboxedL, unboxedR] = types; + auto [leftType, rightType, _, __] = types; auto [left, right] = nodes; - if (isBoxed) { - FlagExpressionWithUnboxing(leftType, nullptr, left); - FlagExpressionWithUnboxing(rightType, nullptr, right); - } else { - FlagExpressionWithUnboxing(leftType, unboxedL, left); - FlagExpressionWithUnboxing(rightType, unboxedR, right); + if (leftType->IsETSEnumType()) { + left->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); + } + if (rightType->IsETSEnumType()) { + right->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); } } @@ -486,7 +485,7 @@ checker::Type *ETSChecker::CheckBinaryOperatorBitwise( LogError(diagnostic::OP_NONNUMERIC, {}, pos); return GlobalTypeError(); } - SetUnboxingFlagsForBinaryExpression(types, {left, right}, promotedType->IsETSUnboxableObject()); + SetGenerateValueOfFlags(types, {left, right}); auto isPrim = promotedType->IsETSPrimitiveType(); auto unboxedProm = MaybeUnboxType(promotedType); @@ -537,8 +536,7 @@ checker::Type *ETSChecker::CheckBinaryOperatorLogical(ir::Expression *left, ir:: if (unboxedL != nullptr && unboxedL->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC) && unboxedR != nullptr && unboxedR->HasTypeFlag(TypeFlag::ETS_CONVERTIBLE_TO_NUMERIC)) { - SetUnboxingFlagsForBinaryExpression({leftType, rightType, unboxedL, unboxedR}, {left, right}, - (leftType->IsETSUnboxableObject() || rightType->IsETSUnboxableObject())); + SetGenerateValueOfFlags({leftType, rightType, unboxedL, unboxedR}, {left, right}); return EffectiveTypeOfNumericOp(this, leftType, rightType); } @@ -835,10 +833,8 @@ bool ETSChecker::AdjustNumberLiteralType(ir::NumberLiteral *const literal, Type if (otherType->IsETSObjectType() && !otherType->IsETSEnumType()) { auto *const objectType = otherType->AsETSObjectType(); if (objectType->HasObjectFlag(ETSObjectFlags::BUILTIN_TYPE) && !objectType->IsETSStringType()) { - literal->RemoveBoxingUnboxingFlags(GetBoxingFlag(literalType)); literalType = MaybeUnboxInRelation(objectType); literal->SetTsType(literalType); - literal->AddBoxingUnboxingFlags(GetBoxingFlag(literalType)); return true; } } @@ -1063,7 +1059,6 @@ std::tuple ETSChecker::CheckArithmeticOperations( } if (tsType->IsETSPrimitiveType()) { tsType = MaybeBoxType(tsType); - expr->AddBoxingUnboxingFlags(GetBoxingFlag(tsType)); } return {tsType, tsType}; } @@ -1135,15 +1130,4 @@ std::tuple ETSChecker::CheckBinaryOperator(ir::Expression *left, std::make_tuple(leftType, rightType, unboxedL, unboxedR)); } -void ETSChecker::FlagExpressionWithUnboxing(Type *type, Type *unboxedType, ir::Expression *typeExpression) -{ - if (type->IsETSEnumType()) { - typeExpression->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); - return; - } - if (type->IsETSObjectType() && (unboxedType != nullptr)) { - typeExpression->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxedType)); - } -} - } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/ets/conversion.cpp b/ets2panda/checker/ets/conversion.cpp index e165cb0e9a3491fecc9d078e62921ba3bce4567f..fa7c78efe346b03ec753dbf4d4856cf9bc27cbb7 100644 --- a/ets2panda/checker/ets/conversion.cpp +++ b/ets2panda/checker/ets/conversion.cpp @@ -253,13 +253,6 @@ void NarrowingReference(TypeRelation *const relation, ETSObjectType *const sourc NarrowingReferenceImpl(relation, source, target); } -static inline void RollbackBoxingIfFailed(TypeRelation *const relation) -{ - if (!relation->IsTrue()) { - relation->GetNode()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); - } -} - ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) { auto *const etsChecker = relation->GetChecker()->AsETSChecker(); @@ -268,7 +261,6 @@ ETSObjectType *Boxing(TypeRelation *const relation, Type *const source) return nullptr; } auto *const boxedType = boxed.Result()->AsETSObjectType(); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetBoxingFlag(boxedType)); return boxedType; } @@ -280,7 +272,6 @@ Type *Unboxing(TypeRelation *const relation, ETSObjectType *const source) return nullptr; } auto *const unboxedType = unboxed.Result(); - relation->GetNode()->AddBoxingUnboxingFlags(etsChecker->GetUnboxingFlag(unboxedType)); return unboxedType; } @@ -292,7 +283,6 @@ void UnboxingWideningPrimitive(TypeRelation *const relation, ETSObjectType *cons } ES2PANDA_ASSERT(unboxedSource != nullptr); WideningPrimitive(relation, target, unboxedSource); - RollbackBoxingIfFailed(relation); } void UnboxingNarrowingPrimitive(TypeRelation *const relation, ETSObjectType *const source, Type *const target) @@ -337,7 +327,6 @@ void BoxingWideningReference(TypeRelation *const relation, Type *const source, E } ES2PANDA_ASSERT(boxedSource != nullptr); WideningReference(relation, boxedSource, target); - RollbackBoxingIfFailed(relation); } void String(TypeRelation *const relation, Type *const source) diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.cpp b/ets2panda/checker/ets/etsWarningAnalyzer.cpp index 3a395fe53dfba5e5adf660ae01617a86c91343c4..20d4093631446c412aedca8f11859d36e4800f98 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.cpp +++ b/ets2panda/checker/ets/etsWarningAnalyzer.cpp @@ -34,8 +34,6 @@ #include "ir/base/classDefinition.h" #include "ir/statements/forOfStatement.h" #include "ir/statements/variableDeclarator.h" -#include "ir/statements/variableDeclaration.h" -#include "ir/expressions/updateExpression.h" namespace ark::es2panda::checker { @@ -270,157 +268,6 @@ void ETSWarningAnalyzer::ETSWarningRemoveLambda(const ir::AstNode *node) node->Iterate([&](auto *childNode) { ETSWarningRemoveLambda(childNode); }); } -void ETSWarningAnalyzer::CheckTypeOfBoxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - const auto flags = node->GetBoxingUnboxingFlags(); - if ((flags & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0) { - std::string diagnosticParam; - switch (static_cast(flags & ir::BoxingUnboxingFlags::BOXING_FLAG)) { - case ir::BoxingUnboxingFlags::BOX_TO_INT: - diagnosticParam = "Int"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN: - diagnosticParam = "Boolean"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_BYTE: - diagnosticParam = "Byte"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_CHAR: - diagnosticParam = "Char"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: - diagnosticParam = "Double"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_FLOAT: - diagnosticParam = "Float"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_LONG: - diagnosticParam = "Long"; - break; - case ir::BoxingUnboxingFlags::BOX_TO_SHORT: - diagnosticParam = "Short"; - break; - default: - break; - } - - if (!diagnosticParam.empty()) { - util::DiagnosticMessageParams diagnosticParams = {diagnosticParam, GetBoxingUnboxingType(node)}; - LogWarning(diagnostic::IMPLICIT_BOXING_TO, diagnosticParams, node->Start()); - } - } -} - -void ETSWarningAnalyzer::CheckTypeOfUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - const auto flags = node->GetBoxingUnboxingFlags(); - if ((flags & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0) { - std::string diagnosticParam; - switch (static_cast(flags & ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - case ir::BoxingUnboxingFlags::UNBOX_TO_INT: - diagnosticParam = "Int"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN: - diagnosticParam = "Boolean"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_BYTE: - diagnosticParam = "Byte"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_CHAR: - diagnosticParam = "Char"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE: - diagnosticParam = "Double"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT: - diagnosticParam = "Float"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_LONG: - diagnosticParam = "Long"; - break; - case ir::BoxingUnboxingFlags::UNBOX_TO_SHORT: - diagnosticParam = "Short"; - break; - default: - break; - } - - if (!diagnosticParam.empty()) { - util::DiagnosticMessageParams diagnosticParams = {diagnosticParam, GetBoxingUnboxingType(node)}; - LogWarning(diagnostic::IMPLICIT_BOXING_TO, diagnosticParams, node->Start()); - } - } -} - -void ETSWarningAnalyzer::CheckTypeOfBoxingUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - - CheckTypeOfBoxing(node); - CheckTypeOfUnboxing(node); -} - -std::string ETSWarningAnalyzer::GetBoxingUnboxingType(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node->Parent() != nullptr); - switch (node->Parent()->Type()) { - case ir::AstNodeType::VARIABLE_DECLARATOR: { - return " in Variable Declaration"; - } - case ir::AstNodeType::CALL_EXPRESSION: { - return " in Call Method/Function"; - } - case ir::AstNodeType::SWITCH_STATEMENT: { - return " in Switch-case Statement"; - } - case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { - return " in Assignment Expression"; - } - case ir::AstNodeType::BINARY_EXPRESSION: { - return " in Binary Expression"; - } - case ir::AstNodeType::UNARY_EXPRESSION: { - return " in Unary Expression"; - } - case ir::AstNodeType::UPDATE_EXPRESSION: { - return " in Update Expression"; - } - case ir::AstNodeType::MEMBER_EXPRESSION: { - return " in Member Expression"; - } - default: - return ""; - } -} - -void ETSWarningAnalyzer::ETSWarningImplicitBoxingUnboxing(const ir::AstNode *node) -{ - ES2PANDA_ASSERT(node != nullptr); - - switch (node->Type()) { - case ir::AstNodeType::VARIABLE_DECLARATOR: - case ir::AstNodeType::SWITCH_STATEMENT: - case ir::AstNodeType::CALL_EXPRESSION: - case ir::AstNodeType::BINARY_EXPRESSION: - case ir::AstNodeType::ASSIGNMENT_EXPRESSION: - case ir::AstNodeType::UNARY_EXPRESSION: - case ir::AstNodeType::UPDATE_EXPRESSION: - case ir::AstNodeType::MEMBER_EXPRESSION: { - if (!program_->NodeContainsETSNolint(node, ETSWarnings::ETS_IMPLICIT_BOXING_UNBOXING)) { - node->Iterate([this](auto *childNode) { CheckTypeOfBoxingUnboxing(childNode); }); - } - break; - } - default: { - break; - } - } - - node->Iterate([&](auto *childNode) { ETSWarningImplicitBoxingUnboxing(childNode); }); -} - void ETSWarningAnalyzer::LogWarning(const std::string &message, const lexer::SourcePosition &position) { diagnosticEngine_.LogWarning(message, position); diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.h b/ets2panda/checker/ets/etsWarningAnalyzer.h index 13f1a0b80b8ea1e650a09e207716b06e2ecdefa2..c0a5ab95d73e430f64a7276ae6d32d81f6f07e85 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.h +++ b/ets2panda/checker/ets/etsWarningAnalyzer.h @@ -48,9 +48,6 @@ public: case ETSWarnings::ETS_REMOVE_LAMBDA: ETSWarningRemoveLambda(node); break; - case ETSWarnings::ETS_IMPLICIT_BOXING_UNBOXING: - ETSWarningImplicitBoxingUnboxing(node); - break; default: break; } @@ -64,12 +61,8 @@ private: void AnalyzeClassDefForFinalModifier(const ir::ClassDefinition *classDef); void AnalyzeClassMethodForFinalModifier(const ir::MethodDefinition *methodDef, const ir::ClassDefinition *classDef); - void CheckTypeOfBoxing(const ir::AstNode *node); - void CheckTypeOfUnboxing(const ir::AstNode *node); void CheckTopLevelExpressions(const ir::Expression *expression); void CheckProhibitedTopLevelStatements(const ir::Statement *statement); - std::string GetBoxingUnboxingType(const ir::AstNode *node); - void CheckTypeOfBoxingUnboxing(const ir::AstNode *node); void ETSWarningAnnotationUnusedGenericAliasWarn(const ir::AstNode *node); void ETSWarningSuggestFinal(const ir::AstNode *node); @@ -77,7 +70,6 @@ private: void ETSWarningBoostEqualityStatement(const ir::AstNode *node); void ETSWarningRemoveAsync(const ir::AstNode *node); void ETSWarningRemoveLambda(const ir::AstNode *node); - void ETSWarningImplicitBoxingUnboxing(const ir::AstNode *node); parser::Program *program_; util::DiagnosticEngine &diagnosticEngine_; diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index e03cd9c579026065bb1be05166c9de519dec78b4..8a55537f4b0c54cb61a966b0c52c3b11a274ab40 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -508,8 +508,6 @@ void ETSChecker::ResolveReturnStatement(checker::Type *funcReturnType, checker:: argumentType = MaybeBoxInRelation(argumentType); if (argumentType == nullptr) { LogError(diagnostic::INVALID_EXPR_IN_RETURN, {}, st->Argument()->Start()); - } else { - st->Argument()->AddBoxingUnboxingFlags(GetBoxingFlag(argumentType)); } } @@ -609,15 +607,12 @@ void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Arr } } -checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags, - ir::Expression *init) +checker::Type *ETSChecker::FixOptionalVariableType(varbinder::Variable *const bindingVar, ir::ModifierFlags flags) { if ((flags & ir::ModifierFlags::OPTIONAL) != 0) { - if (init != nullptr && bindingVar->TsType()->IsETSPrimitiveType()) { - init->SetBoxingUnboxingFlags(GetBoxingFlag(bindingVar->TsType())); - } auto *variableType = bindingVar->TsType() != nullptr ? bindingVar->TsType() : GlobalTypeError(); - bindingVar->SetTsType(CreateETSUnionType({GlobalETSUndefinedType(), variableType})); + bindingVar->SetTsType( + !variableType->IsTypeError() ? CreateETSUnionType({GlobalETSUndefinedType(), variableType}) : variableType); } return bindingVar->TsType(); } @@ -815,7 +810,7 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T } if (init == nullptr) { - return FixOptionalVariableType(bindingVar, flags, init); + return FixOptionalVariableType(bindingVar, flags); } CheckAssignForDeclare(ident, typeAnnotation, init, flags, this); } else { @@ -865,7 +860,7 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T bindingVar->SetTsType(needWidening ? GetNonConstantType(initType) : initType); } - return FixOptionalVariableType(bindingVar, flags, init); + return FixOptionalVariableType(bindingVar, flags); } void ETSChecker::VariableTypeFromInitializer(varbinder::Variable *variable, Type *annotationType, Type *initType) @@ -1992,8 +1987,8 @@ varbinder::VariableFlags ETSChecker::GetAccessFlagFromNode(const ir::AstNode *no Type *ETSChecker::CheckSwitchDiscriminant(ir::Expression *discriminant) { - discriminant->Check(this); - auto *discriminantType = GetNonConstantType(MaybeUnboxExpression(discriminant)); + Type *discriminantType = discriminant->Check(this); + discriminantType = GetNonConstantType(MaybeUnboxType(discriminantType)); if (!discriminantType->HasTypeFlag(TypeFlag::VALID_SWITCH_TYPE)) { if (!(discriminantType->IsETSObjectType() && discriminantType->AsETSObjectType()->HasObjectFlag( @@ -2005,33 +2000,12 @@ Type *ETSChecker::CheckSwitchDiscriminant(ir::Expression *discriminant) return discriminantType; } -void ETSChecker::AddBoxingUnboxingFlagsToNode(ir::AstNode *node, Type *boxingUnboxingType) -{ - if (boxingUnboxingType->IsETSObjectType()) { - node->AddBoxingUnboxingFlags(GetBoxingFlag(boxingUnboxingType)); - } else if (!boxingUnboxingType->IsETSUnionType()) { - node->AddBoxingUnboxingFlags(GetUnboxingFlag(boxingUnboxingType)); - } -} - Type *ETSChecker::MaybeBoxExpression(ir::Expression *expr) { auto *promoted = MaybeBoxType(expr->TsType()); - if (promoted != expr->TsType()) { - expr->AddBoxingUnboxingFlags(GetBoxingFlag(promoted)); - } return promoted; } -Type *ETSChecker::MaybeUnboxExpression(ir::Expression *expr) -{ - auto *primitive = MaybeUnboxType(expr->TsType()); - if (primitive != expr->TsType()) { - expr->AddBoxingUnboxingFlags(GetUnboxingFlag(primitive)); - } - return primitive; -} - void ETSChecker::CheckForSameSwitchCases(ArenaVector const &cases) { CheckItemCasesConstant(cases); diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 4335a0d6a11396ad2c4129b15b40bc5f8b4c5d1a..2284bdad45ce0bad36ffac6784d12f64b7cc0365 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -64,10 +64,6 @@ void ETSChecker::CheckTruthinessOfType(ir::Expression *expr) return; } - if (conditionType->IsETSPrimitiveType()) { - FlagExpressionWithUnboxing(testType, conditionType, expr); - } - // For T_S compatibility if (conditionType->IsETSEnumType()) { expr->AddAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF); @@ -1262,74 +1258,6 @@ Type const *ETSChecker::MaybeUnboxType(Type const *type) const return MaybeUnboxType(const_cast(type)); } -ir::BoxingUnboxingFlags ETSChecker::GetBoxingFlag(Type *const boxingType) -{ - auto typeKind = TypeKind(MaybeUnboxInRelation(boxingType)); - switch (typeKind) { - case TypeFlag::ETS_BOOLEAN: - return ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN; - case TypeFlag::BYTE: - return ir::BoxingUnboxingFlags::BOX_TO_BYTE; - case TypeFlag::CHAR: - return ir::BoxingUnboxingFlags::BOX_TO_CHAR; - case TypeFlag::SHORT: - return ir::BoxingUnboxingFlags::BOX_TO_SHORT; - case TypeFlag::INT: - return ir::BoxingUnboxingFlags::BOX_TO_INT; - case TypeFlag::LONG: - return ir::BoxingUnboxingFlags::BOX_TO_LONG; - case TypeFlag::FLOAT: - return ir::BoxingUnboxingFlags::BOX_TO_FLOAT; - case TypeFlag::DOUBLE: - return ir::BoxingUnboxingFlags::BOX_TO_DOUBLE; - default: - ES2PANDA_UNREACHABLE(); - } -} - -ir::BoxingUnboxingFlags ETSChecker::GetUnboxingFlag(Type const *const unboxingType) const -{ - auto typeKind = TypeKind(unboxingType); - switch (typeKind) { - case TypeFlag::ETS_BOOLEAN: - return ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN; - case TypeFlag::BYTE: - return ir::BoxingUnboxingFlags::UNBOX_TO_BYTE; - case TypeFlag::CHAR: - return ir::BoxingUnboxingFlags::UNBOX_TO_CHAR; - case TypeFlag::SHORT: - return ir::BoxingUnboxingFlags::UNBOX_TO_SHORT; - case TypeFlag::INT: - return ir::BoxingUnboxingFlags::UNBOX_TO_INT; - case TypeFlag::LONG: - return ir::BoxingUnboxingFlags::UNBOX_TO_LONG; - case TypeFlag::FLOAT: - return ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT; - case TypeFlag::DOUBLE: - return ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE; - default: - ES2PANDA_UNREACHABLE(); - } -} - -void ETSChecker::MaybeAddBoxingFlagInRelation(TypeRelation *relation, Type *target) -{ - auto boxingResult = MaybeBoxInRelation(target); - if ((boxingResult != nullptr) && !relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOXING_FLAG); - relation->GetNode()->AddBoxingUnboxingFlags(GetBoxingFlag(boxingResult)); - relation->Result(true); - } -} - -void ETSChecker::MaybeAddUnboxingFlagInRelation(TypeRelation *relation, Type *source, Type *self) -{ - auto unboxingResult = UnboxingConverter(this, relation, source, self).Result(); - if ((unboxingResult != nullptr) && relation->IsTrue() && !relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->AddBoxingUnboxingFlags(GetUnboxingFlag(unboxingResult)); - } -} - void ETSChecker::CheckUnboxedTypeWidenable(TypeRelation *relation, Type *target, Type *self) { checker::SavedTypeRelationFlagsContext savedTypeRelationFlagCtx( @@ -1354,10 +1282,6 @@ void ETSChecker::CheckUnboxedTypesAssignable(TypeRelation *relation, Type *sourc return; } relation->IsAssignableTo(unboxedSourceType, unboxedTargetType); - if (relation->IsTrue()) { - relation->GetNode()->AddBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxedSourceType)); - } } void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *source, Type *target) @@ -1379,17 +1303,12 @@ void ETSChecker::CheckBoxedSourceTypeAssignable(TypeRelation *relation, Type *so return; } relation->IsAssignableTo(boxedSourceType, target); - if (relation->IsTrue()) { - MaybeAddBoxingFlagInRelation(relation, boxedSourceType); - } else { + if (!relation->IsTrue()) { auto unboxedTargetType = MaybeUnboxInRelation(target); if (unboxedTargetType == nullptr) { return; } NarrowingWideningConverter(this, relation, unboxedTargetType, source); - if (relation->IsTrue()) { - MaybeAddBoxingFlagInRelation(relation, target); - } } } @@ -1403,10 +1322,6 @@ void ETSChecker::CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *rela if (!relation->IsTrue() && relation->ApplyWidening()) { relation->GetChecker()->AsETSChecker()->CheckUnboxedTypeWidenable(relation, target, unboxedSourceType); } - if (!relation->OnlyCheckBoxingUnboxing()) { - relation->GetNode()->AddBoxingUnboxingFlags( - relation->GetChecker()->AsETSChecker()->GetUnboxingFlag(unboxedSourceType)); - } } static ir::AstNode *DerefETSTypeReference(ir::AstNode *node) diff --git a/ets2panda/checker/types/ets/byteType.cpp b/ets2panda/checker/types/ets/byteType.cpp index 44537a4f5469bd9f109de7b02dc32816a05cf909..ed72fe203b7977c5de86aa9a429e60bad75d1b1d 100644 --- a/ets2panda/checker/types/ets/byteType.cpp +++ b/ets2panda/checker/types/ets/byteType.cpp @@ -28,9 +28,6 @@ void ByteType::Identical(TypeRelation *relation, Type *other) void ByteType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/charType.cpp b/ets2panda/checker/types/ets/charType.cpp index 73a36a05703144e5cae91cb20a51e17066e144ba..3c8de58e2eafad946136889fef5a69b70c7018ae 100644 --- a/ets2panda/checker/types/ets/charType.cpp +++ b/ets2panda/checker/types/ets/charType.cpp @@ -28,9 +28,6 @@ void CharType::Identical(TypeRelation *relation, Type *other) void CharType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/doubleType.cpp b/ets2panda/checker/types/ets/doubleType.cpp index 91477c19e4e6d3e13e3bd32caa00fe15102b22c2..759d2485f05854f93f7f0daad05d99e262f7950a 100644 --- a/ets2panda/checker/types/ets/doubleType.cpp +++ b/ets2panda/checker/types/ets/doubleType.cpp @@ -28,9 +28,6 @@ void DoubleType::Identical(TypeRelation *relation, Type *other) void DoubleType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } WideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp index 599a503b4334018bdc4681681d7e1e475927ad0c..bc2a83fca736a1b978110d1655b64d2fa954bab3 100644 --- a/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp +++ b/ets2panda/checker/types/ets/etsAsyncFuncReturnType.cpp @@ -56,9 +56,6 @@ bool ETSAsyncFuncReturnType::AssignmentSource([[maybe_unused]] TypeRelation *rel void ETSAsyncFuncReturnType::AssignmentTarget(TypeRelation *relation, Type *source) { relation->IsAssignableTo(source, promiseType_) || relation->IsAssignableTo(source, GetPromiseTypeArg()); - if (relation->IsTrue() && !source->IsETSObjectType() && relation->ApplyBoxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddBoxingFlagInRelation(relation, source); - } } void ETSAsyncFuncReturnType::CheckVarianceRecursively(TypeRelation *relation, VarianceFlag varianceFlag) diff --git a/ets2panda/checker/types/ets/etsBooleanType.cpp b/ets2panda/checker/types/ets/etsBooleanType.cpp index e3d661ea8d4435fc18891f6373dceb2ebff8bdcd..f19823daa2f3ab0f1dc703ee184a7708609884c5 100644 --- a/ets2panda/checker/types/ets/etsBooleanType.cpp +++ b/ets2panda/checker/types/ets/etsBooleanType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 - 2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 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 @@ -26,14 +26,9 @@ void ETSBooleanType::Identical(TypeRelation *relation, Type *other) } } -void ETSBooleanType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) -{ - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } -} +void ETSBooleanType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) {} -bool ETSBooleanType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) +bool ETSBooleanType::AssignmentSource(TypeRelation *relation, Type *target) { if (relation->ApplyBoxing() && target->IsETSObjectType()) { relation->GetChecker()->AsETSChecker()->CheckBoxedSourceTypeAssignable(relation, this, target); diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 71a56eb5e7daba4270a5a88a7a145a65c066ed73..dc0dfc04a81ec6a1c38d94a9b4515d78218bf3bc 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -136,14 +136,6 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co } if (AnyOfConstituentTypes([relation, refsource, relFn](auto *t) { return relFn(relation, refsource, t); })) { - if (refsource != source) { - // Some nodes can have both boxing and unboxing flags set. When applying them, first the unboxing happens - // (then a possible primitive conversion), and boxing at last. - // NOTE (smartin): when boxing/unboxing is moved to a lowering, review this part of the code - const auto mergedBoxingFlags = - relation->GetNode()->GetBoxingUnboxingFlags() | checker->GetBoxingFlag(refsource); - relation->GetNode()->SetBoxingUnboxingFlags(mergedBoxingFlags); - } relation->Result(true); return; } @@ -160,7 +152,6 @@ void ETSUnionType::RelationTarget(TypeRelation *relation, Type *source, RelFN co AmbiguousUnionOperation(relation); return; } - relation->GetNode()->SetBoxingUnboxingFlags(checker->GetBoxingFlag(ct)); related = true; } } diff --git a/ets2panda/checker/types/ets/floatType.cpp b/ets2panda/checker/types/ets/floatType.cpp index 7f69458b1896ea368a70785d9f2cf810d9c0f092..6592c8dae8c447a1406d32e186410d40b7f45725 100644 --- a/ets2panda/checker/types/ets/floatType.cpp +++ b/ets2panda/checker/types/ets/floatType.cpp @@ -28,9 +28,6 @@ void FloatType::Identical(TypeRelation *relation, Type *other) void FloatType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/intType.cpp b/ets2panda/checker/types/ets/intType.cpp index c21e904b086e871881b70036dd39fd804a7eae0c..5c4872c886cfeef9568ffa7233c9e54fae732852 100644 --- a/ets2panda/checker/types/ets/intType.cpp +++ b/ets2panda/checker/types/ets/intType.cpp @@ -28,9 +28,6 @@ void IntType::Identical(TypeRelation *relation, Type *other) void IntType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/longType.cpp b/ets2panda/checker/types/ets/longType.cpp index 7f4d080115b80bcfc8306baef6c79224046bd87c..2420ae1922c7c11222dc8a29e22d888f3fa43f97 100644 --- a/ets2panda/checker/types/ets/longType.cpp +++ b/ets2panda/checker/types/ets/longType.cpp @@ -28,9 +28,6 @@ void LongType::Identical(TypeRelation *relation, Type *other) void LongType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/ets/shortType.cpp b/ets2panda/checker/types/ets/shortType.cpp index bc2011294ba2ee8c3f735743c3f027abcbdacdc7..ef622bbcfcae327275cdb93be07ea5e2eaa0a72d 100644 --- a/ets2panda/checker/types/ets/shortType.cpp +++ b/ets2panda/checker/types/ets/shortType.cpp @@ -28,9 +28,6 @@ void ShortType::Identical(TypeRelation *relation, Type *other) void ShortType::AssignmentTarget(TypeRelation *relation, [[maybe_unused]] Type *source) { - if (relation->ApplyUnboxing() && !relation->IsTrue()) { - relation->GetChecker()->AsETSChecker()->MaybeAddUnboxingFlagInRelation(relation, source, this); - } NarrowingWideningConverter(relation->GetChecker()->AsETSChecker(), relation, this, source); } diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index 3bfa01942cef426a0d9ec499ec191eea22dd58f8..5fe44d2b3dc85d64df4080159d90862a4b0231b0 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -190,10 +190,7 @@ bool TypeRelation::IsCastableTo(Type *const source, Type *const target) return false; } - // NOTE: Can't cache if the node has BoxingUnboxingFlags. These flags should be stored and restored on the node - // on cache hit. - if (UncheckedCast() && node_->GetBoxingUnboxingFlags() == ir::BoxingUnboxingFlags::NONE && - !node_->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { + if (UncheckedCast() && !node_->HasAstNodeFlags(ir::AstNodeFlags::GENERATE_VALUE_OF)) { checker_->UncheckedCastableResult().cached.insert( {{source->Id(), target->Id()}, {result_, RelationType::UNCHECKED_CASTABLE}}); } diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 5432c108e4681956b602ae85579a7f9110971c86..883cf9ce2aa8c4f1d9565ac8233e1b21db1757e6 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -18,7 +18,6 @@ #include "compiler/base/catchTable.h" #include "checker/ets/dynamic/dynamicCall.h" #include "compiler/base/condition.h" -#include "compiler/core/ETSGen-inl.h" #include "compiler/base/lreference.h" #include "compiler/core/switchBuilder.h" #include "compiler/function/functionBuilder.h" @@ -53,15 +52,11 @@ void ETSCompiler::Compile(const ir::ClassProperty *st) const auto ttctx = compiler::TargetTypeContext(etsg, st->TsType()); compiler::RegScope rs(etsg); - ir::BoxingUnboxingFlags flags = - (st->Value() != nullptr) ? st->Value()->GetBoxingUnboxingFlags() : ir::BoxingUnboxingFlags::NONE; - if (st->Value() == nullptr) { etsg->LoadDefaultValue(st, st->TsType()); } else { st->Value()->Compile(etsg); etsg->ApplyConversion(st->Value(), st->TsType()); - st->Value()->SetBoxingUnboxingFlags(flags); } if (st->IsStatic()) { @@ -257,11 +252,7 @@ static void HandleUnionTypeInForOf(compiler::ETSGen *etsg, checker::Type const * } else if (currentType->IsETSResizableArrayType()) { etsg->LoadResizableArrayElement(st, unionReg, *countReg); } else { - etsg->LoadStringChar(st, unionReg, *countReg); - // NOTE(vpukhov): #20510 use a single unboxing convertor - etsg->ApplyCastToBoxingFlags(st, ir::BoxingUnboxingFlags::BOX_TO_CHAR); - etsg->EmitBoxingConversion(ir::BoxingUnboxingFlags::BOX_TO_CHAR, st); - etsg->CastToChar(st); + etsg->LoadStringChar(st, unionReg, *countReg, true); } } @@ -741,9 +732,6 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle checker::Signature *signature) const { ETSGen *etsg = GetETSGen(); - if (expr->Callee()->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { - etsg->ApplyConversionAndStoreAccumulator(expr->Callee(), calleeReg, nullptr); - } if (signature->HasSignatureFlag(checker::SignatureFlags::STATIC)) { etsg->CallExact(expr, expr->Signature(), expr->Arguments()); } else if (expr->Callee()->IsMemberExpression()) { @@ -803,10 +791,6 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const } else { ES2PANDA_UNREACHABLE(); } - - if (expr->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG | ir::BoxingUnboxingFlags::BOXING_FLAG)) { - etsg->ApplyConversion(expr, expr->TsType()); - } } void ETSCompiler::Compile(const ir::ConditionalExpression *expr) const @@ -1415,9 +1399,9 @@ void ETSCompiler::Compile(const ir::ReturnStatement *st) const return; } - auto ttctx = compiler::TargetTypeContext(etsg, etsg->ReturnType()); + auto ttctx = compiler::TargetTypeContext(etsg, st->ReturnType()); argument->Compile(etsg); - etsg->ApplyConversion(argument, etsg->ReturnType()); + etsg->ApplyConversion(argument, st->ReturnType()); if (etsg->ExtendWithFinalizer(st->Parent(), st)) { return; @@ -1639,6 +1623,7 @@ void ETSCompiler::CompileCast(const ir::TSAsExpression *expr, checker::Type cons } default: { CompileCastPrimitives(expr, targetType); + break; } } } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 57a00db32b9795d6e16ffabb325d7d1310dc2394..6c43a31fff327a72117bfb49f5519eb7a0590478 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -1006,11 +1006,9 @@ void ETSGen::GuardUncheckedType(const ir::AstNode *node, const checker::Type *un SetAccumulatorType(unchecked); // this check guards possible type violations, **do not relax it** CheckedReferenceNarrowing(node, Checker()->MaybeBoxType(target)); - // Because on previos step accumulator type may be set in CheckerReferenceNarrowing to boxed countepart of + // Because on previous step accumulator type may be set in CheckerReferenceNarrowing to boxed counterpart of // target We need to apply unbox conversion if needed to avoid RTE if (target->IsETSPrimitiveType() && GetAccumulatorType()->IsETSUnboxableObject()) { - // NOTE: need to refactor - node->AddBoxingUnboxingFlags(Checker()->GetUnboxingFlag(target)); ApplyConversion(node, target); } } @@ -1093,78 +1091,15 @@ void ETSGen::ApplyConversionCast(const ir::AstNode *node, const checker::Type *t } } -void ETSGen::ApplyBoxingConversion(const ir::AstNode *node) -{ - EmitBoxingConversion(node); - node->SetBoxingUnboxingFlags( - static_cast(node->GetBoxingUnboxingFlags() & ~(ir::BoxingUnboxingFlags::BOXING_FLAG))); -} - -void ETSGen::ApplyUnboxingConversion(const ir::AstNode *node) -{ - auto const callUnbox = [this, node](std::string_view sig, checker::Type const *unboxedType) { - auto boxedType = Checker()->MaybeBoxType(unboxedType)->AsETSObjectType(); - EmitUnboxedCall(node, sig, unboxedType, boxedType); - }; - - auto const unboxFlags = - ir::BoxingUnboxingFlags(node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG); - node->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG); - - switch (unboxFlags) { - case ir::BoxingUnboxingFlags::UNBOX_TO_BOOLEAN: - callUnbox(Signatures::BUILTIN_BOOLEAN_UNBOXED, Checker()->GlobalETSBooleanType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_BYTE: - callUnbox(Signatures::BUILTIN_BYTE_UNBOXED, Checker()->GlobalByteType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_CHAR: - callUnbox(Signatures::BUILTIN_CHAR_UNBOXED, Checker()->GlobalCharType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_SHORT: - callUnbox(Signatures::BUILTIN_SHORT_UNBOXED, Checker()->GlobalShortType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_INT: - callUnbox(Signatures::BUILTIN_INT_UNBOXED, Checker()->GlobalIntType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_LONG: - callUnbox(Signatures::BUILTIN_LONG_UNBOXED, Checker()->GlobalLongType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_FLOAT: - callUnbox(Signatures::BUILTIN_FLOAT_UNBOXED, Checker()->GlobalFloatType()); - return; - case ir::BoxingUnboxingFlags::UNBOX_TO_DOUBLE: - callUnbox(Signatures::BUILTIN_DOUBLE_UNBOXED, Checker()->GlobalDoubleType()); - return; - default: - ES2PANDA_UNREACHABLE(); - } -} - void ETSGen::ApplyConversion(const ir::AstNode *node, const checker::Type *targetType) { - auto ttctx = TargetTypeContext(this, targetType); - - const bool hasBoxingflags = (node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG) != 0U; - const bool hasUnboxingflags = (node->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::UNBOXING_FLAG) != 0U; - if (hasBoxingflags && !hasUnboxingflags) { - ApplyBoxingConversion(node); - return; - } - - if (hasUnboxingflags) { - ApplyUnboxingConversion(node); - } - if (targetType == nullptr) { return; } - ApplyConversionCast(node, targetType); + auto ttctx = TargetTypeContext(this, targetType); - if (hasBoxingflags) { - ApplyBoxingConversion(node); - } + ApplyConversionCast(node, targetType); } void ETSGen::ApplyCast(const ir::AstNode *node, const checker::Type *targetType) @@ -1210,118 +1145,6 @@ void ETSGen::ApplyCast(const ir::AstNode *node, const checker::Type *targetType) } } -void ETSGen::ApplyCastToBoxingFlags(const ir::AstNode *node, const ir::BoxingUnboxingFlags targetType) -{ - switch (targetType) { - case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: { - CastToDouble(node); - break; - } - case ir::BoxingUnboxingFlags::BOX_TO_FLOAT: { - CastToFloat(node); - break; - } - case ir::BoxingUnboxingFlags::BOX_TO_LONG: { - CastToLong(node); - break; - } - case ir::BoxingUnboxingFlags::BOX_TO_INT: { - CastToInt(node); - break; - } - case ir::BoxingUnboxingFlags::BOX_TO_BYTE: { - CastToByte(node); - break; - } - default: { - break; - } - } -} - -void ETSGen::EmitUnboxedCall(const ir::AstNode *node, std::string_view signatureFlag, - const checker::Type *const targetType, const checker::Type *const boxedType) -{ - RegScope rs(this); - // NOTE(vpukhov): #20510 lowering - if (node->HasAstNodeFlags(ir::AstNodeFlags::CHECKCAST)) { - CheckedReferenceNarrowing(node, boxedType); - } - - // to cast to primitive types we probably have to cast to corresponding boxed built-in types first. - auto *const checker = Checker()->AsETSChecker(); - auto const *accumulatorType = GetAccumulatorType(); - if (accumulatorType->IsETSObjectType() && //! accumulatorType->DefinitelyNotETSNullish() && - !checker->Relation()->IsIdenticalTo(const_cast(accumulatorType), - const_cast(boxedType))) { - CastToReftype(node, boxedType, false); - } - - Ra().Emit(node, signatureFlag, dummyReg_, 0); - SetAccumulatorType(targetType); - if (node->IsExpression()) { - const_cast(node->AsExpression())->SetTsType(const_cast(targetType)); - } -} - -// NOTE(vpukhov): #20510 should be available only as a part of ApplyBoxingConversion -void ETSGen::EmitBoxingConversion(ir::BoxingUnboxingFlags boxingFlag, const ir::AstNode *node) -{ - auto const callBox = [this, node](std::string_view sig, checker::Type const *unboxedType) { - Ra().Emit(node, sig, dummyReg_, 0); - SetAccumulatorType(Checker()->MaybeBoxType(unboxedType)->AsETSObjectType()); - }; - - switch (boxingFlag) { - case ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN: - callBox(Signatures::BUILTIN_BOOLEAN_VALUE_OF, Checker()->GlobalETSBooleanType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_BYTE: - callBox(Signatures::BUILTIN_BYTE_VALUE_OF, Checker()->GlobalByteType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_CHAR: - callBox(Signatures::BUILTIN_CHAR_VALUE_OF, Checker()->GlobalCharType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_SHORT: - callBox(Signatures::BUILTIN_SHORT_VALUE_OF, Checker()->GlobalShortType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_INT: - callBox(Signatures::BUILTIN_INT_VALUE_OF, Checker()->GlobalIntType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_LONG: - callBox(Signatures::BUILTIN_LONG_VALUE_OF, Checker()->GlobalLongType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_FLOAT: - callBox(Signatures::BUILTIN_FLOAT_VALUE_OF, Checker()->GlobalFloatType()); - return; - case ir::BoxingUnboxingFlags::BOX_TO_DOUBLE: - callBox(Signatures::BUILTIN_DOUBLE_VALUE_OF, Checker()->GlobalDoubleType()); - return; - default: - ES2PANDA_UNREACHABLE(); - } -} - -// NOTE(vpukhov): #20510 should be available only as a part of ApplyBoxingConversion -void ETSGen::EmitBoxingConversion(const ir::AstNode *node) -{ - auto boxingFlag = - static_cast(ir::BoxingUnboxingFlags::BOXING_FLAG & node->GetBoxingUnboxingFlags()); - - RegScope rs(this); - - ApplyCastToBoxingFlags(node, boxingFlag); - - EmitBoxingConversion(boxingFlag, node); - - if (node->IsExpression()) { - auto boxedType = const_cast(GetAccumulatorType()); - const_cast(node->AsExpression())->SetTsType(boxedType); - } - - node->RemoveBoxingUnboxingFlags(boxingFlag); -} - void ETSGen::SwapBinaryOpArgs(const ir::AstNode *const node, const VReg lhs) { const RegScope rs(this); @@ -1706,12 +1529,7 @@ void ETSGen::CastToInt(const ir::AstNode *node) void ETSGen::CastToReftype(const ir::AstNode *const node, const checker::Type *const targetType, const bool unchecked) { const auto *const sourceType = GetAccumulatorType(); - // sourceType can be either RefType or CharType - ES2PANDA_ASSERT(sourceType->IsETSReferenceType() || sourceType->IsCharType()); - if (sourceType->IsCharType()) { - // NOTE: temporary flag have to be set for CastToString - node->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOX_TO_CHAR); - } + ES2PANDA_ASSERT(sourceType->IsETSReferenceType()); if (sourceType->IsETSDynamicType()) { CastDynamicToObject(node, targetType); @@ -3270,10 +3088,14 @@ void ETSGen::DoubleIsNaN(const ir::AstNode *node) SetAccumulatorType(Checker()->GlobalETSBooleanType()); } -void ETSGen::LoadStringChar(const ir::AstNode *node, const VReg stringObj, const VReg charIndex) +void ETSGen::LoadStringChar(const ir::AstNode *node, const VReg stringObj, const VReg charIndex, bool needBox) { Ra().Emit(node, Signatures::BUILTIN_STRING_CHAR_AT, stringObj, charIndex); SetAccumulatorType(Checker()->GlobalCharType()); + if (needBox) { + Ra().Emit(node, Signatures::BUILTIN_CHAR_VALUE_OF, dummyReg_, 0); + SetAccumulatorType(Checker()->GlobalCharBuiltinType()); + } } void ETSGen::ThrowException(const ir::Expression *expr) diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 045a1c0dd8f958c795fe7984c17811bdb74e35f1..3cf794e79ba168f7993e91b8857accd08626297d 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -213,8 +213,6 @@ public: void LoadAccumulatorDynamicModule(const ir::AstNode *node, const ir::ETSImportDeclaration *import); - void ApplyBoxingConversion(const ir::AstNode *node); - void ApplyUnboxingConversion(const ir::AstNode *node); void ApplyConversion(const ir::AstNode *node) { if (targetType_ != nullptr) { @@ -224,9 +222,6 @@ public: void ApplyConversionCast(const ir::AstNode *node, const checker::Type *targetType); void ApplyConversion(const ir::AstNode *node, const checker::Type *targetType); void ApplyCast(const ir::AstNode *node, const checker::Type *targetType); - void ApplyCastToBoxingFlags(const ir::AstNode *node, const ir::BoxingUnboxingFlags targetType); - void EmitBoxingConversion(ir::BoxingUnboxingFlags boxingFlag, const ir::AstNode *node); - void EmitBoxingConversion(const ir::AstNode *node); void SwapBinaryOpArgs(const ir::AstNode *node, VReg lhs); VReg MoveAccToReg(const ir::AstNode *node); @@ -255,7 +250,7 @@ public: } void LoadStringLength(const ir::AstNode *node); - void LoadStringChar(const ir::AstNode *node, VReg stringObj, VReg charIndex); + void LoadStringChar(const ir::AstNode *node, VReg stringObj, VReg charIndex, bool needBox = false); void FloatIsNaN(const ir::AstNode *node); void DoubleIsNaN(const ir::AstNode *node); @@ -447,9 +442,6 @@ public: private: const VReg dummyReg_ = VReg::RegStart(); - void EmitUnboxedCall(const ir::AstNode *node, std::string_view signatureFlag, const checker::Type *targetType, - const checker::Type *boxedType); - void LoadConstantObject(const ir::Expression *node, const checker::Type *type); void StringBuilderAppend(const ir::AstNode *node, VReg builder); void AppendString(const ir::Expression *binExpr, VReg builder); diff --git a/ets2panda/compiler/lowering/ets/boxedTypeLowering.cpp b/ets2panda/compiler/lowering/ets/boxedTypeLowering.cpp deleted file mode 100644 index 5ede67cba95b3851f36b61bdd36b83686d7acaa8..0000000000000000000000000000000000000000 --- a/ets2panda/compiler/lowering/ets/boxedTypeLowering.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * Copyright (c) 2024-2025 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. - */ - -#include "boxedTypeLowering.h" - -#include "checker/ETSchecker.h" -#include "compiler/lowering/util.h" -#include "generated/signatures.h" - -namespace ark::es2panda::compiler { - -std::string_view BoxedTypeLowering::Name() const -{ - return "BoxedTypeLowering"; -} - -void BoxNumberLiteralArguments(ir::CallExpression *callExpr, PhaseManager *phaseManager, checker::ETSChecker *checker, - parser::ETSParser *parser) -{ - const static std::unordered_map BOXTO({ - {ir::BoxingUnboxingFlags::BOX_TO_BOOLEAN, compiler::Signatures::BUILTIN_BOOLEAN_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_BYTE, compiler::Signatures::BUILTIN_BYTE_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_SHORT, compiler::Signatures::BUILTIN_SHORT_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_CHAR, compiler::Signatures::BUILTIN_CHAR_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_INT, compiler::Signatures::BUILTIN_INT_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_LONG, compiler::Signatures::BUILTIN_LONG_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_FLOAT, compiler::Signatures::BUILTIN_FLOAT_CLASS}, - {ir::BoxingUnboxingFlags::BOX_TO_DOUBLE, compiler::Signatures::BUILTIN_DOUBLE_CLASS}, - }); - - for (size_t i = 0; i < callExpr->Arguments().size(); ++i) { - auto arg = callExpr->Arguments()[i]; - if (arg->IsNumberLiteral()) { - const auto boxingFlag = arg->GetBoxingUnboxingFlags() & ir::BoxingUnboxingFlags::BOXING_FLAG; - auto it = BOXTO.find(static_cast(boxingFlag)); - if (it == BOXTO.end()) { - continue; - } - - auto res = parser->CreateFormattedExpression("@@I1.valueOf(@@E2)", it->second, arg); - res->SetParent(callExpr); - res->SetRange(arg->Range()); - arg->RemoveBoxingUnboxingFlags(ir::BoxingUnboxingFlags::BOXING_FLAG); - callExpr->Arguments()[i] = res; - - Recheck(phaseManager, checker->VarBinder()->AsETSBinder(), checker, res); - } - } -} - -bool BoxedTypeLowering::Perform(public_lib::Context *const ctx, parser::Program *const program) -{ - for (const auto &[_, ext_programs] : program->ExternalSources()) { - (void)_; - for (auto *const extProg : ext_programs) { - Perform(ctx, extProg); - } - } - - auto checker = ctx->checker->AsETSChecker(); - auto parser = ctx->parser->AsETSParser(); - auto phaseManager = ctx->phaseManager; - program->Ast()->TransformChildrenRecursively( - // CC-OFFNXT(G.FMT.14-CPP) project code style - [phaseManager, checker, parser](ir::AstNode *ast) -> ir::AstNode * { - if (!ast->IsCallExpression()) { - return ast; - } - - auto callExpr = ast->AsCallExpression(); - if (callExpr->Signature() == nullptr || - // Skip lambda expressions because lambda parameters are treated a special way as ETSObjectType. - callExpr->Callee()->TsType()->IsETSObjectType()) { - return ast; - } - - BoxNumberLiteralArguments(callExpr, phaseManager, checker, parser); - - return ast; - }, - Name()); - - return true; -} - -} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/boxedTypeLowering.h b/ets2panda/compiler/lowering/ets/boxedTypeLowering.h deleted file mode 100644 index cf124f55bb29375e856e38d1df440d4265a45aef..0000000000000000000000000000000000000000 --- a/ets2panda/compiler/lowering/ets/boxedTypeLowering.h +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2024 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 ES2PANDA_COMPILER_LOWERING_BOXED_TYPE_LOWERING_H -#define ES2PANDA_COMPILER_LOWERING_BOXED_TYPE_LOWERING_H - -#include "compiler/lowering/phase.h" - -namespace ark::es2panda::compiler { - -class BoxedTypeLowering : public Phase { -public: - std::string_view Name() const override; - bool Perform(public_lib::Context *ctx, parser::Program *program) override; -}; - -} // namespace ark::es2panda::compiler - -#endif // ES2PANDA_COMPILER_LOWERING_BOXED_TYPE_LOWERING_H diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index 52589b291f4170ed781bbd0910cc3202e958a2a4..d8047479810e5698326789aa9cda923807e34e03 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -310,7 +310,6 @@ static ir::AstNode *HandleAssignment(public_lib::Context *ctx, ir::AssignmentExp res->Check(checker); ES2PANDA_ASSERT(res->TsType() == ass->TsType()); - res->SetBoxingUnboxingFlags(ass->GetBoxingUnboxingFlags()); return res; } diff --git a/ets2panda/compiler/lowering/ets/extensionAccessorLowering.cpp b/ets2panda/compiler/lowering/ets/extensionAccessorLowering.cpp index 4c50938f215dec054b0e0d65a3e42a73a25adb87..8036059fcef943d1cd4c5bc74153061c991aa2e1 100644 --- a/ets2panda/compiler/lowering/ets/extensionAccessorLowering.cpp +++ b/ets2panda/compiler/lowering/ets/extensionAccessorLowering.cpp @@ -71,7 +71,6 @@ static void TryHandleExtensionAccessor(checker::ETSChecker *checker, ir::MemberE checker, expr, ArenaVector(checker->Allocator()->Adapter())); auto *rightExpr = assignExpr->AsAssignmentExpression()->Right(); - rightExpr->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); if (IsMemberExprExtensionAccessor(rightExpr)) { SwitchType(rightExpr->AsMemberExpression()); checker::Type *tsType = rightExpr->AsMemberExpression()->TsType(); @@ -96,7 +95,6 @@ static void TryHandleExtensionAccessor(checker::ETSChecker *checker, ir::MemberE checker, expr, ArenaVector(checker->Allocator()->Adapter())); callExpr->SetParent(oldParent); CheckLoweredNode(checker->VarBinder()->AsETSBinder(), checker, callExpr); - callExpr->AddBoxingUnboxingFlags(expr->GetBoxingUnboxingFlags()); } static ir::AstNode *CheckAndReturnNode(checker::ETSChecker *checker, ir::AstNode *node) diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 1276b243ee934483eb795a7ff5fdecefc158a092..4a28422b1427ea262a5d386ca70f2231ac323c6c 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -1135,9 +1135,7 @@ static ir::AstNode *InsertInvokeCall(public_lib::Context *ctx, ir::CallExpressio In the future, make sure those conversions behave appropriately. */ for (auto *arg : call->Arguments()) { - auto boxingFlags = arg->GetBoxingUnboxingFlags(); Recheck(ctx->phaseManager, varBinder, checker, arg); - arg->SetBoxingUnboxingFlags(boxingFlags); } return call; diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index deefde6145b899278ad075e57cc06081c2aff4da..10af889156133f416921870e7df62209cd65ded4 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -36,7 +36,6 @@ ir::Expression *ObjectIndexLowering::ProcessIndexSetAccess(parser::ETSParser *pa // required accessible index method[s] and all the types are properly resolved. auto indexSymbol = Gensym(checker->Allocator()); - assignmentExpression->Right()->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); auto *const memberExpression = assignmentExpression->Left()->AsMemberExpression(); ir::Expression *loweringResult = nullptr; ir::AstNode *setter = nullptr; @@ -73,7 +72,6 @@ ir::Expression *ObjectIndexLowering::ProcessIndexSetAccess(parser::ETSParser *pa } loweringResult->SetParent(assignmentExpression->Parent()); loweringResult->SetRange(assignmentExpression->Range()); - loweringResult->SetBoxingUnboxingFlags(assignmentExpression->GetBoxingUnboxingFlags()); setter->AddModifier(ir::ModifierFlags::ARRAY_SETTER); auto scope = varbinder::LexicalScope::Enter(checker->VarBinder(), NearestScope(assignmentExpression->Parent())); @@ -99,7 +97,6 @@ ir::Expression *ObjectIndexLowering::ProcessIndexGetAccess(parser::ETSParser *pa loweringResult->SetRange(memberExpression->Range()); CheckLoweredNode(checker->VarBinder()->AsETSBinder(), checker, loweringResult); - loweringResult->SetBoxingUnboxingFlags(memberExpression->GetBoxingUnboxingFlags()); return loweringResult; } diff --git a/ets2panda/compiler/lowering/ets/opAssignment.cpp b/ets2panda/compiler/lowering/ets/opAssignment.cpp index 3c0b7e015ee36719b1eacb6b9d9eb193332b2a07..9eae7df24e285f46acc6c21feee03748baa4be84 100644 --- a/ets2panda/compiler/lowering/ets/opAssignment.cpp +++ b/ets2panda/compiler/lowering/ets/opAssignment.cpp @@ -74,34 +74,6 @@ static lexer::TokenType CombinedOpToOp(const lexer::TokenType combinedOp) ES2PANDA_UNREACHABLE(); } -void AdjustBoxingUnboxingFlags(ir::Expression *loweringResult, const ir::Expression *oldExpr) -{ - ir::Expression *exprToProcess = nullptr; - if (loweringResult->IsAssignmentExpression()) { - exprToProcess = loweringResult->AsAssignmentExpression(); - } else if (loweringResult->IsBlockExpression() && !loweringResult->AsBlockExpression()->Statements().empty()) { - auto *statement = loweringResult->AsBlockExpression()->Statements().back(); - if (statement->IsExpressionStatement()) { - exprToProcess = statement->AsExpressionStatement()->GetExpression(); - } - } else { - ES2PANDA_UNREACHABLE(); - } - - // NOTE: gogabr. make sure that the checker never puts both a boxing and an unboxing flag on the same node. - // Then this function will become unnecessary. - const ir::BoxingUnboxingFlags oldBoxingFlag {oldExpr->GetBoxingUnboxingFlags() & - ir::BoxingUnboxingFlags::BOXING_FLAG}; - const ir::BoxingUnboxingFlags oldUnboxingFlag {oldExpr->GetBoxingUnboxingFlags() & - ir::BoxingUnboxingFlags::UNBOXING_FLAG}; - - if (exprToProcess->TsType()->IsETSPrimitiveType()) { - loweringResult->SetBoxingUnboxingFlags(oldBoxingFlag); - } else if (exprToProcess->TsType()->IsETSObjectType()) { - loweringResult->SetBoxingUnboxingFlags(oldUnboxingFlag); - } -} - static ir::OpaqueTypeNode *CreateProxyTypeNode(checker::ETSChecker *checker, ir::Expression *expr) { auto *lcType = expr->TsType(); @@ -232,7 +204,6 @@ static ir::Expression *ConstructOpAssignmentResult(public_lib::Context *ctx, ir: auto *const left = assignment->Left(); auto *const right = assignment->Right(); - right->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); auto *exprType = CreateProxyTypeNode(checker, left); ir::Expression *retVal = nullptr; @@ -285,9 +256,6 @@ ir::AstNode *HandleOpAssignment(public_lib::Context *ctx, ir::AssignmentExpressi checker::ScopeContext sc {checker, scope}; loweringResult->Check(checker); - - AdjustBoxingUnboxingFlags(loweringResult, assignment); - return loweringResult; } @@ -359,8 +327,9 @@ static ir::Expression *ConstructUpdateResult(public_lib::Context *ctx, ir::Updat // NOLINTBEGIN(readability-magic-numbers) if (upd->IsPrefix()) { - argInfo.newAssignmentStatements += "const @@I7 = (" + GenFormatForExpression(argument, 8U, 9U) + opSign + " 1" + - suffix + ").to" + argument->TsType()->ToString() + "();"; + argInfo.newAssignmentStatements += "const @@I7 = (" + GenFormatForExpression(argument, 8U, 9U) + + (argument->IsTSNonNullExpression() ? "!" : "") + opSign + " 1" + suffix + + ").to" + argument->TsType()->ToString() + "();"; argInfo.newAssignmentStatements += GenFormatForExpression(argument, 10U, 11U) + " = @@I12; @@I13"; return parser->CreateFormattedExpression( argInfo.newAssignmentStatements, argInfo.id1, argInfo.object, argInfo.objType, argInfo.id2, @@ -370,10 +339,10 @@ static ir::Expression *ConstructUpdateResult(public_lib::Context *ctx, ir::Updat } // upd is postfix - argInfo.newAssignmentStatements += "const @@I7 = " + GenFormatForExpression(argument, 8, 9) + ".to" + - argument->TsType()->ToString() + "();" + - GenFormatForExpression(argument, 10U, 11U) + " = (@@I12 " + opSign + " 1" + - suffix + ").to" + argument->TsType()->ToString() + "(); @@I13;"; + argInfo.newAssignmentStatements += + "const @@I7 = " + GenFormatForExpression(argument, 8, 9) + (argument->IsTSNonNullExpression() ? "!" : "") + + ".to" + argument->TsType()->ToString() + "();" + GenFormatForExpression(argument, 10U, 11U) + " = (@@I12 " + + opSign + " 1" + suffix + ").to" + argument->TsType()->ToString() + "(); @@I13;"; return parser->CreateFormattedExpression( argInfo.newAssignmentStatements, argInfo.id1, argInfo.object, argInfo.objType, argInfo.id2, argInfo.property, argInfo.propType, argInfo.id3, GetClone(allocator, argInfo.id1), GetClone(allocator, argInfo.id2), @@ -409,9 +378,6 @@ static ir::AstNode *HandleUpdate(public_lib::Context *ctx, ir::UpdateExpression checker->VarBinder()->AsETSBinder()->ResolveReferencesForScopeWithContext(loweringResult, NearestScope(loweringResult)); loweringResult->Check(checker); - - AdjustBoxingUnboxingFlags(loweringResult, upd); - return loweringResult; } diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index b8b421ea10c3d95799a3bb8885243786235cc01b..ed41fae09264fedae76a479d09501e9acdb5c51f 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -136,7 +136,6 @@ static ir::CallExpression *RebuildCallExpression(public_lib::Context *context, i for (size_t i = 0; i < signature->Params().size(); ++i) { newArgs.push_back(originalCall->Arguments()[i]); - newArgs[i]->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); } newArgs.push_back(restArgsArray); @@ -147,7 +146,6 @@ static ir::CallExpression *RebuildCallExpression(public_lib::Context *context, i restArgsArray->SetParent(newCall); newCall->SetParent(originalCall->Parent()); newCall->AddModifier(originalCall->Modifiers()); - newCall->AddBoxingUnboxingFlags(originalCall->GetBoxingUnboxingFlags()); newCall->AddAstNodeFlags(ir::AstNodeFlags::RESIZABLE_REST); auto *scope = NearestScope(newCall->Parent()); @@ -176,7 +174,6 @@ static ir::ETSNewClassInstanceExpression *RebuildNewClassInstanceExpression( restArgsArray->SetParent(newCall); newCall->SetParent(originalCall->Parent()); newCall->AddModifier(originalCall->Modifiers()); - newCall->AddBoxingUnboxingFlags(originalCall->GetBoxingUnboxingFlags()); auto *scope = NearestScope(newCall->Parent()); auto bscope = varbinder::LexicalScope::Enter(context->checker->VarBinder()->AsETSBinder(), scope); CheckLoweredNode(context->checker->VarBinder()->AsETSBinder(), context->checker->AsETSChecker(), newCall); diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 3640f18cfb08fecb54e18115729802b0ddc38f84..5a22395152163c535031661d6e3d94bc86d7c85f 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -603,7 +603,6 @@ static ir::Expression *AdjustType(UnboxContext *uctx, ir::Expression *expr, chec return res; } - expr->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); if (actualType->IsETSPrimitiveType() && uctx->checker->IsReferenceType(expectedType)) { expr = InsertPrimitiveConversionIfNeeded(uctx, expr, expectedType); ES2PANDA_ASSERT( @@ -1395,10 +1394,7 @@ bool UnboxPhase::PerformForModule(public_lib::Context *ctx, parser::Program *pro }); UnboxVisitor visitor(&uctx); - program->Ast()->IterateRecursivelyPostorder([&visitor](ir::AstNode *ast) { - ast->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); - ast->Accept(&visitor); - }); + program->Ast()->IterateRecursivelyPostorder([&visitor](ir::AstNode *ast) { ast->Accept(&visitor); }); VisitExternalPrograms(&visitor, program); for (auto *stmt : program->Ast()->Statements()) { diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index b9f9b265294bda31d9afac77424f83f2aadde1ca..91a15dd7aefc69c4d2843e3465b14cdf4f535c5d 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -20,7 +20,6 @@ #include "compiler/lowering/ets/ambientLowering.h" #include "compiler/lowering/ets/arrayLiteralLowering.h" #include "compiler/lowering/ets/bigintLowering.h" -#include "compiler/lowering/ets/boxedTypeLowering.h" #include "compiler/lowering/ets/boxingForLocals.h" #include "compiler/lowering/ets/capturedVariables.h" #include "compiler/lowering/ets/constantExpressionLowering.h" @@ -113,7 +112,6 @@ static StringConstantsLowering g_stringConstantsLowering; static PartialExportClassGen g_partialExportClassGen; static PackageImplicitImport g_packageImplicitImport; static GenericBridgesPhase g_genericBridgesLowering; -static BoxedTypeLowering g_boxedTypeLowering; static AsyncMethodLowering g_asyncMethodLowering; static TypeFromLowering g_typeFromLowering; static ResizableArrayConvert g_resizableArrayConvert; @@ -174,7 +172,6 @@ std::vector GetETSPhaseList() &g_extensionAccessorPhase, &g_boxingForLocals, &g_recordLowering, - &g_boxedTypeLowering, &g_objectIndexLowering, &g_objectIteratorLowering, &g_lambdaConversionPhase, diff --git a/ets2panda/ir/astNode.cpp b/ets2panda/ir/astNode.cpp index 4a1640749d927ab6acdbbe7fb01b2e96e1ca898d..bb50c713769313fc19f056c41e394e26b26138cd 100644 --- a/ets2panda/ir/astNode.cpp +++ b/ets2panda/ir/astNode.cpp @@ -329,7 +329,6 @@ void AstNode::CopyTo(AstNode *other) const other->range_ = range_; other->flags_ = flags_; other->astNodeFlags_ = astNodeFlags_; - other->boxingUnboxingFlags_ = boxingUnboxingFlags_; other->variable_ = variable_; other->originalNode_ = originalNode_; other->transformedNode_ = transformedNode_; diff --git a/ets2panda/ir/astNode.h b/ets2panda/ir/astNode.h index ff46bb1d592751bba8b50a43d172f1bd9ce573d3..c302f082898ca7b931b13e61a4fc0ba53428cd32 100644 --- a/ets2panda/ir/astNode.h +++ b/ets2panda/ir/astNode.h @@ -488,7 +488,6 @@ public: (member_name) &= ~flag; \ } - DECLARE_FLAG_OPERATIONS(BoxingUnboxingFlags, boxingUnboxingFlags_); DECLARE_FLAG_OPERATIONS(AstNodeFlags, astNodeFlags_); #undef DECLARE_FLAG_OPERATIONS @@ -575,7 +574,6 @@ protected: AstNodeType type_; ModifierFlags flags_ {}; mutable AstNodeFlags astNodeFlags_ {}; - mutable BoxingUnboxingFlags boxingUnboxingFlags_ {}; // NOLINTEND(misc-non-private-member-variables-in-classes) private: diff --git a/ets2panda/ir/astNodeFlags.h b/ets2panda/ir/astNodeFlags.h index 20af517c70946944fb455a78d3b83c41732978e4..53a0dc072cf0dcf125a5ef23b3f20980a9c8c29d 100644 --- a/ets2panda/ir/astNodeFlags.h +++ b/ets2panda/ir/astNodeFlags.h @@ -109,30 +109,6 @@ enum class ScriptFunctionFlags : uint32_t { enum class TSOperatorType { READONLY, KEYOF, UNIQUE }; enum class MappedOption { NO_OPTS, PLUS, MINUS }; -enum class BoxingUnboxingFlags : uint32_t { - NONE = 0U, - BOX_TO_BOOLEAN = 1U << 0U, - BOX_TO_BYTE = 1U << 1U, - BOX_TO_SHORT = 1U << 2U, - BOX_TO_CHAR = 1U << 3U, - BOX_TO_INT = 1U << 4U, - BOX_TO_LONG = 1U << 5U, - BOX_TO_FLOAT = 1U << 6U, - BOX_TO_DOUBLE = 1U << 7U, - BOX_TO_ENUM = 1U << 8U, - UNBOX_TO_BOOLEAN = 1U << 9U, - UNBOX_TO_BYTE = 1U << 10U, - UNBOX_TO_SHORT = 1U << 11U, - UNBOX_TO_CHAR = 1U << 12U, - UNBOX_TO_INT = 1U << 13U, - UNBOX_TO_LONG = 1U << 14U, - UNBOX_TO_FLOAT = 1U << 15U, - UNBOX_TO_DOUBLE = 1U << 16U, - BOXING_FLAG = BOX_TO_BOOLEAN | BOX_TO_BYTE | BOX_TO_SHORT | BOX_TO_CHAR | BOX_TO_INT | BOX_TO_LONG | BOX_TO_FLOAT | - BOX_TO_DOUBLE | BOX_TO_ENUM, - UNBOXING_FLAG = UNBOX_TO_BOOLEAN | UNBOX_TO_BYTE | UNBOX_TO_SHORT | UNBOX_TO_CHAR | UNBOX_TO_INT | UNBOX_TO_LONG | - UNBOX_TO_FLOAT | UNBOX_TO_DOUBLE, -}; } // namespace ark::es2panda::ir namespace enumbitops { @@ -149,10 +125,6 @@ template <> struct IsAllowedType : std::true_type { }; -template <> -struct IsAllowedType : std::true_type { -}; - } // namespace enumbitops #endif diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp index a3356c3c103d6a17d9f3d1eaad53923fad831539..a1443b6d73833466d8d8e4cac027a03d994f9eb5 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp @@ -107,7 +107,6 @@ void ETSNewArrayInstanceExpression::ClearPreferredType() { SetPreferredType(nullptr); SetTsType(nullptr); - TypeReference()->SetBoxingUnboxingFlags(BoxingUnboxingFlags::NONE); } void ETSNewArrayInstanceExpression::SetPreferredTypeBasedOnFuncParam(checker::ETSChecker *checker, checker::Type *param, diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp index a79d71241b0af99b3416c312c92d79ebd67b382e..3951ddfcc69cf3090db6acb8c1fdb837b6d7adcb 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp @@ -87,7 +87,6 @@ void ETSNewMultiDimArrayInstanceExpression::ClearPreferredType() { SetPreferredType(nullptr); SetTsType(nullptr); - TypeReference()->SetBoxingUnboxingFlags(BoxingUnboxingFlags::NONE); } ETSNewMultiDimArrayInstanceExpression::ETSNewMultiDimArrayInstanceExpression( diff --git a/ets2panda/ir/expressions/arrayExpression.cpp b/ets2panda/ir/expressions/arrayExpression.cpp index cc9ec6588560011295baac64bb84f597b5168aae..d65c4e0f3d86df65e32776f9ff12f464ef81b770 100644 --- a/ets2panda/ir/expressions/arrayExpression.cpp +++ b/ets2panda/ir/expressions/arrayExpression.cpp @@ -355,7 +355,6 @@ void ArrayExpression::ClearPreferredType() SetPreferredType(nullptr); SetTsType(nullptr); for (auto element : Elements()) { - element->SetBoxingUnboxingFlags(ir::BoxingUnboxingFlags::NONE); element->SetTsType(nullptr); element->SetAstNodeFlags(ir::AstNodeFlags::NO_OPTS); if (element->IsArrayExpression()) { diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index 8fb25780f2adff70bbb8c2fc07751f03701325dc..c15fd9b0758dd76b0fab334f7d46fba4834f7878 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -395,20 +395,8 @@ checker::Type *MemberExpression::CheckIndexAccessMethod(checker::ETSChecker *che checker::Type *MemberExpression::GetTypeOfTupleElement(checker::ETSChecker *checker, checker::Type *baseType) { ES2PANDA_ASSERT(baseType->IsETSTupleType()); - ir::Expression *expr = nullptr; - if (Property()->HasBoxingUnboxingFlags(ir::BoxingUnboxingFlags::UNBOXING_FLAG)) { - ES2PANDA_ASSERT(Property()->Variable()->Declaration()->Node()->AsClassElement()->Value()); - expr = Property()->Variable()->Declaration()->Node()->AsClassElement()->Value(); - } else { - expr = Property(); - } - - auto idxIfAny = checker->GetTupleElementAccessValue(expr); - if (!idxIfAny.has_value()) { - return nullptr; - } - - return baseType->AsETSTupleType()->GetTypeAtIndex(*idxIfAny); + auto const idxIfAny = checker->GetTupleElementAccessValue(Property()); + return idxIfAny.has_value() ? baseType->AsETSTupleType()->GetTypeAtIndex(*idxIfAny) : nullptr; } static void CastTupleElementFromClassMemberType(checker::ETSChecker *checker, diff --git a/ets2panda/ir/statements/returnStatement.cpp b/ets2panda/ir/statements/returnStatement.cpp index 67e8bd3a5f63c1a92cee712b398c494771dbd0a7..a14d55209022265152bc5a14a5507f8b11834a97 100644 --- a/ets2panda/ir/statements/returnStatement.cpp +++ b/ets2panda/ir/statements/returnStatement.cpp @@ -89,7 +89,6 @@ void ReturnStatement::SetReturnType(checker::ETSChecker *checker, checker::Type checker->LogError(diagnostic::INVALID_EXPR_IN_RETURN, {}, argument_->Start()); return; } - argument_->AddBoxingUnboxingFlags(checker->GetBoxingFlag(argumentType)); relation->SetNode(nullptr); } diff --git a/ets2panda/public/headers_parser/supported_types.py b/ets2panda/public/headers_parser/supported_types.py index be10e6eb989b06f89d3a2769433e6efdf34dd94c..3934a02ee85917fe490aaa3d31c72aa4fe24fb10 100644 --- a/ets2panda/public/headers_parser/supported_types.py +++ b/ets2panda/public/headers_parser/supported_types.py @@ -187,7 +187,6 @@ all_types_supported = [ "void", # enums "AstNodeFlags", - "BoxingUnboxingFlags", "ModifierFlags", "ScriptFunctionFlags", "TSOperatorType",