diff --git a/ecmascript/debugger/debugger_api.cpp b/ecmascript/debugger/debugger_api.cpp index 7ba0c27ff9d64364a42c985021d41b27365e5c47..31c663d1923ddd25bd4c7f2e8a025848cc60295c 100644 --- a/ecmascript/debugger/debugger_api.cpp +++ b/ecmascript/debugger/debugger_api.cpp @@ -743,8 +743,8 @@ void DebuggerApi::GetIndirectExportVariables(const EcmaVM *ecmaVm, LocalGetImportName(); name.Update(key); if (key.IsString()) { - JSHandle importModule = - SourceTextModule::GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex()); + JSHandle importModule = JSHandle::Cast( + SourceTextModule::GetRequestedModule(thread, requestedModules, ee->GetModuleRequestIndex())); RETURN_IF_ABRUPT_COMPLETION(thread); std::string importName = EcmaStringAccessor(ee->GetImportName()).ToStdString(); Local value = GetModuleValue(ecmaVm, importModule, importName); @@ -780,8 +780,8 @@ void DebuggerApi::GetImportVariables(const EcmaVM *ecmaVm, Local &mod JSTaggedValue localName = ee->GetLocalName(); name.Update(localName); if (JSTaggedValue::SameValue(key, starString.GetTaggedValue())) { - JSHandle importModule = - SourceTextModule::GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex()); + JSHandle importModule = JSHandle::Cast( + SourceTextModule::GetRequestedModule(thread, requestedModules, ee->GetModuleRequestIndex())); RETURN_IF_ABRUPT_COMPLETION(thread); Local importModuleObj = ObjectRef::New(ecmaVm); GetLocalExportVariables(ecmaVm, importModuleObj, importModule, true); diff --git a/ecmascript/module/js_module_deregister.cpp b/ecmascript/module/js_module_deregister.cpp index bd11e3369a963323ef455aed05189d9bff148768..3cc2ed935c48309df0c078c9f2d7bd2b6161ae79 100644 --- a/ecmascript/module/js_module_deregister.cpp +++ b/ecmascript/module/js_module_deregister.cpp @@ -101,8 +101,8 @@ void ModuleDeregister::IncreaseRegisterCounts(JSThread *thread, JSHandle requestedModules(thread, module->GetRequestedModules()); size_t requestedModulesLen = requestedModules->GetLength(); for (size_t idx = 0; idx < requestedModulesLen; idx++) { - JSHandle requiredModule = JSHandle::Cast( - SourceTextModule::GetRequestedModule(thread, module, requestedModules, idx)); + JSHandle requiredModule = + SourceTextModule::GetRequestedModule(thread, requestedModules, idx); RETURN_IF_ABRUPT_COMPLETION(thread); const CString moduleRecordName = module->GetEcmaModuleRecordNameString(); CString moduleName = @@ -138,8 +138,8 @@ void ModuleDeregister::DecreaseRegisterCounts(JSThread *thread, JSHandle requestedModules(thread, module->GetRequestedModules()); size_t requestedModulesLen = requestedModules->GetLength(); for (size_t idx = 0; idx < requestedModulesLen; idx++) { - JSHandle requiredModule = JSHandle::Cast( - SourceTextModule::GetRequestedModule(thread, module, requestedModules, idx)); + JSHandle requiredModule = + SourceTextModule::GetRequestedModule(thread, requestedModules, idx); RETURN_IF_ABRUPT_COMPLETION(thread); const CString moduleRecordName = module->GetEcmaModuleRecordNameString(); CString moduleName = diff --git a/ecmascript/module/js_module_manager.cpp b/ecmascript/module/js_module_manager.cpp index 9dda8b20c1744aa358e73842dc683e0c8cc2cf25..b94029a6a29dd3aabed204d0f3f5cfebdac0d6d2 100644 --- a/ecmascript/module/js_module_manager.cpp +++ b/ecmascript/module/js_module_manager.cpp @@ -472,8 +472,8 @@ JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedV JSThread *thread = vm_->GetJSThread(); JSHandle module(thread, SourceTextModule::Cast(currentModule)); JSHandle requestedModules(thread, module->GetRequestedModules()); - JSHandle requiredModule = JSHandle::Cast( - SourceTextModule::GetRequestedModule(thread, module, requestedModules, index)); + JSHandle requiredModule = + SourceTextModule::GetRequestedModule(thread, requestedModules, index); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception()); ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger(); diff --git a/ecmascript/module/js_module_source_text.cpp b/ecmascript/module/js_module_source_text.cpp index 06ff4acc65d4af198019330136142f7a76db8b04..868458ad4d40f9a5f8d329df35432d7e44332f75 100644 --- a/ecmascript/module/js_module_source_text.cpp +++ b/ecmascript/module/js_module_source_text.cpp @@ -70,8 +70,8 @@ CVector SourceTextModule::GetExportedNames(JSThread *thread, const for (size_t idx = 0; idx < starExportEntriesLen; idx++) { ee.Update(starExportEntries->Get(idx)); // a. Let requestedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]). - JSHandle requestedModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex())); + JSHandle requestedModule = + GetRequestedModule(thread, requestedModules, ee->GetModuleRequestIndex()); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exportedNames); SetExportName(thread, requestedModule, exportedNames, newExportStarSet); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, exportedNames); @@ -220,8 +220,8 @@ JSHandle SourceTextModule::ResolveExport(JSThread *thread, const for (size_t idx = 0; idx < starExportEntriesLen; idx++) { ee.Update(starExportEntries->Get(idx)); // a. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]). - JSHandle requestedModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex())); + JSHandle requestedModule = + GetRequestedModule(thread, requestedModules, ee->GetModuleRequestIndex()); RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); JSHandle result = GetStarResolution(thread, exportName, requestedModule, starResolution, resolveVector); @@ -410,6 +410,33 @@ bool SourceTextModule::EvaluateNativeModule(JSThread *thread, JSHandle module) +{ + if (module->GetStatus() != ModuleStatus::PREINSTANTIATING) { + return; + } + module->SetStatus(ModuleStatus::UNINSTANTIATED); + if (!module->GetRequestedModules().IsUndefined()) { + JSHandle requestedModules(thread, module->GetRequestedModules()); + size_t requestedModulesLen = requestedModules->GetLength(); + for (size_t idx = 0; idx < requestedModulesLen; idx++) { + JSHandle request(thread, requestedModules->Get(idx)); + if (request->IsSourceTextModule()) { + HandlePreInstantiationException(thread, JSHandle::Cast(request)); + } else if (request->IsString()) { + ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); + CString requestStr = ModulePathHelper::Utf8ConvertToString(request.GetTaggedValue()); + JSHandle mm = moduleManager->GetImportedModule(requestStr); + HandlePreInstantiationException(thread, mm); + } else { + // else request is hole; + break; + } + } + } +} + int SourceTextModule::HandleInstantiateException([[maybe_unused]] JSHandle &module, const CVector> &stack, int result) { @@ -444,12 +471,16 @@ int SourceTextModule::Instantiate(JSThread *thread, const JSHandle> stack; // 4. Let result be InnerModuleInstantiation(module, stack, 0). - JSHandle moduleRecord = JSHandle::Cast(module); - int result = SourceTextModule::InnerModuleInstantiation(thread, moduleRecord, stack, 0, executeType); + int result = SourceTextModule::PreModuleInstantiation(thread, module, executeType); // 5. If result is an abrupt completion, then + if (thread->HasPendingException()) { + HandlePreInstantiationException(thread, module); + return result; + } + // 3. Let stack be a new empty List. + CVector> stack; + result = FinishModuleInstantiation(thread, module, stack, 0); if (thread->HasPendingException()) { return HandleInstantiateException(module, stack, result); } @@ -500,76 +531,77 @@ void SourceTextModule::DFSModuleInstantiation(JSHandle &module } } -std::optional SourceTextModule::HandleInnerModuleInstantiation(JSThread *thread, - JSHandle &module, - JSMutableHandle &required, - CVector> &stack, - JSHandle requestModules, - size_t &moduleRequestsIdx, int &index, - const ExecuteTypes &executeType) +bool SourceTextModule::PreModuleInstantiation(JSThread *thread, + JSHandle module, const ExecuteTypes &executeType) { - // a. Let requiredModule be ? HostResolveImportedModule(module, required). - JSMutableHandle requiredModule(thread, thread->GlobalConstants()->GetUndefined()); - JSHandle requiredVal = - ModuleResolver::HostResolveImportedModule(thread, module, required, executeType); - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, SourceTextModule::UNDEFINED_INDEX); - if (!SourceTextModule::IsSharedModule(JSHandle::Cast(module))) { - requestModules->Set(thread, moduleRequestsIdx, requiredVal.GetTaggedValue()); + // Add a safepoint here to check if a suspension is needed. + thread->CheckSafepointIfSuspended(); + ModuleStatus status = module->GetStatus(); + ASSERT(status != ModuleStatus::INSTANTIATING); + if (status != ModuleStatus::UNINSTANTIATED && status != ModuleStatus::EVALUATING) { + return true; } - requiredModule.Update(JSHandle::Cast(requiredVal)); + bool isShared = SourceTextModule::IsSharedModule(module); + if (isShared && status == ModuleStatus::EVALUATING) { + LOG_FULL(INFO) << "circular dependency occurred of shared-module"; + return true; + } + module->SetStatus(ModuleStatus::PREINSTANTIATING); + JSHandle moduleRequests(thread, module->GetModuleRequests()); + // 9. For each String required that is an element of module.[[RequestedModules]], do + if (!moduleRequests.GetTaggedValue().IsUndefined()) { + JSHandle requestedModules(thread, module->GetRequestedModules()); + size_t moduleRequestsLen = moduleRequests->GetLength(); + JSMutableHandle required(thread, thread->GlobalConstants()->GetUndefined()); + JSHandle sharedRequestedModules(thread, thread->GlobalConstants()->GetUndefined()); + if (isShared) { + sharedRequestedModules = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(moduleRequestsLen); + } + for (size_t idx = 0; idx < moduleRequestsLen; idx++) { + required.Update(moduleRequests->Get(idx)); + JSHandle requiredModule = + ModuleResolver::HostResolveImportedModule(thread, module, required, executeType); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + if (!isShared) { + requestedModules->Set(thread, idx, requiredModule.GetTaggedValue()); + } else { + JSHandle requireModuleName = + thread->GetEcmaVM()->GetFactory()->NewFromUtf8(GetModuleName(requiredModule.GetTaggedValue())); + requestedModules->Set(thread, idx, requireModuleName.GetTaggedValue()); + sharedRequestedModules->Set(thread, idx, requiredModule.GetTaggedValue()); + } + } + // In case of circularImport, we need resolve separately. + if (isShared) { + requestedModules = sharedRequestedModules; + } + size_t requestedModulesLen = requestedModules->GetLength(); + for (size_t idx = 0; idx < requestedModulesLen; idx++) { + JSHandle requestedModule = GetRequestedModule(thread, requestedModules, idx); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + PreModuleInstantiation(thread, requestedModule, executeType); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, false); + } + } + return true; +} - // b. Set index to ? InnerModuleInstantiation(requiredModule, stack, index). - JSHandle requiredModuleRecord = JSHandle::Cast(requiredModule); - index = SourceTextModule::InnerModuleInstantiation(thread, - requiredModuleRecord, stack, index, executeType); - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); - // c. Assert: requiredModule.[[Status]] is one of LINKING, LINKED, EVALUATING-ASYNC, or EVALUATED. - ModuleStatus requiredModuleStatus = requiredModule->GetStatus(); - ASSERT(requiredModuleStatus == ModuleStatus::INSTANTIATING || - requiredModuleStatus == ModuleStatus::INSTANTIATED || - requiredModuleStatus == ModuleStatus::EVALUATING_ASYNC || - requiredModuleStatus == ModuleStatus::EVALUATED || - requiredModuleStatus == ModuleStatus::ERRORED); - // d. Assert: requiredModule.[[Status]] is "instantiating" if and only if requiredModule is in stack. - // e. If requiredModule.[[Status]] is "instantiating", then - if (requiredModuleStatus == ModuleStatus::INSTANTIATING) { - // d. Assert: requiredModule.[[Status]] is "instantiating" if and only if requiredModule is in stack. - ASSERT(std::find(stack.begin(), stack.end(), requiredModule) != stack.end()); - // i. Assert: requiredModule is a Source Text Module Record. - // ii. Set module.[[DFSAncestorIndex]] to min( - // module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]). - int dfsAncIdx = std::min(module->GetDFSAncestorIndex(), requiredModule->GetDFSAncestorIndex()); - module->SetDFSAncestorIndex(dfsAncIdx); - } - return std::nullopt; -} - -int SourceTextModule::InnerModuleInstantiation(JSThread *thread, const JSHandle &moduleRecord, - CVector> &stack, int index, const ExecuteTypes &executeType) +int SourceTextModule::FinishModuleInstantiation(JSThread *thread, JSHandle module, + CVector> &stack, int index) { // Add a safepoint here to check if a suspension is needed. thread->CheckSafepointIfSuspended(); + // ArkTS module doesn't implement other module Record, delete follow branch. // 1. If module is not a Source Text Module Record, then - if (!moduleRecord.GetTaggedValue().IsSourceTextModule()) { - STACK_LIMIT_CHECK(thread, SourceTextModule::UNDEFINED_INDEX); - SourceTextModule::Instantiate(thread, JSHandle::Cast(moduleRecord)); // a. Perform ? module.Instantiate(). - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); // b. Return index. - return index; - } - JSHandle module = JSHandle::Cast(moduleRecord); // 2. If module.[[Status]] is one of LINKING, LINKED, EVALUATING-ASYNC, or EVALUATED, then Return index. ModuleStatus status = module->GetStatus(); - if (status != ModuleStatus::UNINSTANTIATED && status != ModuleStatus::EVALUATING) { + if (status >= ModuleStatus::INSTANTIATING) { return index; } - if (SourceTextModule::IsSharedModule(module) && status == ModuleStatus::EVALUATING) { - LOG_FULL(INFO) << "circular dependency occurred of shared-module"; - return index; - } - // 3. Assert: module.[[Status]] is "uninstantiated". - ASSERT(status == ModuleStatus::UNINSTANTIATED); + // 3. Assert: module.[[Status]] is "PREINSTANTIATING". + ASSERT(status == ModuleStatus::PREINSTANTIATING); // 4. Set module.[[Status]] to "instantiating". module->SetStatus(ModuleStatus::INSTANTIATING); // 5. Set module.[[DFSIndex]] to index. @@ -581,17 +613,28 @@ int SourceTextModule::InnerModuleInstantiation(JSThread *thread, const JSHandle< // 8. Append module to stack. stack.emplace_back(module); // 9. For each String required that is an element of module.[[RequestedModules]], do - if (!module->GetModuleRequests().IsUndefined()) { - JSHandle moduleRequests(thread, module->GetModuleRequests()); + if (!module->GetRequestedModules().IsUndefined()) { JSHandle requestedModules(thread, module->GetRequestedModules()); - size_t moduleRequestsLen = moduleRequests->GetLength(); - JSMutableHandle required(thread, thread->GlobalConstants()->GetUndefined()); - for (size_t idx = 0; idx < moduleRequestsLen; idx++) { - required.Update(moduleRequests->Get(idx)); - auto result = HandleInnerModuleInstantiation( - thread, module, required, stack, requestedModules, idx, index, executeType); - if (UNLIKELY(result.has_value())) { // exception occurs - return result.value(); + size_t requestedModulesLen = requestedModules->GetLength(); + for (size_t idx = 0; idx < requestedModulesLen; idx++) { + JSHandle requiredModule = + GetRequestedModule(thread, requestedModules, idx); + index = FinishModuleInstantiation(thread, requiredModule, stack, index); + RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); + // c. Assert: requiredModule.[[Status]] is one of LINKING, LINKED, EVALUATING-ASYNC, or EVALUATED. + ModuleStatus requiredModuleStatus = requiredModule->GetStatus(); + ASSERT(requiredModuleStatus >= ModuleStatus::INSTANTIATING && + requiredModuleStatus != ModuleStatus::EVALUATING); + // d. Assert: requiredModule.[[Status]] is "instantiating" if and only if requiredModule is in stack. + // e. If requiredModule.[[Status]] is "instantiating", then + if (requiredModuleStatus == ModuleStatus::INSTANTIATING) { + // d. Assert: requiredModule.[[Status]] is "instantiating" if and only if requiredModule is in stack. + ASSERT(std::find(stack.begin(), stack.end(), requiredModule) != stack.end()); + // i. Assert: requiredModule is a Source Text Module Record. + // ii. Set module.[[DFSAncestorIndex]] to min( + // module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]). + int dfsAncIdx = std::min(module->GetDFSAncestorIndex(), requiredModule->GetDFSAncestorIndex()); + module->SetDFSAncestorIndex(dfsAncIdx); } } } @@ -640,7 +683,7 @@ void SourceTextModule::ModuleDeclarationEnvironmentSetup(JSThread *thread, importName.Update(in->GetImportName()); // a. Let importedModule be ! HostResolveImportedModule(module, in.[[ModuleRequest]]). JSHandle importedModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, in->GetModuleRequestIndex())); + GetRequestedModule(thread, requestedModules, in->GetModuleRequestIndex())); RETURN_IF_ABRUPT_COMPLETION(thread); // c. If in.[[ImportName]] is "*", then JSHandle starString = globalConstants->GetHandledStarString(); @@ -716,8 +759,8 @@ void SourceTextModule::ModuleDeclarationArrayEnvironmentSetup(JSThread *thread, in.Update(importEntries->Get(idx)); importName.Update(in->GetImportName()); // a. Let importedModule be ! HostResolveImportedModule(module, in.[[ModuleRequest]]). - JSHandle importedModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, in->GetModuleRequestIndex())); + JSHandle importedModule = + GetRequestedModule(thread, requestedModules, in->GetModuleRequestIndex()); RETURN_IF_ABRUPT_COMPLETION(thread); // c. If in.[[ImportName]] is "*", then JSHandle starString = globalConstants->GetHandledStarString(); @@ -877,8 +920,7 @@ int SourceTextModule::EvaluateForConcurrent(JSThread *thread, const JSHandleGetStatus(); ASSERT((status == ModuleStatus::INSTANTIATED || status == ModuleStatus::EVALUATED)); // 4. Let result be InnerModuleEvaluation(module, stack, 0) - JSHandle moduleRecord = JSHandle::Cast(module); - int result = SourceTextModule::ModuleEvaluation(thread, moduleRecord, 0, method); + int result = SourceTextModule::ModuleEvaluation(thread, module, 0, method); // 5. If result is an abrupt completion, then if (thread->HasPendingException()) { return result; @@ -888,26 +930,11 @@ int SourceTextModule::EvaluateForConcurrent(JSThread *thread, const JSHandle &moduleRecord, +int SourceTextModule::InnerModuleEvaluationUnsafe(JSThread *thread, JSHandle &module, CVector> &stack, CVector> &errorStack, int index, const void *buffer, size_t size, const ExecuteTypes &executeType) { STACK_LIMIT_CHECK(thread, index); - if (!moduleRecord.GetTaggedValue().IsSourceTextModule()) { - RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); - JSTaggedValue promise = SourceTextModule::Evaluate(thread, JSHandle::Cast(moduleRecord)); - PromiseState state = JSPromise::Cast(moduleRecord.GetTaggedValue().GetTaggedObject())->GetPromiseState(); - ASSERT(state != PromiseState::PENDING); - if (state == PromiseState::REJECTED) { - ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); - JSTaggedValue promiseResult = JSPromise::Cast(promise.GetTaggedObject())->GetPromiseResult(); - JSHandle error = - factory->GetJSError(base::ErrorType::ERROR, nullptr, StackCheck::NO); - THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error.GetTaggedValue(), promiseResult.GetInt()); - } - return index; - } - JSHandle module = JSHandle::Cast(moduleRecord); ModuleStatus status = module->GetStatus(); if (status >= ModuleStatus::EVALUATING_ASYNC) { if (status == ModuleStatus::ERRORED) { @@ -938,8 +965,7 @@ int SourceTextModule::InnerModuleEvaluationUnsafe(JSThread *thread, const JSHand if (module->IsLazyImportModule(idx)) { continue; } - requiredModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, idx)); + requiredModule = GetRequestedModule(thread, requestedModules, idx); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); if (moduleLogger != nullptr) { moduleLogger->InsertParentModule(module, requiredModule); @@ -1057,16 +1083,15 @@ ModuleStatus SourceTextModule::GetModuleEvaluatingType(JSThread *thread, StateVi return module->GetStatus(); } -int SourceTextModule::InnerModuleEvaluation(JSThread *thread, const JSHandle &module, +int SourceTextModule::InnerModuleEvaluation(JSThread *thread, JSHandle &module, CVector> &stack, CVector> &errorStack, int index, const void *buffer, size_t size, const ExecuteTypes &executeType) { bool isShared = IsSharedModule(module); - JSHandle moduleRecord = JSHandle::Cast(module); if (!isShared) { return SourceTextModule::InnerModuleEvaluationUnsafe( - thread, moduleRecord, stack, errorStack, index, buffer, size, executeType); + thread, module, stack, errorStack, index, buffer, size, executeType); } else { StateVisit &stateVisit = SharedModuleManager::GetInstance()->findModuleMutexWithLock(thread, module); ModuleStatus status = module->GetStatus(); @@ -1083,7 +1108,7 @@ int SourceTextModule::InnerModuleEvaluation(JSThread *thread, const JSHandleGetThreadId(); int idx = SourceTextModule::InnerModuleEvaluationUnsafe( - thread, moduleRecord, stack, errorStack, index, buffer, size, executeType); + thread, module, stack, errorStack, index, buffer, size, executeType); return idx; } return index; @@ -1120,10 +1145,9 @@ void SourceTextModule::HandleConcurrentEvaluateResult(JSThread *thread, JSHandle ASSERT(stack.empty()); } -int SourceTextModule::ModuleEvaluation(JSThread *thread, const JSHandle &moduleRecord, +int SourceTextModule::ModuleEvaluation(JSThread *thread, const JSHandle &module, int index, const JSHandle &method) { - JSHandle module = JSHandle::Cast(moduleRecord); if (!module->GetRequestedModules().IsUndefined()) { JSHandle requestedModules(thread, module->GetRequestedModules()); size_t requestedModulesLen = requestedModules->GetLength(); @@ -1134,8 +1158,7 @@ int SourceTextModule::ModuleEvaluation(JSThread *thread, const JSHandle requiredModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, idx)); + JSHandle requiredModule = GetRequestedModule(thread, requestedModules, idx); RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, index); ModuleTypes moduleType = requiredModule->GetTypes(); @@ -1573,8 +1596,8 @@ JSHandle SourceTextModule::ResolveIndirectExport(JSThread *thread if (JSTaggedValue::SameValue(exportName.GetTaggedValue(), ee->GetExportName())) { // i. Assert: module imports a specific binding for this export. // ii. Let importedModule be ? HostResolveImportedModule(module, e.[[ModuleRequest]]). - JSHandle requestedModule = JSHandle::Cast( - GetRequestedModule(thread, module, requestedModules, ee->GetModuleRequestIndex())); + JSHandle requestedModule = + GetRequestedModule(thread, requestedModules, ee->GetModuleRequestIndex()); RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread); // iii. Return importedModule.ResolveExport(e.[[ImportName]], resolveVector). importName.Update(ee->GetImportName()); @@ -2135,22 +2158,18 @@ void SourceTextModule::HandleErrorStack(JSThread *thread, const CVector SourceTextModule::GetRequestedModule(JSThread *thread, - const JSHandle module, - const JSHandle requestedModules, - uint32_t idx) +JSHandle SourceTextModule::GetRequestedModule(JSThread *thread, + const JSHandle requestedModules, + uint32_t idx) { - // if module is not shared or circularImport, requestedModules may not be modules. - if (!requestedModules.GetTaggedValue().IsUndefined()) { - // directly get SourceTextModule. - JSHandle moduleA(thread, requestedModules->Get(idx)); - if (moduleA->IsSourceTextModule()) { - return moduleA; - } + JSHandle request(thread, requestedModules->Get(idx)); + if (request->IsSourceTextModule()) { + // current is normal module: directly get require SourceTextModule. + return JSHandle::Cast(request); } - // resolve or find module by request string. - JSHandle moduleRequests(thread, module->GetModuleRequests()); - JSHandle moduleRequest(thread, moduleRequests->Get(idx)); - return ModuleResolver::HostResolveImportedModule(thread, module, moduleRequest); + // current is shared module: resolve or find request module by request string. + ModuleManager *moduleManager = thread->GetCurrentEcmaContext()->GetModuleManager(); + CString requestStr = ModulePathHelper::Utf8ConvertToString(request.GetTaggedValue()); + return moduleManager->GetImportedModule(requestStr); } } // namespace panda::ecmascript diff --git a/ecmascript/module/js_module_source_text.h b/ecmascript/module/js_module_source_text.h index aa29b4badda8b5c749a527a2214fbcc750077dee..4705b253216bbffb60f12bcc47cfa5e8b6b372ef 100644 --- a/ecmascript/module/js_module_source_text.h +++ b/ecmascript/module/js_module_source_text.h @@ -27,7 +27,8 @@ namespace panda::ecmascript { struct StateVisit; enum class ModuleStatus : uint8_t { // don't change order - UNINSTANTIATED = 0x01, + UNINSTANTIATED = 0x0, + PREINSTANTIATING, INSTANTIATING, INSTANTIATED, EVALUATING, @@ -100,23 +101,19 @@ public: static JSHandle ResolveCjsStarExport(JSThread *thread, const JSHandle &cjsModule, const JSHandle &exportName); - // 15.2.1.16.4.1 InnerModuleInstantiation ( module, stack, index ) - static int InnerModuleInstantiation(JSThread *thread, - const JSHandle &moduleRecord, CVector> &stack, - int index, const ExecuteTypes &executeType = ExecuteTypes::STATIC); // 15.2.1.16.4.2 ModuleDeclarationEnvironmentSetup ( module ) static void ModuleDeclarationEnvironmentSetup(JSThread *thread, const JSHandle &module); static void ModuleDeclarationArrayEnvironmentSetup(JSThread *thread, const JSHandle &module); // 15.2.1.16.5.1 InnerModuleEvaluation ( module, stack, index ) - static int InnerModuleEvaluation(JSThread *thread, const JSHandle &moduleRecord, + static int InnerModuleEvaluation(JSThread *thread, JSHandle &moduleRecord, CVector> &stack, CVector> &errorStack, int index, const void *buffer = nullptr, size_t size = 0, const ExecuteTypes &executeType = ExecuteTypes::STATIC); static int InnerModuleEvaluationUnsafe(JSThread *thread, - const JSHandle &moduleRecord, CVector> &stack, + JSHandle &module, CVector> &stack, CVector> &errorStack, int index, const void *buffer, size_t size, const ExecuteTypes &executeType); // 15.2.1.16.5.2 ModuleExecution ( module ) @@ -378,7 +375,7 @@ public: static std::optional> GetConcurrentRequestedModules(const JSHandle &method); static int EvaluateForConcurrent(JSThread *thread, const JSHandle &module, const JSHandle &method); - static int ModuleEvaluation(JSThread *thread, const JSHandle &moduleRecord, + static int ModuleEvaluation(JSThread *thread, const JSHandle &module, int index, const JSHandle &method); static void CheckCircularImportTool(JSThread *thread, const CString &circularModuleRecordName, CList &referenceList, bool printOtherCircular = false); @@ -393,10 +390,16 @@ public: static void SetExportName(JSThread *thread, const JSHandle requestedModule, CVector &exportedNames, JSHandle &newExportStarSet); static void RecordEvaluatedOrError(JSThread *thread, JSHandle module); - static JSHandle GetRequestedModule(JSThread *thread, - const JSHandle module, - const JSHandle requestedModules, - uint32_t idx); + static JSHandle GetRequestedModule(JSThread *thread, + const JSHandle requestedModules, + uint32_t idx); + static bool PreModuleInstantiation(JSThread *thread, + JSHandle module, + const ExecuteTypes &executeType); + static int FinishModuleInstantiation(JSThread *thread, + JSHandle module, + CVector> &stack, + int index); private: static JSHandle GetStarResolution(JSThread *thread, const JSHandle &exportName, @@ -421,15 +424,9 @@ private: const JSTaggedValue &dictionary); static void DFSModuleInstantiation(JSHandle &module, CVector> &stack); - static std::optional HandleInnerModuleInstantiation(JSThread *thread, - JSHandle &module, - JSMutableHandle &required, - CVector> &stack, - JSHandle requestModules, - size_t &moduleRequestsIdx, int &index, - const ExecuteTypes &executeType); static int HandleInstantiateException(JSHandle &module, const CVector> &stack, int result); + static void HandlePreInstantiationException(JSThread *thread, JSHandle module); static void HandleEvaluateResult(JSThread *thread, JSHandle &module, JSHandle &capability, const CVector> &stack, diff --git a/ecmascript/module/module_data_extractor.cpp b/ecmascript/module/module_data_extractor.cpp index 4baea859f4a2593a8335e85137466e999fc2d168..a1ababd508a310a3b78214ebf897241a8b70880b 100644 --- a/ecmascript/module/module_data_extractor.cpp +++ b/ecmascript/module/module_data_extractor.cpp @@ -65,10 +65,11 @@ void ModuleDataExtractor::ExtractModuleDatas(JSThread *thread, const JSPandaFile const std::vector &moduleRequests = mda.getModuleRequests(); size_t len = moduleRequests.size(); JSHandle moduleRequestArray; - JSHandle requestModuleArray(thread->GlobalConstants()->GetHandledUndefined()); + JSHandle requestModuleArray; bool isShared = SourceTextModule::IsSharedModule(moduleRecord); if (isShared) { moduleRequestArray = factory->NewSTaggedArray(len, JSTaggedValue::Hole(), MemSpaceType::SHARED_OLD_SPACE); + requestModuleArray = factory->NewSTaggedArray(len, JSTaggedValue::Hole(), MemSpaceType::SHARED_OLD_SPACE); } else { moduleRequestArray = factory->NewTaggedArray(len); requestModuleArray = factory->NewTaggedArray(len); @@ -81,11 +82,8 @@ void ModuleDataExtractor::ExtractModuleDatas(JSThread *thread, const JSPandaFile } if (len > 0) { moduleRecord->SetModuleRequests(thread, moduleRequestArray); - // For .[RequestedModules], normal module will later replace by sourceTextModule + // For .[RequestedModules], will later replace by sourceTextModule/recordName moduleRecord->SetRequestedModules(thread, requestModuleArray); - if (isShared) { - moduleRecord->SetRequestedModules(thread, moduleRequestArray); - } } uint32_t lazyImportIdx = recordInfo->lazyImportIdx; diff --git a/ecmascript/module/tests/ecma_module_test.cpp b/ecmascript/module/tests/ecma_module_test.cpp index 2d202561391b5144a5613fdbf6b27689856a342c..c4ea30081f30efe75a3bd5acca9a855b4fd9ad3b 100644 --- a/ecmascript/module/tests/ecma_module_test.cpp +++ b/ecmascript/module/tests/ecma_module_test.cpp @@ -2167,7 +2167,7 @@ HWTEST_F_L0(EcmaModuleTest, EvaluateNativeModule3) } -HWTEST_F_L0(EcmaModuleTest, InnerModuleInstantiation) +HWTEST_F_L0(EcmaModuleTest, ModuleInstantiation) { auto vm = thread->GetEcmaVM(); ObjectFactory *objectFactory = vm->GetFactory(); @@ -2178,7 +2178,8 @@ HWTEST_F_L0(EcmaModuleTest, InnerModuleInstantiation) module->SetStatus(ModuleStatus::UNINSTANTIATED); module->SetIsNewBcVersion(false); CVector> stack; - int index = SourceTextModule::InnerModuleInstantiation(thread, JSHandle::Cast(module), stack, 1); + SourceTextModule::PreModuleInstantiation(thread, module, ExecuteTypes::STATIC); + int index = SourceTextModule::FinishModuleInstantiation(thread, module, stack, 1); EXPECT_EQ(index, 2); } @@ -2591,7 +2592,7 @@ HWTEST_F_L0(EcmaModuleTest, GetBundleNameWithRecordName) EXPECT_EQ(res, expectRes); } -HWTEST_F_L0(EcmaModuleTest, InnerModuleInstantiation_ReEnterTest) +HWTEST_F_L0(EcmaModuleTest, ModuleInstantiation_ReEnterTest) { auto vm = thread->GetEcmaVM(); ObjectFactory *objectFactory = vm->GetFactory(); @@ -2603,8 +2604,14 @@ HWTEST_F_L0(EcmaModuleTest, InnerModuleInstantiation_ReEnterTest) module->SetIsNewBcVersion(true); module->SetSharedType(SharedTypes::SHARED_MODULE); CVector> stack; - int index = SourceTextModule::InnerModuleInstantiation(thread, JSHandle::Cast(module), stack, 1); + SourceTextModule::PreModuleInstantiation(thread, module, ExecuteTypes::STATIC); + int index = SourceTextModule::FinishModuleInstantiation(thread, module, stack, 1); EXPECT_EQ(index, 1); + module->SetStatus(ModuleStatus::EVALUATING); + module->SetSharedType(SharedTypes::UNSENDABLE_MODULE); + SourceTextModule::PreModuleInstantiation(thread, module, ExecuteTypes::STATIC); + index = SourceTextModule::FinishModuleInstantiation(thread, module, stack, 1); + EXPECT_EQ(index, 2); } HWTEST_F_L0(EcmaModuleTest, TransformToNormalizedOhmUrl) @@ -4236,7 +4243,8 @@ HWTEST_F_L0(EcmaModuleTest, CheckAndThrowModuleError) HWTEST_F_L0(EcmaModuleTest, ModuleStatusOrder) { - EXPECT_EQ(static_cast(ModuleStatus::UNINSTANTIATED), 0x01); + EXPECT_EQ(static_cast(ModuleStatus::UNINSTANTIATED), 0x00); + EXPECT_EQ(static_cast(ModuleStatus::PREINSTANTIATING), 0x01); EXPECT_EQ(static_cast(ModuleStatus::INSTANTIATING), 0x02); EXPECT_EQ(static_cast(ModuleStatus::INSTANTIATED), 0x03); EXPECT_EQ(static_cast(ModuleStatus::EVALUATING), 0x04);