diff --git a/static_core/plugins/ets/runtime/ets_coroutine.cpp b/static_core/plugins/ets/runtime/ets_coroutine.cpp index 151c85498a2fe38f262aec6148d9376fbd16b0f3..84da35c787734f78c4d27f07cf241f0ab0e365cc 100644 --- a/static_core/plugins/ets/runtime/ets_coroutine.cpp +++ b/static_core/plugins/ets/runtime/ets_coroutine.cpp @@ -70,6 +70,7 @@ void EtsCoroutine::Initialize() // initialization in MT ManagedThread ctor and EtsCoroutine::Initialize auto *linkExt = GetPandaVM()->GetClassLinker()->GetEtsClassLinkerExtension(); SetStringClassPtr(linkExt->GetClassRoot(ClassRoot::STRING)); + SetBaseStringClassPtr(linkExt->GetClassRoot(ClassRoot::BASE_STRING)); SetArrayU16ClassPtr(linkExt->GetClassRoot(ClassRoot::ARRAY_U16)); SetArrayU8ClassPtr(linkExt->GetClassRoot(ClassRoot::ARRAY_U8)); } diff --git a/static_core/plugins/ets/runtime/ets_vtable_builder.cpp b/static_core/plugins/ets/runtime/ets_vtable_builder.cpp index 81ffd11fd466b1491585aea8f836aa8cd59dcacd..a320ba1e3dbfb6724d3426d0a836321d74dab293 100644 --- a/static_core/plugins/ets/runtime/ets_vtable_builder.cpp +++ b/static_core/plugins/ets/runtime/ets_vtable_builder.cpp @@ -139,6 +139,7 @@ static bool RefExtendsOrImplements(const ClassLinkerContext *ctx, RefTypeLink su return false; } panda_file::ClassDataAccessor const &superCDA = superCDAOpt.value(); + // what about this? if (superCDA.IsFinal()) { return false; } diff --git a/static_core/plugins/ets/runtime/intrinsics/std_core_Type.cpp b/static_core/plugins/ets/runtime/intrinsics/std_core_Type.cpp index 71b2f7c3dc1788c9b6b08a128ee1b2fc39cf3ced..3b656c302ccc62ab96fab7a7a2435c1064e6197c 100644 --- a/static_core/plugins/ets/runtime/intrinsics/std_core_Type.cpp +++ b/static_core/plugins/ets/runtime/intrinsics/std_core_Type.cpp @@ -195,7 +195,7 @@ EtsString *TypeAPIGetUndefinedTypeDescriptor() EtsInt TypeAPIGetClassAttributes(EtsClass *cls) { uint32_t attrs = 0; - attrs |= (cls->IsFinal()) ? static_cast(EtsTypeAPIAttributes::FINAL) : 0U; + attrs |= (cls->IsNotExtensible()) ? static_cast(EtsTypeAPIAttributes::FINAL) : 0U; return static_cast(attrs); } diff --git a/static_core/plugins/ets/runtime/types/ets_class.h b/static_core/plugins/ets/runtime/types/ets_class.h index 0c4b44f89c1aa1e38b05e754388126eaf73b7214..97e0ef7ed3101e7d35f86ccf98ad63d41e554a44 100644 --- a/static_core/plugins/ets/runtime/types/ets_class.h +++ b/static_core/plugins/ets/runtime/types/ets_class.h @@ -196,6 +196,11 @@ public: return GetRuntimeClass()->IsFinal(); } + bool IsNotExtensible() const + { + return GetRuntimeClass()->IsNotExtensible(); + } + bool IsAnnotation() const { return GetRuntimeClass()->IsAnnotation(); diff --git a/static_core/runtime/include/class.h b/static_core/runtime/include/class.h index a6121da5975ae474ead8522102d18625d9b97725..476809425b68fa1d4ac5b34787d93a63df74e14e 100644 --- a/static_core/runtime/include/class.h +++ b/static_core/runtime/include/class.h @@ -26,6 +26,7 @@ #include "runtime/include/field.h" #include "runtime/include/itable.h" #include "runtime/include/method.h" +#include "runtime/include/managed_thread.h" #include "libpandabase/macros.h" namespace ark { @@ -290,6 +291,15 @@ public: return (accessFlags_ & ACC_FINAL) != 0; } + bool IsNotExtensible() const + { + auto baseStringKls = ManagedThread::GetCurrent()->GetBaseStringClassPtr(); + if (this != baseStringKls) { + return this->IsFinal(); + } + return baseStringKls == ManagedThread::GetCurrent()->GetStringClassPtr(); + } + bool IsAnnotation() const { return (accessFlags_ & ACC_ANNOTATION) != 0; diff --git a/static_core/runtime/include/managed_thread.h b/static_core/runtime/include/managed_thread.h index 2278a385abd79c3b2c5b997e74be4db7dfeb65d0..820ae542011b8bcbd81c756d7d6b4067f80ab369 100644 --- a/static_core/runtime/include/managed_thread.h +++ b/static_core/runtime/include/managed_thread.h @@ -191,6 +191,19 @@ public: { stringClassPtr_ = p; } + Class *GetStringClassPtr() + { + return static_cast(stringClassPtr_); + } + + void SetBaseStringClassPtr(void *p) + { + baseStringClassPtr_ = p; + } + Class *GetBaseStringClassPtr() + { + return static_cast(baseStringClassPtr_); + } void SetArrayU8ClassPtr(void *p) { diff --git a/static_core/runtime/include/thread.h b/static_core/runtime/include/thread.h index 174784d30319f270af92fa1ebe4819bdcec32451..92d912dac4a7cff988b317468613ba6b51312c1f 100644 --- a/static_core/runtime/include/thread.h +++ b/static_core/runtime/include/thread.h @@ -338,6 +338,7 @@ protected: void *postWrbOneObject_ {nullptr}; // keeps IRtoC GC PostWrb impl for storing two objects void *postWrbTwoObjects_ {nullptr}; + void *baseStringClassPtr_ {nullptr}; // ClassRoot::STRING void *stringClassPtr_ {nullptr}; // ClassRoot::STRING void *arrayU16ClassPtr_ {nullptr}; // ClassRoot::ARRAY_U16 void *arrayU8ClassPtr_ {nullptr}; // ClassRoot::ARRAY_U8 diff --git a/static_core/runtime/runtime.cpp b/static_core/runtime/runtime.cpp index 09436a660dbbe71f8cc78f9b6f399e90b52f4169..59c52e80b82ce9350dca4646d4353b9693064ddf 100644 --- a/static_core/runtime/runtime.cpp +++ b/static_core/runtime/runtime.cpp @@ -890,6 +890,7 @@ void Runtime::SetThreadClassPointers() auto ext = GetClassLinker()->GetExtension(GetLanguageContext(GetRuntimeType())); if (ext != nullptr) { thread->SetStringClassPtr(ext->GetClassRoot(ClassRoot::STRING)); + thread->SetBaseStringClassPtr(ext->GetClassRoot(ClassRoot::BASE_STRING)); thread->SetArrayU16ClassPtr(ext->GetClassRoot(ClassRoot::ARRAY_U16)); thread->SetArrayU8ClassPtr(ext->GetClassRoot(ClassRoot::ARRAY_U8)); }