diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index a047c992aa488e77e5e29063dec0bab15d1340bf..8fa1c8ab96078f66734503421236d1189252cf51 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -365,7 +365,7 @@ void ETSLReference::SetValue() const } if (objectType->IsETSUnionType()) { - etsg_->StoreUnionProperty(Node(), baseReg_, propName); + etsg_->StoreUnionProperty(Node(), memberExprTsType, baseReg_, propName); return; } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 54425151d3a10cfb4cb5897830123d45ba336873..a5094b8d8ed59769b256c2534c358e4f97218632 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -464,11 +464,18 @@ void ETSGen::LoadProperty(const ir::AstNode *const node, const checker::Type *pr SetAccumulatorType(propType); } -void ETSGen::StoreUnionProperty([[maybe_unused]] const ir::AstNode *node, [[maybe_unused]] VReg objReg, +void ETSGen::StoreUnionProperty([[maybe_unused]] const ir::AstNode *node, + [[maybe_unused]] const checker::Type *propType, [[maybe_unused]] VReg objReg, [[maybe_unused]] const util::StringView &propName) { #ifdef PANDA_WITH_ETS - Ra().Emit(node, objReg, propName); + if (propType->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { + Ra().Emit(node, objReg, propName); + } else if (propType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + Ra().Emit(node, objReg, propName); + } else { + Ra().Emit(node, objReg, propName); + } #else UNREACHABLE(); #endif // PANDA_WITH_ETS @@ -479,7 +486,13 @@ void ETSGen::LoadUnionProperty([[maybe_unused]] const ir::AstNode *const node, [[maybe_unused]] const util::StringView &propName) { #ifdef PANDA_WITH_ETS - Ra().Emit(node, objReg, propName); + if (propType->HasTypeFlag(TYPE_FLAG_BYTECODE_REF)) { + Ra().Emit(node, objReg, propName); + } else if (propType->HasTypeFlag(checker::TypeFlag::ETS_WIDE_NUMERIC)) { + Ra().Emit(node, objReg, propName); + } else { + Ra().Emit(node, objReg, propName); + } SetAccumulatorType(propType); #else UNREACHABLE(); diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index b06ec78733004e7fb184246f7c6b96d7c5bff304..f4cf2f43dc84b449a6c1087b09f710635fdb6155 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -77,7 +77,8 @@ public: void StoreElementDynamic(const ir::AstNode *node, VReg objectReg, VReg index); void LoadElementDynamic(const ir::AstNode *node, VReg objectReg); - void StoreUnionProperty(const ir::AstNode *node, VReg objReg, const util::StringView &propName); + void StoreUnionProperty(const ir::AstNode *node, const checker::Type *propType, VReg objReg, + const util::StringView &propName); void LoadUnionProperty(const ir::AstNode *node, const checker::Type *propType, VReg objReg, const util::StringView &propName); diff --git a/ets2panda/test/runtime/ets/union_wide_property_access.ets b/ets2panda/test/runtime/ets/union_wide_property_access.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a496dcc79b3993efd8aeba4a2a21a7327c64145 --- /dev/null +++ b/ets2panda/test/runtime/ets/union_wide_property_access.ets @@ -0,0 +1,42 @@ +/* + * 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. + */ + +class A { memb: number = 2; } +class B { memb: number = 6; } +class C { memb: A|B = new A(); } + +function bar(a0: A | B): void { + a0.memb = 50; +} + +function foo(arr: Int8Array | Int16Array): void { + let len = arr.length + assert len == 42; +} + +function main() { + let buffer: ArrayBuffer = new ArrayBuffer(42); + let byteArr: Int8Array= new Int8Array(buffer) + foo(byteArr); + assert byteArr.length == 42; + + let ab: A|B = new A(); + bar(ab); + assert ab.memb == 50 + + let cClass: C = new C(); + cClass.memb = new B(); + assert cClass.memb.memb == 6; +} diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 7b6b2e0d97a8ed83bdb97e21f71a9007f3265ae9..b766e9e536ddca7bb1300e18b5745349f86bd8de 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -58,5 +58,9 @@ lambdaExpressionWithRestParameter.ets castSequence.ets # ignored due to interface implementation modification -local-class-standard-example1.ets +local-class-standard-example1.ets local-class-standard-example2.ets + +# verifier false positive for 64 bit instructions on union types. +# Issue: #16216 +union_wide_property_access.ets