diff --git a/ecmascript/global_env_constants.cpp b/ecmascript/global_env_constants.cpp index 8fafa36635..497f50b6bd 100644 --- a/ecmascript/global_env_constants.cpp +++ b/ecmascript/global_env_constants.cpp @@ -90,6 +90,11 @@ void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass) ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); SetConstant(ConstantIndex::HCLASS_CLASS_INDEX, JSTaggedValue(hClass)); + // To reverse the order, the hclass of string needs to load default supers + SetConstant(ConstantIndex::ARRAY_CLASS_INDEX, + factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_ARRAY)); + SetConstant(ConstantIndex::DEFAULT_SUPERS_INDEX, + WeakVector::Create(thread, SubtypingOperator::DEFAULT_SUPERS_CAPACITY, MemSpaceType::NON_MOVABLE)); SetConstant(ConstantIndex::FREE_OBJECT_WITH_NONE_FIELD_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, FreeObject::NEXT_OFFSET, JSType::FREE_OBJECT_WITH_NONE_FIELD)); SetConstant(ConstantIndex::FREE_OBJECT_WITH_ONE_FIELD_CLASS_INDEX, @@ -102,8 +107,6 @@ void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass) SetConstant(ConstantIndex::CONSTANT_STRING_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_STRING)); SetConstant(ConstantIndex::TREE_STRING_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TREE_STRING)); - SetConstant(ConstantIndex::ARRAY_CLASS_INDEX, - factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_ARRAY)); SetConstant(ConstantIndex::BYTE_ARRAY_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::BYTE_ARRAY)); SetConstant(ConstantIndex::CONSTANT_POOL_CLASS_INDEX, @@ -302,8 +305,6 @@ void GlobalEnvConstants::InitGlobalConstantSpecial(JSThread *thread) auto vm = thread->GetEcmaVM(); SetConstant(ConstantIndex::EMPTY_STRING_OBJECT_INDEX, JSTaggedValue(EcmaStringAccessor::CreateEmptyString(vm))); SetConstant(ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX, factory->NewEmptyArray()); - SetConstant(ConstantIndex::DEFAULT_SUPERS_INDEX, - WeakVector::Create(thread, SubtypingOperator::DEFAULT_SUPERS_CAPACITY)); SetConstant(ConstantIndex::EMPTY_LAYOUT_INFO_OBJECT_INDEX, factory->CreateLayoutInfo(0)); SetConstant(ConstantIndex::EMPTY_TAGGED_QUEUE_OBJECT_INDEX, factory->NewTaggedQueue(0)); } diff --git a/ecmascript/js_hclass.cpp b/ecmascript/js_hclass.cpp index 806b2ff6ff..f1867dea30 100644 --- a/ecmascript/js_hclass.cpp +++ b/ecmascript/js_hclass.cpp @@ -164,7 +164,8 @@ void JSHClass::Initialize(const JSThread *thread, uint32_t size, JSType type, ui void JSHClass::InitTSInheritInfo(const JSThread *thread) { // Supers and Level are used to record the relationship between TSHClass. - if (IsECMAObject()) { + if (ShouldSetDefaultSupers()) { + ASSERT(thread->GlobalConstants()->GetDefaultSupers().IsTaggedArray()); SetSupers(thread, thread->GlobalConstants()->GetDefaultSupers()); } else { SetSupers(thread, JSTaggedValue::Undefined()); diff --git a/ecmascript/js_hclass.h b/ecmascript/js_hclass.h index e0396465b0..ef40c3e882 100644 --- a/ecmascript/js_hclass.h +++ b/ecmascript/js_hclass.h @@ -540,6 +540,11 @@ public: return (JSType::ECMA_OBJECT_FIRST <= jsType && jsType <= JSType::ECMA_OBJECT_LAST); } + inline bool ShouldSetDefaultSupers() const + { + return IsECMAObject() || IsStringOrSymbol(); + } + inline bool IsRealm() const { return GetObjectType() == JSType::JS_REALM; diff --git a/ecmascript/weak_vector.cpp b/ecmascript/weak_vector.cpp index 93f904a3b3..968ec87be2 100644 --- a/ecmascript/weak_vector.cpp +++ b/ecmascript/weak_vector.cpp @@ -18,12 +18,17 @@ #include "ecmascript/object_factory.h" namespace panda::ecmascript { -JSHandle WeakVector::Create(const JSThread *thread, uint32_t capacity) +JSHandle WeakVector::Create(const JSThread *thread, uint32_t capacity, MemSpaceType type) { ASSERT(capacity < MAX_VECTOR_INDEX); uint32_t length = VectorToArrayIndex(capacity); - JSHandle vector = JSHandle(thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length)); + JSHandle vector; + if (type == MemSpaceType::NON_MOVABLE) { + vector = JSHandle(thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length, JSTaggedValue::Hole(), true)); + } else { + vector = JSHandle(thread->GetEcmaVM()->GetFactory()->NewTaggedArray(length)); + } vector->SetEnd(thread, 0); return vector; diff --git a/ecmascript/weak_vector.h b/ecmascript/weak_vector.h index dfeaa31f99..c48d1f6b30 100644 --- a/ecmascript/weak_vector.h +++ b/ecmascript/weak_vector.h @@ -35,7 +35,7 @@ public: static constexpr uint32_t DEFAULT_CAPACITY = 4; static constexpr uint32_t DEFAULT_GROW_SIZE = 4; - static JSHandle Create(const JSThread *thread, uint32_t capacity = DEFAULT_CAPACITY); + static JSHandle Create(const JSThread *thread, uint32_t capacity = DEFAULT_CAPACITY, MemSpaceType type = MemSpaceType::SEMI_SPACE); static JSHandle Grow(const JSThread *thread, const JSHandle &old, uint32_t newCapacity); static JSHandle Append(const JSThread *thread, const JSHandle &vec, const JSHandle &value, ElementType type = ElementType::NORMAL); diff --git a/test/aottest/BUILD.gn b/test/aottest/BUILD.gn index 3cdaf6e2e5..e50539e6e8 100644 --- a/test/aottest/BUILD.gn +++ b/test/aottest/BUILD.gn @@ -74,6 +74,7 @@ group("ark_aot_ts_test") { "createobjectwithexcludedkeys", "createregexpwithliteral", "dec", + "default_supers", "defineasyncfunc", "defineclasswithbuffer", "defineclass", diff --git a/test/aottest/default_supers/BUILD.gn b/test/aottest/default_supers/BUILD.gn new file mode 100644 index 0000000000..3286d211bf --- /dev/null +++ b/test/aottest/default_supers/BUILD.gn @@ -0,0 +1,17 @@ +# 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. +import("//arkcompiler/ets_runtime/test/test_helper.gni") + +host_aot_test_action("default_supers") { + deps = [] +} diff --git a/test/aottest/default_supers/default_supers.ts b/test/aottest/default_supers/default_supers.ts new file mode 100644 index 0000000000..f572f5a085 --- /dev/null +++ b/test/aottest/default_supers/default_supers.ts @@ -0,0 +1,31 @@ +/* + * 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. + */ +class A { + a:number = 1; +} +class B { + foo(a : A) { + print(a.a); + } +} +let b = new B(); +let a = new A(); +print(1); +a = "aaaaa"; +b.foo(a); +print(2); +a = Symbol(); +b.foo(a); +print(3); diff --git a/test/aottest/default_supers/expect_output.txt b/test/aottest/default_supers/expect_output.txt new file mode 100644 index 0000000000..0cc36b9f8e --- /dev/null +++ b/test/aottest/default_supers/expect_output.txt @@ -0,0 +1,18 @@ +# 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. + +1 +undefined +2 +undefined +3