diff --git a/checker/ets/helpers.cpp b/checker/ets/helpers.cpp index d8417228b46d5ae5a1133b84f46a5fd42e16d848..898ed600dfac94e6e9fbdb0ca2eb049ee3e4b447 100644 --- a/checker/ets/helpers.cpp +++ b/checker/ets/helpers.cpp @@ -344,7 +344,8 @@ void ETSChecker::ValidateResolvedIdentifier(ir::Identifier *const ident, binder: } if (!resolved_type->IsETSObjectType() && !resolved_type->IsETSArrayType() && - !resolved_type->IsETSEnumType() && !resolved_type->IsETSStringEnumType()) { + !resolved_type->IsETSEnumType() && !resolved_type->IsETSStringEnumType() && + !resolved_type->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { throw_error(); } diff --git a/ir/expressions/callExpression.cpp b/ir/expressions/callExpression.cpp index 715e0706569785690eee7665cbfe1f27d625e376..7085d0ed4f82cea5405f28296bad95c45407cb81 100644 --- a/ir/expressions/callExpression.cpp +++ b/ir/expressions/callExpression.cpp @@ -258,6 +258,10 @@ void CallExpression::Compile(compiler::ETSGen *etsg) const // Helper function to avoid branching in non optional cases auto emit_arguments = [this, etsg, is_static, is_dynamic, &callee_reg, &dyn_param2]() { + if (callee_->GetBoxingUnboxingFlags() != ir::BoxingUnboxingFlags::NONE) { + etsg->ApplyConversionAndStoreAccumulator(callee_, callee_reg, nullptr); + } + if (is_dynamic) { etsg->CallDynamic(this, callee_reg, dyn_param2, signature_, arguments_); } else if (is_static) { diff --git a/ir/expressions/memberExpression.cpp b/ir/expressions/memberExpression.cpp index 6789de0bfbd4157634287be1f72030e85efe57d0..6522eaf5d8bb35c20afe3c6aaa8097581f73d113 100644 --- a/ir/expressions/memberExpression.cpp +++ b/ir/expressions/memberExpression.cpp @@ -368,7 +368,7 @@ checker::Type *MemberExpression::Check(checker::ETSChecker *checker) checker::Type *const base_type = object_->Check(checker); - if (!base_type->IsETSObjectType()) { + if (!base_type->IsETSObjectType() && !base_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { if (base_type->IsETSArrayType() && property_->AsIdentifier()->Name().Is("length")) { SetTsType(checker->GlobalIntType()); return TsType(); @@ -398,7 +398,13 @@ checker::Type *MemberExpression::Check(checker::ETSChecker *checker) checker->ThrowTypeError({"Cannot access property of non-object or non-enum type"}, object_->Start()); } - obj_type_ = base_type->AsETSObjectType(); + if (base_type->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { + checker->Relation()->SetNode(this); + obj_type_ = checker->PrimitiveTypeAsETSBuiltinType(base_type)->AsETSObjectType(); + checker->AddBoxingUnboxingFlagToNode(this, obj_type_); + } else { + obj_type_ = base_type->AsETSObjectType(); + } auto resolve_res = checker->ResolveMemberReference(this, obj_type_); ASSERT(!resolve_res.empty()); checker::Type *type_to_set = nullptr; diff --git a/test/runtime/ets/autoboxing.ets b/test/runtime/ets/autoboxing.ets new file mode 100644 index 0000000000000000000000000000000000000000..f66dbbb41beb1e59fbe8b454950c4bdca77c0a9d --- /dev/null +++ b/test/runtime/ets/autoboxing.ets @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 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 foo_i(value: int): string { + return value.toString(); +} + +function foo_d(value: double): string { + return value.toString(); +} + +function foo_n(value: number): string { + return value.toString(); +} + +function main(): void { + let str_i: string = foo_i(4); + assert str_i == "4"; + let str_d: string = foo_d(3.14); + assert str_d == "3.14"; + let str_n: string = foo_n(5); + assert str_n == "5"; +} \ No newline at end of file