diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 3d97acae289e59b3908657466042bc35b32c07b1..3301a597b1fda40167f1302443c178ffd6c9fef4 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -24,6 +24,7 @@ #include "checker/types/globalTypesHolder.h" #include "compiler/lowering/util.h" #include "util/es2pandaMacros.h" +#include "generated/signatures.h" namespace ark::es2panda::compiler { @@ -49,9 +50,6 @@ struct UnboxContext { // NOLINTEND(misc-non-private-member-variables-in-classes) }; -// NOLINTNEXTLINE(readability-identifier-naming) -char const *UNBOXER_METHOD_NAME = "unboxed"; - bool AnyOfElementTypes(checker::Type *type, const std::function &isFunc) { auto const anyOf = [&isFunc](ArenaVector const &list) { @@ -342,6 +340,36 @@ static void HandleDeclarationNode(UnboxContext *uctx, ir::AstNode *ast) /// uctx->handled.insert(ast); } +std::string_view GetUnboxerMethodName(const checker::Type *unboxedType) +{ + if (unboxedType->IsETSBooleanType()) { + return Signatures::BOOLEAN_CAST; + } + if (unboxedType->IsByteType()) { + return Signatures::BYTE_CAST; + } + // NOTE(pronaip): #29054 Remove IsCharType once stdlib stops using legacy JS type + if (unboxedType->IsETSCharType() || unboxedType->IsCharType()) { + return Signatures::CHAR_CAST; + } + if (unboxedType->IsDoubleType()) { + return Signatures::DOUBLE_CAST; + } + if (unboxedType->IsFloatType()) { + return Signatures::FLOAT_CAST; + } + if (unboxedType->IsIntType()) { + return Signatures::INT_CAST; + } + if (unboxedType->IsLongType()) { + return Signatures::LONG_CAST; + } + if (unboxedType->IsShortType()) { + return Signatures::SHORT_CAST; + } + ES2PANDA_UNREACHABLE(); +} + static ir::Expression *InsertUnboxing(UnboxContext *uctx, ir::Expression *expr) { auto *boxedType = expr->TsType(); @@ -363,7 +391,9 @@ static ir::Expression *InsertUnboxing(UnboxContext *uctx, ir::Expression *expr) return ret; } - auto *methodId = allocator->New(UNBOXER_METHOD_NAME, allocator); + const std::string_view unboxerName = GetUnboxerMethodName(unboxedType); + + auto *methodId = allocator->New(unboxerName, allocator); auto *mexpr = util::NodeAllocator::ForceSetParent( allocator, expr, methodId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *call = util::NodeAllocator::ForceSetParent( @@ -425,13 +455,21 @@ static ir::Expression *CreateToIntrinsicCallExpression(UnboxContext *uctx, check static bool CheckIfOnTopOfUnboxing(UnboxContext *uctx, ir::Expression *expr, checker::Type *boxedType) { - return expr->IsCallExpression() && expr->AsCallExpression()->Arguments().empty() && - expr->AsCallExpression()->Callee()->IsMemberExpression() && - expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->IsIdentifier() && - expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->AsIdentifier()->Name() == - UNBOXER_METHOD_NAME && - uctx->checker->Relation()->IsIdenticalTo( - expr->AsCallExpression()->Callee()->AsMemberExpression()->Object()->TsType(), boxedType); + constexpr std::array UNBOXER_METHOD_NAMES { + Signatures::BOOLEAN_CAST, Signatures::BYTE_CAST, Signatures::CHAR_CAST, Signatures::DOUBLE_CAST, + Signatures::FLOAT_CAST, Signatures::INT_CAST, Signatures::LONG_CAST, Signatures::SHORT_CAST, + }; + if (expr->IsCallExpression() && expr->AsCallExpression()->Arguments().empty() && + expr->AsCallExpression()->Callee()->IsMemberExpression() && + expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->IsIdentifier()) { + const util::StringView &name = + expr->AsCallExpression()->Callee()->AsMemberExpression()->Property()->AsIdentifier()->Name(); + return UNBOXER_METHOD_NAMES.cend() != std::find_if(UNBOXER_METHOD_NAMES.cbegin(), UNBOXER_METHOD_NAMES.cend(), + [&name](const auto &hay) { return name.Is(hay); }) && + uctx->checker->Relation()->IsIdenticalTo( + expr->AsCallExpression()->Callee()->AsMemberExpression()->Object()->TsType(), boxedType); + } + return false; } static ir::Expression *LinkUnboxingExpr(ir::Expression *expr, ir::AstNode *parent) diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index 41a3720127681d2a03ee8edccf1bae8ce994bfa9..468a7154ae98ba613a45d75ab36dc174a86c48a4 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -224,6 +224,8 @@ defines: ref: MIN_ARGSCOUNT_OF_FUNC - name: 'gensym%%_anonymous_const' ref: EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY + - name: 'toBoolean' + ref: BOOLEAN_CAST - name: 'toByte' ref: BYTE_CAST - name: 'toShort'