From 07e55725e70e466851be6122316a0f68a4f1c85e Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 23 Jul 2025 11:49:03 +0800 Subject: [PATCH] as Signed-off-by: yaochaonan Change-Id: If6080877528be21cae4020b77a7633049e09c93f --- ecmascript/compiler/stub_builder-inl.h | 12 ++++++ ecmascript/compiler/stub_builder.cpp | 12 +++--- ecmascript/compiler/stub_builder.h | 2 + ecmascript/debugger/debugger_api.cpp | 2 +- ecmascript/module/js_module_manager.cpp | 18 ++++++-- ecmascript/module/js_module_manager.h | 2 + ecmascript/module/js_module_namespace.cpp | 11 +---- ecmascript/module/js_module_source_text.cpp | 41 +++++++++++++------ ecmascript/module/js_module_source_text.h | 11 +++++ ecmascript/module/js_shared_module.cpp | 2 +- ecmascript/module/module_value_accessor.cpp | 10 ++--- .../module/tests/module_snapshot_test.cpp | 6 +-- .../module/tests/module_test/import_shared.js | 18 ++++++++ .../tests/module_test/single_instance.js | 23 +++++++++++ .../tests/module_test/single_instance_test.js | 19 +++++++++ .../single_instance_test_shared.js | 27 ++++++++++++ ecmascript/module/tests/shared_test/entry.js | 18 ++++++++ .../module/tests/shared_test/shared_test.txt | 5 +++ .../tests/shared_test/single_instance.js | 23 +++++++++++ .../tests/shared_test/single_instance_test.js | 19 +++++++++ .../single_instance_test_shared.js | 27 ++++++++++++ ecmascript/module/tests/shared_test/string.js | 17 ++++++++ ecmascript/stubs/runtime_stubs.cpp | 7 +--- 23 files changed, 283 insertions(+), 49 deletions(-) create mode 100644 ecmascript/module/tests/module_test/import_shared.js create mode 100644 ecmascript/module/tests/module_test/single_instance.js create mode 100644 ecmascript/module/tests/module_test/single_instance_test.js create mode 100644 ecmascript/module/tests/module_test/single_instance_test_shared.js create mode 100644 ecmascript/module/tests/shared_test/entry.js create mode 100644 ecmascript/module/tests/shared_test/shared_test.txt create mode 100644 ecmascript/module/tests/shared_test/single_instance.js create mode 100644 ecmascript/module/tests/shared_test/single_instance_test.js create mode 100644 ecmascript/module/tests/shared_test/single_instance_test_shared.js create mode 100644 ecmascript/module/tests/shared_test/string.js diff --git a/ecmascript/compiler/stub_builder-inl.h b/ecmascript/compiler/stub_builder-inl.h index 71ab0f2d71..6ecc1767b7 100644 --- a/ecmascript/compiler/stub_builder-inl.h +++ b/ecmascript/compiler/stub_builder-inl.h @@ -4589,12 +4589,24 @@ inline GateRef StubBuilder::GetSharedType(GateRef module) Int32((1LU << SourceTextModule::IS_SHARED_TYPE_BITS) - 1)); } +inline GateRef StubBuilder::GetModuleStatus(GateRef module) +{ + GateRef bitfield = GetBitFieldFromSourceTextModule(module); + return Int32And(bitfield, Int32((1LU << SourceTextModule::STATUS_BITS) - 1)); +} + inline GateRef StubBuilder::IsSharedModule(GateRef module) { GateRef sharedType = GetSharedType(module); return Int32Equal(sharedType, Int32(static_cast(SharedTypes::SHARED_MODULE))); } +inline GateRef StubBuilder::NeedUpdate(GateRef module) +{ + GateRef status = GetModuleStatus(module); + return BitAnd(IsSharedModule(module), Int32LessThan(status, Int32(static_cast(ModuleStatus::EVALUATING)))); +} + inline GateRef StubBuilder::GetCjsModuleFunction(GateRef glue) { GateRef globalEnv = GetCurrentGlobalEnv(); diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 9968d3cbb7..aae0f8ffa7 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12352,13 +12352,13 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - Label isSharedModule(env); - Label notSharedModule(env); - BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); - Bind(&isSharedModule); + Label needUpdate(env); + Label noNeedUpdate(env); + BRANCH(NeedUpdate(*resolvedModule), &needUpdate, &noNeedUpdate); + Bind(&needUpdate); resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); - Jump(¬SharedModule); - Bind(¬SharedModule); + Jump(&noNeedUpdate); + Bind(&noNeedUpdate); result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index 956668e6c8..78fbdaf118 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -1230,6 +1230,8 @@ public: inline GateRef IsCjsModule(GateRef module); inline GateRef GetSharedType(GateRef module); inline GateRef IsSharedModule(GateRef module); + inline GateRef GetModuleStatus(GateRef module); + inline GateRef NeedUpdate(GateRef module); inline GateRef GetCjsModuleFunction(GateRef glue); void ModuleEnvMustBeValid(GateRef glue, GateRef curEnv); GateRef SearchFromModuleCache(GateRef glue, GateRef moduleName); diff --git a/ecmascript/debugger/debugger_api.cpp b/ecmascript/debugger/debugger_api.cpp index ede12c47c2..3988dc9608 100644 --- a/ecmascript/debugger/debugger_api.cpp +++ b/ecmascript/debugger/debugger_api.cpp @@ -522,7 +522,7 @@ JSHandle DebuggerApi::GetImportModule(const EcmaVM *ecmaVm, environment.Update(moduleEnvironment); JSTaggedValue resolvedBinding = environment->Get(thread, idx); ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject()); - importModule.Update(binding->GetModule(thread)); + importModule.Update(binding->GetIndexBindingModule(thread)); name = EcmaStringAccessor(importName).ToStdString(thread); return importModule; } diff --git a/ecmascript/module/js_module_manager.cpp b/ecmascript/module/js_module_manager.cpp index fbb25daca0..4eb7813449 100644 --- a/ecmascript/module/js_module_manager.cpp +++ b/ecmascript/module/js_module_manager.cpp @@ -102,11 +102,21 @@ JSTaggedValue ModuleManager::GetExternalModuleVarFastPathForJIT(JSThread *thread JSHandle ModuleManager::GetImportedModule(const CString &referencing) { auto thread = vm_->GetJSThread(); - if (!IsLocalModuleLoaded(referencing)) { - return SharedModuleManager::GetInstance()->GetSModule(thread, referencing); - } else { - return HostGetImportedModule(referencing); + JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule(thread, referencing); + if (sharedModule.GetTaggedValue().IsUndefined()) { + return TryGetImportedLocalModule(referencing); + } + return sharedModule; +} + +JSHandle ModuleManager::TryGetImportedLocalModule(const CString &referencing) +{ + auto thread = vm_->GetJSThread(); + auto entry = resolvedModules_.Find(referencing); + if (!entry) { + return JSHandle(thread->GlobalConstants()->GetHandledUndefined()); } + return JSHandle(thread, entry.value()); } JSHandle ModuleManager::HostGetImportedModule(const CString &referencing) diff --git a/ecmascript/module/js_module_manager.h b/ecmascript/module/js_module_manager.h index 8311b78343..b58b17260a 100644 --- a/ecmascript/module/js_module_manager.h +++ b/ecmascript/module/js_module_manager.h @@ -141,6 +141,8 @@ private: void RemoveModuleNameFromList(const CString &recordName); + JSHandle TryGetImportedLocalModule(const CString &referencing); + static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4; uint32_t nextModuleAsyncEvaluatingOrdinal_{SourceTextModule::FIRST_ASYNC_EVALUATING_ORDINAL}; diff --git a/ecmascript/module/js_module_namespace.cpp b/ecmascript/module/js_module_namespace.cpp index 377c8d3e82..2675ec5042 100644 --- a/ecmascript/module/js_module_namespace.cpp +++ b/ecmascript/module/js_module_namespace.cpp @@ -140,7 +140,7 @@ OperationResult ModuleNamespace::GetProperty(JSThread *thread, const JSHandle resolvedBind = JSHandle::Cast(binding); - JSTaggedValue targetModule = resolvedBind->GetModule(thread); + JSTaggedValue targetModule = resolvedBind->GetIndexBindingModule(thread); // 9. Assert: targetModule is not undefined. ASSERT(!targetModule.IsUndefined()); JSHandle module(thread, targetModule); @@ -154,13 +154,6 @@ OperationResult ModuleNamespace::GetProperty(JSThread *thread, const JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule( - thread, module->GetEcmaModuleRecordNameString()); - if (sharedModule.GetTaggedValue().IsSourceTextModule()) { - module = sharedModule; - } - } result = module->GetModuleValue(thread, resolvedBind->GetIndex(), true); } break; @@ -375,7 +368,7 @@ bool ModuleNamespace::ValidateKeysAvailable(JSThread *thread, const JSHandleIsResolvedBinding()) { targetModule = JSHandle::Cast(binding)->GetModule(thread); } else if (binding->IsResolvedIndexBinding()) { - targetModule = JSHandle::Cast(binding)->GetModule(thread); + targetModule = JSHandle::Cast(binding)->GetIndexBindingModule(thread); } ASSERT(!targetModule.IsUndefined()); JSTaggedValue dictionary = SourceTextModule::Cast(targetModule.GetTaggedObject())->GetNameDictionary(thread); diff --git a/ecmascript/module/js_module_source_text.cpp b/ecmascript/module/js_module_source_text.cpp index 1fe6fc22b8..f5cd03489a 100644 --- a/ecmascript/module/js_module_source_text.cpp +++ b/ecmascript/module/js_module_source_text.cpp @@ -1508,8 +1508,8 @@ JSHandle SourceTextModule::GetStarResolution(JSThread *thread, } else { JSHandle resolutionBd = JSHandle::Cast(resolution); JSHandle starResolutionBd = JSHandle::Cast(starResolution); - if ((!JSTaggedValue::SameValue(thread, resolutionBd->GetModule(thread), - starResolutionBd->GetModule(thread))) || + if ((!JSTaggedValue::SameValue(thread, resolutionBd->GetIndexBindingModule(thread), + starResolutionBd->GetIndexBindingModule(thread))) || resolutionBd->GetIndex() != starResolutionBd->GetIndex()) { return globalConstants->GetHandledAmbiguousString(); } @@ -2186,15 +2186,11 @@ JSHandle SourceTextModule::GetModuleFromCacheOrResolveNewOne(J return requireModule; } /* - * case A import B, A is sharedModule, B is normalModule. - * Thread 1 Instantiate: 1. resolve A/B, add A to resolvedSharedModules_ , add B to resolvedModules_ - * 2. mark A/B as INSTANTIATED. - * Thread 1 Evaluate: Doesn't evaluate A immediately. - * Thread 2 Instantiate: find A in resolvedSharedModules_, it's stauts is INSTANTIATED, return; - * Thread 2 Evaluate: 1. evaluate B first, then evaluate A. - * 2. find B through [GetRequestedModuleFromCache], crash. - * Because [GetRequestedModuleFromCache] is a fastpath for resolvedModule, but B is not resolved in thread 2. - * In this case, we need to add resolve new module process. + * case shared module has re-export. + * A(normal module, import string) -> B(shared module, re-export string)-> C(normal module, export string) + * If shared module B is evaluatd in other thread. B won't Instantiate in current thread. + * A will create binding with C when instantiating. But C is not resolved in current thread. + * Therefore, need resolve one here. */ JSHandle moduleRequests(thread, module->GetModuleRequests(thread)); JSHandle required(thread, moduleRequests->Get(thread, idx)); @@ -2279,7 +2275,7 @@ JSHandle SourceTextModule::CreateBindingByIndexBinding(JSThread* JSHandle binding, bool isShared) { - JSHandle resolvedModule(thread, binding->GetModule(thread)); + JSHandle resolvedModule(thread, binding->GetIndexBindingModule(thread)); JSHandle bindingName = GetBindingNameByIndex(thread, resolvedModule, binding->GetIndex()); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); @@ -2326,4 +2322,25 @@ JSHandle SourceTextModule::FindFuncInModuleForHook(JSThread* thre } return JSObject::FindFuncInObjectForHook(thread, exportEntity, className, funcName); } + +JSHandle SourceTextModule::UpdateSharedModule(JSThread *thread, JSHandle module) +{ + JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule( + thread, module->GetEcmaModuleRecordNameString()); + // shared module may not evaluated if lazy, thus won't add to sharedModule map. + if (sharedModule.GetTaggedValue().IsSourceTextModule()) { + return sharedModule; + } + return module; +} + +// Attention: use GetIndexBindingModule get corresponding module rather than GetModule from field. +JSTaggedValue ResolvedIndexBinding::GetIndexBindingModule(JSThread *thread) +{ + JSHandle module(thread, GetModule(thread)); + if (SourceTextModule::NeedUpdate(module)) { + return SourceTextModule::UpdateSharedModule(thread, module).GetTaggedValue(); + } + return module.GetTaggedValue(); +} } // namespace panda::ecmascript diff --git a/ecmascript/module/js_module_source_text.h b/ecmascript/module/js_module_source_text.h index c25a2cbd84..a24fdc013d 100644 --- a/ecmascript/module/js_module_source_text.h +++ b/ecmascript/module/js_module_source_text.h @@ -449,6 +449,13 @@ public: const std::string &className, const std::string &funcName); + static JSHandle UpdateSharedModule(JSThread *thread, JSHandle module); + + static bool NeedUpdate(JSHandle module) + { + return SourceTextModule::IsSharedModule(module) && module->GetStatus() < ModuleStatus::EVALUATING; + } + private: static JSHandle GetStarResolution(JSThread *thread, const JSHandle &exportName, @@ -521,6 +528,7 @@ public: CAST_CHECK(ResolvedIndexBinding, IsResolvedIndexBinding); static constexpr size_t MODULE_OFFSET = Record::SIZE; + // use GetModule may cause problem if module is shared, please use GetIndexBindingModule. ACCESSORS(Module, MODULE_OFFSET, INDEX_OFFSET); ACCESSORS_PRIMITIVE_FIELD(Index, int32_t, INDEX_OFFSET, BIT_FIELD_OFFSET); ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, END_OFFSET) @@ -530,6 +538,9 @@ public: FIRST_BIT_FIELD(BitField, IsUpdatedFromResolvedBinding, bool, IS_UPDATED_FROM_RESOLVED_BINDING_BITS) DECL_DUMP() DECL_VISIT_OBJECT(MODULE_OFFSET, INDEX_OFFSET) + + // Attention: use GetIndexBindingModule get corresponding module rather than GetModule from field. + JSTaggedValue GetIndexBindingModule(JSThread *thread); }; } // namespace panda::ecmascript #endif // ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H diff --git a/ecmascript/module/js_shared_module.cpp b/ecmascript/module/js_shared_module.cpp index b7af5330ac..1c97f830f0 100644 --- a/ecmascript/module/js_shared_module.cpp +++ b/ecmascript/module/js_shared_module.cpp @@ -48,7 +48,7 @@ JSHandle SendableClassModule::CloneRecordIndexBinding(JSThread *t { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle binding(thread, indexBinding); - JSHandle resolvedModule(thread, binding->GetModule(thread)); + JSHandle resolvedModule(thread, binding->GetIndexBindingModule(thread)); if (SourceTextModule::IsSharedModule((resolvedModule))) { return JSHandle::Cast( factory->NewSResolvedIndexBindingRecord(resolvedModule, binding->GetIndex())); diff --git a/ecmascript/module/module_value_accessor.cpp b/ecmascript/module/module_value_accessor.cpp index 2f14161db6..beaba5c622 100644 --- a/ecmascript/module/module_value_accessor.cpp +++ b/ecmascript/module/module_value_accessor.cpp @@ -295,7 +295,7 @@ template JSTaggedValue ModuleValueAccessor::GetModuleValueFromIndexBinding(const GetModuleValueFromBindingInfo &info) { JSHandle binding(info.thread, info.resolvedBinding); - JSMutableHandle resolvedModule(info.thread, binding->GetModule(info.thread)); + JSMutableHandle resolvedModule(info.thread, binding->GetIndexBindingModule(info.thread)); if (!info.isSendable && info.thread->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) { const JSHandle resolvedModuleOfHotReload = info.thread->GetEcmaVM()->FindPatchModule(resolvedModule->GetEcmaModuleRecordNameString()); @@ -309,12 +309,8 @@ JSTaggedValue ModuleValueAccessor::GetModuleValueFromIndexBinding(const GetModul EvaluateModuleIfNeeded(info.thread, resolvedModule); } RETURN_VALUE_IF_ABRUPT_COMPLETION(info.thread, JSTaggedValue::Exception()); - if (SourceTextModule::IsSharedModule(resolvedModule)) { - JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule( - info.thread, resolvedModule->GetEcmaModuleRecordNameString()); - if (sharedModule.GetTaggedValue().IsSourceTextModule()) { - resolvedModule.Update(sharedModule); - } + if (SourceTextModule::NeedUpdate(resolvedModule)) { + resolvedModule.Update(SourceTextModule::UpdateSharedModule(info.thread, resolvedModule)); } LogModuleLoadInfo(info.thread, info.module, resolvedModule, info.index, info.isSendable); return GetModuleValue(info.thread, resolvedModule, binding->GetIndex()); diff --git a/ecmascript/module/tests/module_snapshot_test.cpp b/ecmascript/module/tests/module_snapshot_test.cpp index 4fd9a00eb3..7a3ba2de91 100644 --- a/ecmascript/module/tests/module_snapshot_test.cpp +++ b/ecmascript/module/tests/module_snapshot_test.cpp @@ -253,8 +253,8 @@ public: auto serializeBinding = ResolvedIndexBinding::Cast(serializeResolvedBinding.GetTaggedObject()); auto deserializeBinding = ResolvedIndexBinding::Cast(deserializeResolvedBinding.GetTaggedObject()); EXPECT_EQ(serializeBinding->GetIndex(), deserializeBinding->GetIndex()); - JSHandle seriBindingModule(thread, serializeBinding->GetModule(thread)); - JSHandle deSeriBindingModule(thread, deserializeBinding->GetModule(thread)); + JSHandle seriBindingModule(thread, serializeBinding->GetIndexBindingModule(thread)); + JSHandle deSeriBindingModule(thread, deserializeBinding->GetIndexBindingModule(thread)); CheckModule(seriBindingModule, deSeriBindingModule); } else if (serializeResolvedBinding.IsResolvedBinding()) { ASSERT_TRUE(serializeResolvedBinding.IsResolvedBinding()); @@ -387,7 +387,7 @@ public: ASSERT_TRUE(serializeResolvedBinding.IsResolvedIndexBinding()); auto serializeBinding = ResolvedIndexBinding::Cast(serializeResolvedBinding.GetTaggedObject()); ASSERT_TRUE(serializeBinding->GetIsUpdatedFromResolvedBinding()); - ASSERT_EQ(serializeBinding->GetModule(thread), serializeNativeModule.GetTaggedValue()); + ASSERT_EQ(serializeBinding->GetIndexBindingModule(thread), serializeNativeModule.GetTaggedValue()); // serialize and persist ASSERT_TRUE(MockModuleSnapshot::SerializeDataAndSaving(vm, path, version)); // after serialize, indexBinding has been restore to binding diff --git a/ecmascript/module/tests/module_test/import_shared.js b/ecmascript/module/tests/module_test/import_shared.js new file mode 100644 index 0000000000..0027a8374d --- /dev/null +++ b/ecmascript/module/tests/module_test/import_shared.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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 {stringOut} from "./single_instance_test_shared" +let string = stringOut; +export {string}; \ No newline at end of file diff --git a/ecmascript/module/tests/module_test/single_instance.js b/ecmascript/module/tests/module_test/single_instance.js new file mode 100644 index 0000000000..dfa73b64fe --- /dev/null +++ b/ecmascript/module/tests/module_test/single_instance.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 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 { + static a = 0; + add() { + return A.a++; + } +} +export {A}; +export {stringOut} from './module_unexecute' \ No newline at end of file diff --git a/ecmascript/module/tests/module_test/single_instance_test.js b/ecmascript/module/tests/module_test/single_instance_test.js new file mode 100644 index 0000000000..cbfb7fb76f --- /dev/null +++ b/ecmascript/module/tests/module_test/single_instance_test.js @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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 {A} from "./single_instance" +let instanceA = new A(); +instanceA.add(); +export let normalA = A.a; \ No newline at end of file diff --git a/ecmascript/module/tests/module_test/single_instance_test_shared.js b/ecmascript/module/tests/module_test/single_instance_test_shared.js new file mode 100644 index 0000000000..99460f1f08 --- /dev/null +++ b/ecmascript/module/tests/module_test/single_instance_test_shared.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 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 {A} from "./single_instance" +export {stringOut} from "./single_instance" +"use shared" +let instanceA = new A(); +instanceA.add(); + +export let normalA = A.a; + +export function zoo() { + 'use sendable' + return "zoo"; +} \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/entry.js b/ecmascript/module/tests/shared_test/entry.js new file mode 100644 index 0000000000..35beb7c407 --- /dev/null +++ b/ecmascript/module/tests/shared_test/entry.js @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 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 {stringOut} from "./single_instance_test_shared" +let string = stringOut +export {string}; \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/shared_test.txt b/ecmascript/module/tests/shared_test/shared_test.txt new file mode 100644 index 0000000000..84f46ebe7a --- /dev/null +++ b/ecmascript/module/tests/shared_test/shared_test.txt @@ -0,0 +1,5 @@ +single_instance.js;single_instance;esm;single_instance.js;xxsingle_instancexx +single_instance_test_shared.js;single_instance_test_shared;esm;single_instance_test_shared.js;xxsingle_instance_test_sharedxx +single_instance_test.js;single_instance_test;esm;single_instance_test.js;xxsingle_instance_testxx +string.js;string;esm;string.js;xxstringxx +entry.js;entry;esm;entry.js;xxentryxx \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/single_instance.js b/ecmascript/module/tests/shared_test/single_instance.js new file mode 100644 index 0000000000..83a76596b1 --- /dev/null +++ b/ecmascript/module/tests/shared_test/single_instance.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 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 { + static a = 0; + add() { + return A.a++; + } +} +export {A}; +export {stringOut} from './string' \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/single_instance_test.js b/ecmascript/module/tests/shared_test/single_instance_test.js new file mode 100644 index 0000000000..cbfb7fb76f --- /dev/null +++ b/ecmascript/module/tests/shared_test/single_instance_test.js @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 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 {A} from "./single_instance" +let instanceA = new A(); +instanceA.add(); +export let normalA = A.a; \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/single_instance_test_shared.js b/ecmascript/module/tests/shared_test/single_instance_test_shared.js new file mode 100644 index 0000000000..99460f1f08 --- /dev/null +++ b/ecmascript/module/tests/shared_test/single_instance_test_shared.js @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 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 {A} from "./single_instance" +export {stringOut} from "./single_instance" +"use shared" +let instanceA = new A(); +instanceA.add(); + +export let normalA = A.a; + +export function zoo() { + 'use sendable' + return "zoo"; +} \ No newline at end of file diff --git a/ecmascript/module/tests/shared_test/string.js b/ecmascript/module/tests/shared_test/string.js new file mode 100644 index 0000000000..6bc69247f6 --- /dev/null +++ b/ecmascript/module/tests/shared_test/string.js @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 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. + */ + +let stringOut = 'module string'; +export {stringOut}; diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index 5dd40211a3..f8767a5c94 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -4976,12 +4976,7 @@ JSTaggedValue RuntimeStubs::UpdateSharedModule(uintptr_t argGlue, JSTaggedValue DISALLOW_GARBAGE_COLLECTION; auto thread = JSThread::GlueToJSThread(argGlue); JSHandle module(thread, resolvedModule); - JSHandle sharedModule = - SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); - if (sharedModule.GetTaggedValue().IsSourceTextModule()) { - return sharedModule.GetTaggedValue(); - } - return module.GetTaggedValue(); + return SourceTextModule::UpdateSharedModule(thread, module).GetTaggedValue(); } void RuntimeStubs::FatalPrintMisstakenResolvedBinding(int32_t index, JSTaggedValue curModule) -- Gitee