From 0b26cfdb59fda59ed6b71d81a37ac0481f68009f Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Wed, 3 May 2023 14:41:47 +0300 Subject: [PATCH] Implement EtsClassLinker Signed-off-by: Vyacheslav Cherkashin --- plugins/ets/ets_plugin_options.yaml | 2 +- plugins/ets/runtime/CMakeLists.txt | 2 + plugins/ets/runtime/ets_class_linker.cpp | 56 +++++++++++++++++ plugins/ets/runtime/ets_class_linker.h | 61 +++++++++++++++++++ .../runtime/ets_class_linker_extension.cpp | 4 +- .../ets/runtime/ets_class_linker_extension.h | 20 +++--- plugins/ets/runtime/ets_class_root.h | 51 ++++++++++++++++ plugins/ets/runtime/ets_itable_builder.cpp | 4 +- plugins/ets/runtime/ets_itable_builder.h | 6 +- plugins/ets/runtime/ets_language_context.cpp | 4 +- plugins/ets/runtime/ets_language_context.h | 4 +- plugins/ets/runtime/ets_vm.cpp | 12 ++++ plugins/ets/runtime/ets_vm.h | 17 ++---- plugins/ets/runtime/ets_vtable_builder.cpp | 4 +- plugins/ets/runtime/ets_vtable_builder.h | 4 +- .../ets/runtime/interpreter/interpreter-inl.h | 12 ++-- .../napi/ets_napi_native_interface.cpp | 9 ++- plugins/ets/runtime/types/ets_array.h | 35 ++++++----- plugins/ets/runtime/types/ets_class.cpp | 23 ++++--- plugins/ets/runtime/types/ets_method.cpp | 25 ++++---- plugins/ets/runtime/types/ets_method.h | 2 +- plugins/ets/runtime/types/ets_promise.cpp | 30 +++++++++ plugins/ets/runtime/types/ets_promise.h | 4 ++ plugins/ets/subproject_sources.gn | 2 + .../tests/runtime/types/ets_array_test.cpp | 20 +++--- .../tests/runtime/types/ets_promise_test.cpp | 13 +--- 26 files changed, 319 insertions(+), 107 deletions(-) create mode 100644 plugins/ets/runtime/ets_class_linker.cpp create mode 100644 plugins/ets/runtime/ets_class_linker.h create mode 100644 plugins/ets/runtime/ets_class_root.h create mode 100644 plugins/ets/runtime/types/ets_promise.cpp diff --git a/plugins/ets/ets_plugin_options.yaml b/plugins/ets/ets_plugin_options.yaml index 6438e5a16..642b2fde4 100644 --- a/plugins/ets/ets_plugin_options.yaml +++ b/plugins/ets/ets_plugin_options.yaml @@ -13,7 +13,7 @@ - ETS: lang_enum_id: 5 - lang_context_class: panda::EtsLanguageContext + lang_context_class: panda::ets::EtsLanguageContext lang_context_header_path: plugins/ets/runtime/ets_language_context.h additional_interpter_inl: plugins/ets/runtime/interpreter/interpreter-inl.h language_config: diff --git a/plugins/ets/runtime/CMakeLists.txt b/plugins/ets/runtime/CMakeLists.txt index 71c7fd558..d42358612 100644 --- a/plugins/ets/runtime/CMakeLists.txt +++ b/plugins/ets/runtime/CMakeLists.txt @@ -18,6 +18,7 @@ option(PANDA_LINK_ICU "Enable linking with icu third party library" true) panda_promote_to_definitions(USE_ETS_NAPI_CRITICAL_BY_DEFAULT) set(ETS_RUNTIME_SOURCES + ${ETS_EXT_SOURCES}/ets_class_linker.cpp ${ETS_EXT_SOURCES}/ets_class_linker_extension.cpp ${ETS_EXT_SOURCES}/ets_language_context.cpp ${ETS_EXT_SOURCES}/ets_napi_env.cpp @@ -48,6 +49,7 @@ set(ETS_RUNTIME_SOURCES ${ETS_EXT_SOURCES}/types/ets_class.cpp ${ETS_EXT_SOURCES}/types/ets_field.cpp ${ETS_EXT_SOURCES}/types/ets_method.cpp + ${ETS_EXT_SOURCES}/types/ets_promise.cpp ${ETS_EXT_SOURCES}/ets_vm_api.cpp ) diff --git a/plugins/ets/runtime/ets_class_linker.cpp b/plugins/ets/runtime/ets_class_linker.cpp new file mode 100644 index 000000000..4d05937a7 --- /dev/null +++ b/plugins/ets/runtime/ets_class_linker.cpp @@ -0,0 +1,56 @@ +/** + * 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. + */ + +#include "plugins/ets/runtime/ets_class_linker.h" +#include "plugins/ets/runtime/ets_class_linker_extension.h" +#include "plugins/ets/runtime/types/ets_class.h" + +namespace panda::ets { + +EtsClassLinker::EtsClassLinker(ClassLinker *class_linker) : class_linker_(class_linker) {} + +/*static*/ +Expected, PandaString> EtsClassLinker::Create(ClassLinker *class_linker) +{ + PandaUniquePtr ets_class_linker = MakePandaUnique(class_linker); + return Expected, PandaString>(std::move(ets_class_linker)); +} + +bool EtsClassLinker::Initialize() +{ + ClassLinkerExtension *ext = class_linker_->GetExtension(panda_file::SourceLang::ETS); + ext_ = EtsClassLinkerExtension::FromCoreType(ext); + return true; +} + +EtsClass *EtsClassLinker::GetClassRoot(EtsClassRoot root) const +{ + return EtsClass::FromRuntimeClass(ext_->GetClassRoot(static_cast(root))); +} + +EtsClass *EtsClassLinker::GetClass(const char *name, bool need_copy_descriptor, + ClassLinkerContext *class_linker_context, ClassLinkerErrorHandler *error_handler) +{ + const uint8_t *class_descriptor = utf::CStringAsMutf8(name); + Class *cls = ext_->GetClass(class_descriptor, need_copy_descriptor, class_linker_context, error_handler); + return EtsClass::FromRuntimeClass(cls); +} + +EtsClass *EtsClassLinker::GetPromiseClass() +{ + return EtsClass::FromRuntimeClass(ext_->GetPromiseClass()); +} + +} // namespace panda::ets diff --git a/plugins/ets/runtime/ets_class_linker.h b/plugins/ets/runtime/ets_class_linker.h new file mode 100644 index 000000000..87a5c79e4 --- /dev/null +++ b/plugins/ets/runtime/ets_class_linker.h @@ -0,0 +1,61 @@ +/** + * 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. + */ + +#ifndef PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_H_ +#define PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_H_ + +#include "plugins/ets/runtime/ets_class_root.h" +#include "runtime/include/mem/panda_smart_pointers.h" +#include "runtime/include/mem/panda_string.h" + +namespace panda { +class ClassLinker; +class ClassLinkerContext; +class ClassLinkerErrorHandler; +} // namespace panda + +namespace panda::ets { + +class EtsClass; +class EtsClassLinkerExtension; + +class EtsClassLinker { +public: + static Expected, PandaString> Create(ClassLinker *class_linker); + ~EtsClassLinker() = default; + + bool Initialize(); + + EtsClass *GetClassRoot(EtsClassRoot root) const; + EtsClass *GetClass(const char *name, bool need_copy_descriptor = false, + ClassLinkerContext *class_linker_context = nullptr, + ClassLinkerErrorHandler *error_handler = nullptr); + EtsClass *GetPromiseClass(); + + NO_COPY_SEMANTIC(EtsClassLinker); + NO_MOVE_SEMANTIC(EtsClassLinker); + +private: + explicit EtsClassLinker(ClassLinker *class_linker); + + ClassLinker *class_linker_ {}; + EtsClassLinkerExtension *ext_ {}; + + friend class mem::Allocator; +}; + +} // namespace panda::ets + +#endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_H_ diff --git a/plugins/ets/runtime/ets_class_linker_extension.cpp b/plugins/ets/runtime/ets_class_linker_extension.cpp index 887afdc60..af72cd1f5 100644 --- a/plugins/ets/runtime/ets_class_linker_extension.cpp +++ b/plugins/ets/runtime/ets_class_linker_extension.cpp @@ -31,7 +31,7 @@ #include "ets_class_linker_extension.h" #include "ets_utils.h" -namespace panda { +namespace panda::ets { namespace { enum class EtsNapiType { GENERIC, // - Switches the coroutine to native mode (GC is allowed) @@ -497,4 +497,4 @@ size_t EtsClassLinkerExtension::GetClassObjectSizeFromClassSize(uint32_t size) { return ets::EtsClass::GetSize(size); } -} // namespace panda +} // namespace panda::ets diff --git a/plugins/ets/runtime/ets_class_linker_extension.h b/plugins/ets/runtime/ets_class_linker_extension.h index 324cdeb40..c06a4554c 100644 --- a/plugins/ets/runtime/ets_class_linker_extension.h +++ b/plugins/ets/runtime/ets_class_linker_extension.h @@ -32,6 +32,10 @@ class Class; class Method; class ObjectHeader; +} // namespace panda + +namespace panda::ets { + class EtsClassLinkerExtension : public ClassLinkerExtension { public: EtsClassLinkerExtension() : ClassLinkerExtension(panda_file::SourceLang::ETS) {} @@ -81,7 +85,7 @@ public: return nullptr; } - return ets::EtsClass::FromRuntimeClass(klass); + return EtsClass::FromRuntimeClass(klass); } ets::EtsClass *GetEtsClass(const PandaString &name, bool need_copy_descriptor = true, @@ -90,12 +94,6 @@ public: return GetEtsClass(name.c_str(), need_copy_descriptor, context, error_handler); } - static EtsClassLinkerExtension *GetEtsClassLinkerExtension() - { - return reinterpret_cast( - Runtime::GetCurrent()->GetClassLinker()->GetExtension(panda_file::SourceLang::ETS)); - } - Class *FromClassObject(panda::ObjectHeader *obj) override; size_t GetClassObjectSizeFromClassSize(uint32_t size) override; @@ -104,6 +102,12 @@ public: return promise_class_; } + static EtsClassLinkerExtension *FromCoreType(ClassLinkerExtension *ext) + { + ASSERT(ext->GetLanguage() == panda_file::SourceLang::ETS); + return static_cast(ext); + } + NO_COPY_SEMANTIC(EtsClassLinkerExtension); NO_MOVE_SEMANTIC(EtsClassLinkerExtension); @@ -127,6 +131,6 @@ private: Class *promise_class_ = nullptr; }; -} // namespace panda +} // namespace panda::ets #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_LINKER_EXTENSION_H_ diff --git a/plugins/ets/runtime/ets_class_root.h b/plugins/ets/runtime/ets_class_root.h new file mode 100644 index 000000000..2b4c73240 --- /dev/null +++ b/plugins/ets/runtime/ets_class_root.h @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2021-2022 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. + */ +#ifndef PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_ROOT_H_ +#define PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_ROOT_H_ + +#include "libpandabase/utils/type_helpers.h" +#include "runtime/include/class_root.h" + +namespace panda::ets { + +enum class EtsClassRoot { + VOID = helpers::ToUnderlying(panda::ClassRoot::V), + BOOLEAN = helpers::ToUnderlying(panda::ClassRoot::U1), + BYTE = helpers::ToUnderlying(panda::ClassRoot::I8), + CHAR = helpers::ToUnderlying(panda::ClassRoot::U16), + SHORT = helpers::ToUnderlying(panda::ClassRoot::I16), + INT = helpers::ToUnderlying(panda::ClassRoot::I32), + LONG = helpers::ToUnderlying(panda::ClassRoot::I64), + FLOAT = helpers::ToUnderlying(panda::ClassRoot::F32), + DOUBLE = helpers::ToUnderlying(panda::ClassRoot::F64), + + BOOLEAN_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_U1), + BYTE_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_I8), + CHAR_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_U16), + SHORT_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_I16), + INT_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_I32), + LONG_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_I64), + FLOAT_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_F32), + DOUBLE_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_F64), + + CLASS = helpers::ToUnderlying(panda::ClassRoot::CLASS), + OBJECT = helpers::ToUnderlying(panda::ClassRoot::OBJECT), + STRING = helpers::ToUnderlying(panda::ClassRoot::STRING), + STRING_ARRAY = helpers::ToUnderlying(panda::ClassRoot::ARRAY_STRING), +}; + +} // namespace panda::ets + +#endif // PANDA_PLUGINS_ETS_RUNTIME_ETS_CLASS_ROOT_H_ diff --git a/plugins/ets/runtime/ets_itable_builder.cpp b/plugins/ets/runtime/ets_itable_builder.cpp index 3a1a53fa0..1d78948c9 100644 --- a/plugins/ets/runtime/ets_itable_builder.cpp +++ b/plugins/ets/runtime/ets_itable_builder.cpp @@ -33,7 +33,7 @@ #include "runtime/include/exceptions.h" #include "runtime/include/mem/panda_containers.h" -namespace panda { +namespace panda::ets { static Method *FindMethodInVTable(Class *klass, Method *method) { @@ -180,4 +180,4 @@ void EtsITableBuilder::DumpITable([[maybe_unused]] Class *klass) #endif // NDEBUG } -} // namespace panda +} // namespace panda::ets diff --git a/plugins/ets/runtime/ets_itable_builder.h b/plugins/ets/runtime/ets_itable_builder.h index 07bc739be..10c97deca 100644 --- a/plugins/ets/runtime/ets_itable_builder.h +++ b/plugins/ets/runtime/ets_itable_builder.h @@ -25,6 +25,10 @@ namespace panda { class ClassLinker; +} // namespace panda + +namespace panda::ets { + class EtsITableBuilder : public ITableBuilder { public: void Build(ClassLinker *class_linker, Class *base, Span class_interfaces, bool is_interface) override; @@ -44,6 +48,6 @@ private: ITable itable_; }; -} // namespace panda +} // namespace panda::ets #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_ITABLE_BUILDER_H_ diff --git a/plugins/ets/runtime/ets_language_context.cpp b/plugins/ets/runtime/ets_language_context.cpp index 687610667..ddc8fe373 100644 --- a/plugins/ets/runtime/ets_language_context.cpp +++ b/plugins/ets/runtime/ets_language_context.cpp @@ -47,7 +47,7 @@ #include "ets_utils.h" #include "ets_vtable_builder.h" -namespace panda { +namespace panda::ets { static Class *GetExceptionClass(ManagedThread *thread, const uint8_t *mutf8_name) { @@ -199,4 +199,4 @@ VerificationInitAPI EtsLanguageContext::GetVerificationInitAPI() const return v_api; } -} // namespace panda +} // namespace panda::ets diff --git a/plugins/ets/runtime/ets_language_context.h b/plugins/ets/runtime/ets_language_context.h index 401292019..1baf1ccd0 100644 --- a/plugins/ets/runtime/ets_language_context.h +++ b/plugins/ets/runtime/ets_language_context.h @@ -42,7 +42,7 @@ #include "ets_class_linker_extension.h" #include "ets_vm.h" -namespace panda { +namespace panda::ets { class EtsLanguageContext : public LanguageContextBase { public: @@ -337,6 +337,6 @@ public: } }; -} // namespace panda +} // namespace panda::ets #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_LANGUAGE_CONTEXT_H_ diff --git a/plugins/ets/runtime/ets_vm.cpp b/plugins/ets/runtime/ets_vm.cpp index 2384a717d..e35797b6c 100644 --- a/plugins/ets/runtime/ets_vm.cpp +++ b/plugins/ets/runtime/ets_vm.cpp @@ -104,6 +104,14 @@ Expected PandaEtsVM::Create(Runtime *runtime, const R return Unexpected(PandaString("Cannot create PandaCoreVM")); } + auto class_linker = EtsClassLinker::Create(runtime->GetClassLinker()); + if (!class_linker) { + allocator->Delete(vm); + mem::MemoryManager::Destroy(mm); + return Unexpected(class_linker.Error()); + } + vm->class_linker_ = std::move(class_linker.Value()); + vm->InitializeGC(); std::string icu_path = options.GetIcuDataPath(); @@ -197,6 +205,10 @@ bool PandaEtsVM::Initialize() return false; } + if (!class_linker_->Initialize()) { + LOG(FATAL, ETS) << "Cannot initialize ets class linker"; + } + if (Runtime::GetCurrent()->GetOptions().ShouldLoadBootPandaFiles()) { auto ctx = ets::utils::GetLanguageContext(); auto cls = ets::utils::GetClassLinkerExtension()->GetClass(ctx.GetOutOfMemoryErrorClassDescriptor()); diff --git a/plugins/ets/runtime/ets_vm.h b/plugins/ets/runtime/ets_vm.h index b43d2fa1d..57397e0ae 100644 --- a/plugins/ets/runtime/ets_vm.h +++ b/plugins/ets/runtime/ets_vm.h @@ -36,7 +36,6 @@ #include "runtime/include/panda_vm.h" #include "runtime/include/runtime_options.h" #include "runtime/include/runtime.h" -#include "runtime/include/class_linker.h" #include "runtime/mem/gc/gc_stats.h" #include "runtime/mem/gc/gc_trigger.h" #include "runtime/mem/gc/gc.h" @@ -48,6 +47,7 @@ #include "runtime/monitor_pool.h" #include "runtime/string_table.h" #include "runtime/thread_manager.h" +#include "plugins/ets/runtime/ets_class_linker.h" #include "plugins/ets/runtime/ets_coroutine.h" #include "runtime/coroutine_manager.h" #include "plugins/ets/runtime/ets_native_library_provider.h" @@ -115,11 +115,6 @@ public: return runtime_; } - panda::ClassLinker *GetClassLinker() const - { - return Runtime::GetCurrent()->GetClassLinker(); - } - mem::HeapManager *GetHeapManager() const override { ASSERT(mm_ != nullptr); @@ -150,10 +145,10 @@ public: return mm_->GetGCStats(); } - // EtsClassLinker *GetClassLinker() const - // { - // return class_linker_.get(); - // } + EtsClassLinker *GetClassLinker() const + { + return class_linker_.get(); + } mem::GlobalObjectStorage *GetGlobalObjectStorage() const override { @@ -237,7 +232,7 @@ private: Runtime *runtime_ {nullptr}; mem::MemoryManager *mm_ {nullptr}; - // PandaUniquePtr class_linker_; + PandaUniquePtr class_linker_; mem::ReferenceProcessor *reference_processor_ {nullptr}; PandaVector gc_roots_; Rendezvous *rendezvous_ {nullptr}; diff --git a/plugins/ets/runtime/ets_vtable_builder.cpp b/plugins/ets/runtime/ets_vtable_builder.cpp index 56a155cb4..893af540f 100644 --- a/plugins/ets/runtime/ets_vtable_builder.cpp +++ b/plugins/ets/runtime/ets_vtable_builder.cpp @@ -17,7 +17,7 @@ #include "runtime/include/class_linker.h" -namespace panda { +namespace panda::ets { bool EtsVTableOverridePred::IsInSamePackage(const MethodInfo &info1, const MethodInfo &info2) const { @@ -57,4 +57,4 @@ bool EtsVTableOverridePred::IsInSamePackage(const MethodInfo &info1, const Metho return is_same_package; } -} // namespace panda +} // namespace panda::ets diff --git a/plugins/ets/runtime/ets_vtable_builder.h b/plugins/ets/runtime/ets_vtable_builder.h index f7d130d87..168639d12 100644 --- a/plugins/ets/runtime/ets_vtable_builder.h +++ b/plugins/ets/runtime/ets_vtable_builder.h @@ -21,7 +21,7 @@ #include "runtime/include/vtable_builder-inl.h" -namespace panda { +namespace panda::ets { struct EtsVTableSearchBySignature { bool operator()(const MethodInfo &info1, const MethodInfo &info2) const @@ -65,6 +65,6 @@ struct EtsVTableOverridePred { using EtsVTableBuilder = VTableBuilderImpl; -} // namespace panda +} // namespace panda::ets #endif // !PANDA_PLUGINS_ETS_RUNTIME_ETS_ITABLE_BUILDER_H_ diff --git a/plugins/ets/runtime/interpreter/interpreter-inl.h b/plugins/ets/runtime/interpreter/interpreter-inl.h index f2f015786..de2fce298 100644 --- a/plugins/ets/runtime/interpreter/interpreter-inl.h +++ b/plugins/ets/runtime/interpreter/interpreter-inl.h @@ -20,6 +20,8 @@ #include "runtime/interpreter/interpreter-inl.h" #include "runtime/mem/internal_allocator.h" #include "plugins/ets/runtime/ets_class_linker_extension.h" +#include "plugins/ets/runtime/ets_coroutine.h" +#include "plugins/ets/runtime/ets_vm.h" #include "plugins/ets/runtime/types/ets_promise.h" #include "runtime/mem/refstorage/global_object_storage.h" @@ -135,21 +137,21 @@ private: FillArgs(args); // this promise is going to be resolved on coro completion - Class *promise_class = EtsClassLinkerExtension::GetEtsClassLinkerExtension()->GetPromiseClass(); - auto *promise = reinterpret_cast(RuntimeIfaceT::CreateObject(promise_class)); + EtsCoroutine *coroutine = EtsCoroutine::GetCurrent(); + EtsPromise *promise = EtsPromise::Create(coroutine); if (UNLIKELY(promise == nullptr)) { this->MoveToExceptionHandler(); return; } - auto promise_ref = - Coroutine::GetCurrent()->GetVM()->GetGlobalObjectStorage()->Add(promise, mem::Reference::ObjectType::WEAK); + PandaEtsVM *ets_vm = coroutine->GetPandaVM(); + auto promise_ref = ets_vm->GetGlobalObjectStorage()->Add(promise, mem::Reference::ObjectType::WEAK); auto evt = Runtime::GetCurrent()->GetInternalAllocator()->New(promise_ref); promise->SetEventPtr(evt); this->GetAccAsVReg().SetReference(promise); this->GetFrame()->GetAcc() = this->GetAcc(); // create the coro and put it to the ready queue - auto *cm = static_cast(Coroutine::GetCurrent()->GetVM()->GetThreadManager()); + auto *cm = static_cast(ets_vm->GetThreadManager()); cm->Launch(evt, method, std::move(args)); this->template MoveToNextInst(); diff --git a/plugins/ets/runtime/napi/ets_napi_native_interface.cpp b/plugins/ets/runtime/napi/ets_napi_native_interface.cpp index 8cd5caf90..bf23ed303 100644 --- a/plugins/ets/runtime/napi/ets_napi_native_interface.cpp +++ b/plugins/ets/runtime/napi/ets_napi_native_interface.cpp @@ -436,9 +436,8 @@ NO_UB_SANITIZE static ets_class FindClass(EtsEnv *env, const char *name) } PandaString class_descriptor = ToClassDescriptor(name); - - auto *class_linker_extension = EtsClassLinkerExtension::GetEtsClassLinkerExtension(); - auto klass = class_linker_extension->GetEtsClass(class_descriptor, true, GetClassLinkerContext(&s)); + EtsClassLinker *class_linker = ets_env->GetEtsVM()->GetClassLinker(); + EtsClass *klass = class_linker->GetClass(class_descriptor.c_str(), true, GetClassLinkerContext(&s)); if (ets_env->HasPendingException()) { EtsThrowable *current_exception = ets_env->GetThrowable(); @@ -2687,7 +2686,7 @@ const ETS_NativeInterface NATIVE_INTERFACE = { NewObjectList, NewObjectArray, GetObjectClass, - IsInstanceOf, + IsInstanceOf, Getp_method, CallObjectMethod, CallObjectMethodList, @@ -2719,7 +2718,7 @@ const ETS_NativeInterface NATIVE_INTERFACE = { CallVoidMethod, CallVoidMethodList, CallVoidMethodArray, - CallNonvirtualObjectMethod, + CallNonvirtualObjectMethod, CallNonvirtualObjectMethodList, CallNonvirtualObjectMethodArray, CallNonvirtualBooleanMethod, diff --git a/plugins/ets/runtime/types/ets_array.h b/plugins/ets/runtime/types/ets_array.h index 699b60f99..f060791e5 100644 --- a/plugins/ets/runtime/types/ets_array.h +++ b/plugins/ets/runtime/types/ets_array.h @@ -21,6 +21,7 @@ #include "plugins/ets/runtime/types/ets_class.h" #include "plugins/ets/runtime/types/ets_primitives.h" #include "plugins/ets/runtime/types/ets_object.h" +#include "plugins/ets/runtime/ets_class_root.h" #include "plugins/ets/runtime/ets_vm.h" namespace panda::ets { @@ -98,10 +99,9 @@ protected: } template - static T *CreateForPrimitive(ClassRoot root, uint32_t length) + static T *CreateForPrimitive(EtsClassRoot root, uint32_t length) { - EtsClass *array_class = EtsClass::FromRuntimeClass( - PandaEtsVM::GetCurrent()->GetClassLinker()->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(root)); + EtsClass *array_class = PandaEtsVM::GetCurrent()->GetClassLinker()->GetClassRoot(root); return Create(array_class, length); } @@ -125,14 +125,13 @@ public: { ASSERT_HAVE_ACCESS_TO_MANAGED_OBJECTS(); // Generate Array class name "[L;" - ClassLinker *class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); + EtsClassLinker *class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); PandaString array_class_name = PandaString("[") + object_class->GetDescriptor(); - Class *array_class = - class_linker->GetClass(utf::CStringAsMutf8(array_class_name.c_str()), true, object_class->GetClassLoader()); + EtsClass *array_class = class_linker->GetClass(array_class_name.c_str(), true, object_class->GetClassLoader()); if (array_class == nullptr) { return nullptr; } - return EtsArray::Create(EtsClass::FromRuntimeClass(array_class), length, space_type); + return EtsArray::Create(array_class, length, space_type); } void Set(uint32_t index, EtsObject *element) @@ -158,14 +157,14 @@ private: NO_MOVE_SEMANTIC(EtsObjectArray); }; -template +template class EtsPrimitiveArray : public EtsArray { public: static EtsPrimitiveArray *Create(uint32_t length) { ASSERT_HAVE_ACCESS_TO_MANAGED_OBJECTS(); // NOLINTNEXTLINE(readability-magic-numbers) - return EtsArray::CreateForPrimitive(CLASS_ROOT, length); + return EtsArray::CreateForPrimitive(ETS_CLASS_ROOT, length); } void Set(uint32_t index, ClassType element) { @@ -184,15 +183,15 @@ private: NO_MOVE_SEMANTIC(EtsPrimitiveArray); }; -using EtsBooleanArray = EtsPrimitiveArray; -using EtsByteArray = EtsPrimitiveArray; -using EtsCharArray = EtsPrimitiveArray; -using EtsShortArray = EtsPrimitiveArray; -using EtsIntArray = EtsPrimitiveArray; -using EtsLongArray = EtsPrimitiveArray; -using EtsFloatArray = EtsPrimitiveArray; -using EtsDoubleArray = EtsPrimitiveArray; +using EtsBooleanArray = EtsPrimitiveArray; +using EtsByteArray = EtsPrimitiveArray; +using EtsCharArray = EtsPrimitiveArray; +using EtsShortArray = EtsPrimitiveArray; +using EtsIntArray = EtsPrimitiveArray; +using EtsLongArray = EtsPrimitiveArray; +using EtsFloatArray = EtsPrimitiveArray; +using EtsDoubleArray = EtsPrimitiveArray; } // namespace panda::ets -#endif // PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_ARRAY_H_ \ No newline at end of file +#endif // PANDA_PLUGINS_ETS_RUNTIME_FFI_CLASSES_ETS_ARRAY_H_ diff --git a/plugins/ets/runtime/types/ets_class.cpp b/plugins/ets/runtime/types/ets_class.cpp index 02c534098..f293630f7 100644 --- a/plugins/ets/runtime/types/ets_class.cpp +++ b/plugins/ets/runtime/types/ets_class.cpp @@ -91,44 +91,44 @@ EtsClass *EtsClass::GetPrimitiveClass(EtsString *name) return nullptr; } const char *primitive_name = nullptr; - ClassRoot class_root; + EtsClassRoot class_root; char hash = name->At(0) ^ ((name->At(1) & 0x10) << 1); // NOLINT switch (hash) { case 'v': primitive_name = "void"; - class_root = ClassRoot::V; + class_root = EtsClassRoot::VOID; break; case 'b': primitive_name = "boolean"; - class_root = ClassRoot::U1; + class_root = EtsClassRoot::BOOLEAN; break; case 'B': primitive_name = "byte"; - class_root = ClassRoot::I8; + class_root = EtsClassRoot::BYTE; break; case 'c': primitive_name = "char"; - class_root = ClassRoot::U16; + class_root = EtsClassRoot::CHAR; break; case 's': primitive_name = "short"; - class_root = ClassRoot::I16; + class_root = EtsClassRoot::SHORT; break; case 'i': primitive_name = "int"; - class_root = ClassRoot::I32; + class_root = EtsClassRoot::INT; break; case 'l': primitive_name = "long"; - class_root = ClassRoot::I64; + class_root = EtsClassRoot::LONG; break; case 'f': primitive_name = "float"; - class_root = ClassRoot::F32; + class_root = EtsClassRoot::FLOAT; break; case 'd': primitive_name = "double"; - class_root = ClassRoot::F64; + class_root = EtsClassRoot::DOUBLE; break; default: break; @@ -136,8 +136,7 @@ EtsClass *EtsClass::GetPrimitiveClass(EtsString *name) // StringIndexOutOfBoundsException is not thrown by At method above, because index (0, 1) < length (>= 2) if (primitive_name != nullptr && name->IsEqual(primitive_name)) { // SUPPRESS_CSA(alpha.core.WasteObjHeader) - return EtsClass::FromRuntimeClass( - Runtime::GetCurrent()->GetClassLinker()->GetExtension(SourceLanguage::ETS)->GetClassRoot(class_root)); + return PandaEtsVM::GetCurrent()->GetClassLinker()->GetClassRoot(class_root); } return nullptr; diff --git a/plugins/ets/runtime/types/ets_method.cpp b/plugins/ets/runtime/types/ets_method.cpp index 045ef0d79..3b6b27aca 100644 --- a/plugins/ets/runtime/types/ets_method.cpp +++ b/plugins/ets/runtime/types/ets_method.cpp @@ -66,16 +66,16 @@ uint32_t EtsMethod::GetNumArgSlots() const return num_of_slots; } -Class *EtsMethod::ResolveArgType(uint32_t idx) +EtsClass *EtsMethod::ResolveArgType(uint32_t idx) { if (!IsStatic()) { if (idx == 0) { - return GetClass()->GetRuntimeClass(); + return GetClass(); } } // get reference type - ClassLinker *class_linker = Runtime::GetCurrent()->GetClassLinker(); + EtsClassLinker *class_linker = PandaEtsVM::GetCurrent()->GetClassLinker(); auto type = GetPandaMethod()->GetArgType(idx); if (!type.IsPrimitive()) { size_t ref_idx = 0; @@ -87,28 +87,27 @@ Class *EtsMethod::ResolveArgType(uint32_t idx) } } ASSERT(ref_idx <= proto.GetRefTypes().size()); - return class_linker->GetClass(utf::CStringAsMutf8(proto.GetRefTypes()[ref_idx].data()), false, - GetClass()->GetClassLoader()); + return class_linker->GetClass(proto.GetRefTypes()[ref_idx].data(), false, GetClass()->GetClassLoader()); } // get primitive type switch (type.GetId()) { case panda_file::Type::TypeId::U1: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::U1); + return class_linker->GetClassRoot(EtsClassRoot::BOOLEAN); case panda_file::Type::TypeId::I8: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::I8); + return class_linker->GetClassRoot(EtsClassRoot::BYTE); case panda_file::Type::TypeId::I16: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::I16); + return class_linker->GetClassRoot(EtsClassRoot::SHORT); case panda_file::Type::TypeId::U16: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::U16); + return class_linker->GetClassRoot(EtsClassRoot::CHAR); case panda_file::Type::TypeId::I32: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::I32); + return class_linker->GetClassRoot(EtsClassRoot::INT); case panda_file::Type::TypeId::I64: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::I64); + return class_linker->GetClassRoot(EtsClassRoot::LONG); case panda_file::Type::TypeId::F32: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::F32); + return class_linker->GetClassRoot(EtsClassRoot::FLOAT); case panda_file::Type::TypeId::F64: - return class_linker->GetExtension(panda_file::SourceLang::ETS)->GetClassRoot(ClassRoot::F64); + return class_linker->GetClassRoot(EtsClassRoot::DOUBLE); default: LOG(FATAL, RUNTIME) << "ResolveArgType: not a valid ets type for " << type; return nullptr; diff --git a/plugins/ets/runtime/types/ets_method.h b/plugins/ets/runtime/types/ets_method.h index 1d0955e95..2d3853c5b 100644 --- a/plugins/ets/runtime/types/ets_method.h +++ b/plugins/ets/runtime/types/ets_method.h @@ -117,7 +117,7 @@ public: return EtsClass::FromRuntimeClass(GetPandaMethod()->GetClass()); } - Class *ResolveArgType(uint32_t idx); + EtsClass *ResolveArgType(uint32_t idx); EtsClass *ResolveReturnType() { diff --git a/plugins/ets/runtime/types/ets_promise.cpp b/plugins/ets/runtime/types/ets_promise.cpp new file mode 100644 index 000000000..3d909e192 --- /dev/null +++ b/plugins/ets/runtime/types/ets_promise.cpp @@ -0,0 +1,30 @@ +/** + * 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. + */ + +#include "plugins/ets/runtime/types/ets_promise.h" +#include "plugins/ets/runtime/ets_coroutine.h" +#include "plugins/ets/runtime/ets_vm.h" + +namespace panda::ets { + +/*static*/ +EtsPromise *EtsPromise::Create(EtsCoroutine *ets_coroutine) +{ + EtsClass *klass = ets_coroutine->GetPandaVM()->GetClassLinker()->GetPromiseClass(); + ObjectHeader *object_header = ObjectHeader::Create(klass->GetRuntimeClass()); + return reinterpret_cast(object_header); +} + +} // namespace panda::ets diff --git a/plugins/ets/runtime/types/ets_promise.h b/plugins/ets/runtime/types/ets_promise.h index d760383d4..bb1cfe092 100644 --- a/plugins/ets/runtime/types/ets_promise.h +++ b/plugins/ets/runtime/types/ets_promise.h @@ -22,6 +22,8 @@ namespace panda::ets { +class EtsCoroutine; + namespace test { class EtsPromiseMembers; } // namespace test @@ -39,6 +41,8 @@ public: NO_COPY_SEMANTIC(EtsPromise); NO_MOVE_SEMANTIC(EtsPromise); + static EtsPromise *Create(EtsCoroutine *ets_coroutine); + ObjectHeader *GetThenQueue() { return then_queue_; diff --git a/plugins/ets/subproject_sources.gn b/plugins/ets/subproject_sources.gn index ec4eb8088..c54cbfa83 100644 --- a/plugins/ets/subproject_sources.gn +++ b/plugins/ets/subproject_sources.gn @@ -30,6 +30,7 @@ inst_templates_yaml_path = "compiler/optimizer/ir_builder/ets_inst_templates.yaml" srcs_runtime = [ + "runtime/ets_class_linker.cpp", "runtime/ets_class_linker_extension.cpp", "runtime/ets_coroutine.cpp", "runtime/ets_itable_builder.cpp", @@ -61,6 +62,7 @@ srcs_runtime = [ "runtime/types/ets_class.cpp", "runtime/types/ets_field.cpp", "runtime/types/ets_method.cpp", + "runtime/types/ets_promise.cpp", ] if (current_cpu == "amd64" || current_cpu == "x64" || current_cpu == "x86_64") { diff --git a/plugins/ets/tests/runtime/types/ets_array_test.cpp b/plugins/ets/tests/runtime/types/ets_array_test.cpp index af5b574d8..36e19a154 100644 --- a/plugins/ets/tests/runtime/types/ets_array_test.cpp +++ b/plugins/ets/tests/runtime/types/ets_array_test.cpp @@ -69,10 +69,10 @@ private: EtsCoroutine *coroutine_ = nullptr; }; -template +template static void TestEtsPrimitiveArray(uint32_t array_length, ClassType element) { - auto *array = EtsPrimitiveArray::Create(array_length); + auto *array = EtsPrimitiveArray::Create(array_length); ASSERT_NE(array, nullptr); ASSERT_EQ(array->GetLength(), array_length); @@ -89,14 +89,14 @@ TEST_F(EtsArrayTest, PrimitiveEtsArray) { uint32_t array_length = 100; - TestEtsPrimitiveArray(array_length, 1U); // EtsBooleanArray - TestEtsPrimitiveArray(array_length, 127); // EtsByteArray - TestEtsPrimitiveArray(array_length, 65000U); // EtsCharArray - TestEtsPrimitiveArray(array_length, 150); // EtsShortArray - TestEtsPrimitiveArray(array_length, 65000); // EtsIntArray - TestEtsPrimitiveArray(array_length, 65000); // EtsLongArray - TestEtsPrimitiveArray(array_length, 65000.0F); // EtsFloatArray - TestEtsPrimitiveArray(array_length, 65000.0F); // EtsDoubleArray + TestEtsPrimitiveArray(array_length, 1U); // EtsBooleanArray + TestEtsPrimitiveArray(array_length, 127); // EtsByteArray + TestEtsPrimitiveArray(array_length, 65000U); // EtsCharArray + TestEtsPrimitiveArray(array_length, 150); // EtsShortArray + TestEtsPrimitiveArray(array_length, 65000); // EtsIntArray + TestEtsPrimitiveArray(array_length, 65000); // EtsLongArray + TestEtsPrimitiveArray(array_length, 65000.0F); // EtsFloatArray + TestEtsPrimitiveArray(array_length, 65000.0F); // EtsDoubleArray } static void TestEtsObjectArray(const char *class_name, const char *source, uint32_t array_length) diff --git a/plugins/ets/tests/runtime/types/ets_promise_test.cpp b/plugins/ets/tests/runtime/types/ets_promise_test.cpp index 35be79020..98d97bef5 100644 --- a/plugins/ets/tests/runtime/types/ets_promise_test.cpp +++ b/plugins/ets/tests/runtime/types/ets_promise_test.cpp @@ -51,11 +51,6 @@ public: Runtime::Destroy(); } - const uint8_t *AsUtf8(const char *str) - { - return reinterpret_cast(str); - } - NO_COPY_SEMANTIC(EtsPromiseTest); NO_MOVE_SEMANTIC(EtsPromiseTest); @@ -81,17 +76,15 @@ public: TEST_F(EtsPromiseTest, MemoryLayout) { - ClassLinker *class_linker = vm_->GetClassLinker(); - auto *ext = reinterpret_cast(class_linker->GetExtension(panda_file::SourceLang::ETS)); - Class *promise_class = ext->GetPromiseClass(); + EtsClass *promise_class = vm_->GetClassLinker()->GetPromiseClass(); ASSERT_NE(nullptr, promise_class); - ASSERT_EQ(4, promise_class->GetInstanceFields().size()); + ASSERT_EQ(4, promise_class->GetInstanceFieldsNumber()); std::vector members = EtsPromiseMembers::GetMembers(); // Check both EtsPromise and panda::Class has the same number of fields // and at the same offsets for (const Member &memb : members) { - Field *field = promise_class->GetInstanceFieldByName(AsUtf8(memb.name)); + EtsField *field = promise_class->GetFieldIDByName(memb.name); ASSERT_NE(nullptr, field); ASSERT_EQ(memb.offset, field->GetOffset()); } -- Gitee