From 967c3f9f8ea2c86afb9d7fb8fd416cb10029d2a8 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Mon, 21 Jul 2025 15:46:55 +0800 Subject: [PATCH] Fix Lambda Recevier Classlinker Error Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICNPIS Description: Incorrectly unboxed the call_receiver type within the lambda object; the receiver must be an object, not a primitive type. For the receiver object, there is no need to unbox the BUILT_IN type. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- .../compiler/lowering/ets/lambdaLowering.cpp | 3 +++ .../compiler/lowering/ets/unboxLowering.cpp | 4 +++ ets2panda/ir/expressions/identifier.h | 11 ++++++++ .../test/runtime/ets/boxing_receiver.ets | 25 +++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 ets2panda/test/runtime/ets/boxing_receiver.ets diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 467b360b00..60a76f9dcc 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -464,6 +464,9 @@ static void CreateLambdaClassFields(public_lib::Context *ctx, ir::ClassDefinitio if (info->callReceiver != nullptr) { auto *outerThisDeclaration = parser->CreateFormattedClassFieldDefinition( "@@I1: @@T2", "$this", objectType->Substitute(checker->Relation(), substitution)); + ES2PANDA_ASSERT(outerThisDeclaration->IsClassProperty() && + outerThisDeclaration->AsClassProperty()->Key()->IsIdentifier()); + outerThisDeclaration->AsClassProperty()->Key()->AsIdentifier()->SetCallReceiver(); props.push_back(outerThisDeclaration); } diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 0e5299b822..8b6e9c458d 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -322,6 +322,10 @@ static void HandleClassProperty(UnboxContext *uctx, ir::ClassProperty *prop, boo if (propType == nullptr) { propType = prop->Key()->Variable()->TsType(); } + // Receiver must be an object, it should not be unboxed. + if (prop->Id()->IsCallReceiver()) { + return; + } // Primitive Types from JS should be Boxed, but in case of annotation, it should be unboxed. ir::AstNode *node = prop; while (node != nullptr && !node->IsETSModule()) { diff --git a/ets2panda/ir/expressions/identifier.h b/ets2panda/ir/expressions/identifier.h index 6f8814018b..c4f7d5f27d 100644 --- a/ets2panda/ir/expressions/identifier.h +++ b/ets2panda/ir/expressions/identifier.h @@ -39,6 +39,7 @@ enum class IdentifierFlags : uint32_t { ANNOTATIONDECL = 1U << 6U, ANNOTATIONUSAGE = 1U << 7U, ERROR_PLACEHOLDER = 1U << 8U, + CALL_RECEIVER = 1U << 9U, }; } // namespace ark::es2panda::ir @@ -188,6 +189,16 @@ public: AddIdFlags(IdentifierFlags::ANNOTATIONUSAGE); } + void SetCallReceiver() noexcept + { + AddIdFlags(IdentifierFlags::CALL_RECEIVER); + } + + [[nodiscard]] bool IsCallReceiver() const noexcept + { + return (IdFlags() & IdentifierFlags::CALL_RECEIVER) != 0; + } + void AddDecorators([[maybe_unused]] ArenaVector &&decorators) override { GetOrCreateHistoryNodeAs()->decorators_ = std::move(decorators); diff --git a/ets2panda/test/runtime/ets/boxing_receiver.ets b/ets2panda/test/runtime/ets/boxing_receiver.ets new file mode 100644 index 0000000000..948cd3f3be --- /dev/null +++ b/ets2panda/test/runtime/ets/boxing_receiver.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 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. + */ + +function main() { + let count = 0; + let tmp: Int = 0; + let initalArray = new Array(1, 2, 3, 4); + for (tmp of initalArray) { + let a = tmp.intValue + count++; + } + arktest.assertEQ(count, 4) +} -- Gitee