• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ecmascript/module/js_module_manager.h"
16 
17 #include "ecmascript/interpreter/frame_handler.h"
18 #include "ecmascript/jspandafile/js_pandafile_executor.h"
19 #include "ecmascript/jspandafile/js_pandafile_manager.h"
20 #include "ecmascript/module/js_module_deregister.h"
21 #include "ecmascript/module/js_shared_module_manager.h"
22 #include "ecmascript/module/module_data_extractor.h"
23 #include "ecmascript/module/module_manager_helper.h"
24 #include "ecmascript/module/module_path_helper.h"
25 #include "ecmascript/module/module_tools.h"
26 #include "ecmascript/require/js_cjs_module.h"
27 #ifdef PANDA_TARGET_WINDOWS
28 #include <algorithm>
29 #endif
30 
31 namespace panda::ecmascript {
32 using StringHelper = base::StringHelper;
33 using JSPandaFile = ecmascript::JSPandaFile;
34 using JSRecordInfo = ecmascript::JSPandaFile::JSRecordInfo;
35 
ModuleManager(EcmaVM * vm)36 ModuleManager::ModuleManager(EcmaVM *vm) : vm_(vm) {}
37 
GetCurrentModule()38 JSTaggedValue ModuleManager::GetCurrentModule()
39 {
40     FrameHandler frameHandler(vm_->GetJSThread());
41     JSTaggedValue currentFunc = frameHandler.GetFunction();
42     JSTaggedValue module = JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule();
43     if (SourceTextModule::IsSendableFunctionModule(module)) {
44         CString recordNameStr = SourceTextModule::GetModuleName(module);
45         return HostGetImportedModule(recordNameStr).GetTaggedValue();
46     }
47     return module;
48 }
49 
GenerateSendableFuncModule(const JSHandle<JSTaggedValue> & module)50 JSHandle<JSTaggedValue> ModuleManager::GenerateSendableFuncModule(const JSHandle<JSTaggedValue> &module)
51 {
52     // Clone isolate module at shared-heap to mark sendable class.
53     return SendableClassModule::GenerateSendableFuncModule(vm_->GetJSThread(), module);
54 }
55 
GetModuleValueInner(int32_t index)56 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index)
57 {
58     JSTaggedValue currentModule = GetCurrentModule();
59     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
60         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
61     }
62     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
63 }
64 
GetModuleValueInner(int32_t index,JSTaggedValue jsFunc)65 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index, JSTaggedValue jsFunc)
66 {
67     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
68     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
69         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
70     }
71     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
72 }
73 
GetModuleValueInner(int32_t index,JSHandle<JSTaggedValue> currentModule)74 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index, JSHandle<JSTaggedValue> currentModule)
75 {
76     if (currentModule->IsUndefined()) { // LCOV_EXCL_BR_LINE
77         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
78     }
79     return SourceTextModule::Cast(currentModule->GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
80 }
81 
GetModuleValueOutter(int32_t index)82 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index)
83 {
84     JSTaggedValue currentModule = GetCurrentModule();
85     return GetModuleValueOutterInternal(index, currentModule);
86 }
87 
GetModuleValueOutter(int32_t index,JSTaggedValue jsFunc)88 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index, JSTaggedValue jsFunc)
89 {
90     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
91     return GetModuleValueOutterInternal(index, currentModule);
92 }
93 
GetModuleValueOutter(int32_t index,JSHandle<JSTaggedValue> currentModule)94 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index, JSHandle<JSTaggedValue> currentModule)
95 {
96     return GetModuleValueOutterInternal(index, currentModule.GetTaggedValue());
97 }
98 
GetModuleValueOutterInternal(int32_t index,JSTaggedValue currentModule)99 JSTaggedValue ModuleManager::GetModuleValueOutterInternal(int32_t index, JSTaggedValue currentModule)
100 {
101     JSThread *thread = vm_->GetJSThread();
102     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
103         LOG_FULL(FATAL) << "GetModuleValueOutter currentModule failed";
104         UNREACHABLE();
105     }
106     JSHandle<SourceTextModule> currentModuleHdl(thread, currentModule);
107     JSTaggedValue moduleEnvironment = currentModuleHdl->GetEnvironment();
108     if (moduleEnvironment.IsUndefined()) {
109         return thread->GlobalConstants()->GetUndefined();
110     }
111     ASSERT(moduleEnvironment.IsTaggedArray());
112     JSTaggedValue resolvedBinding = TaggedArray::Cast(moduleEnvironment.GetTaggedObject())->Get(index);
113     ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
114     if (moduleLogger != nullptr) {
115         return ModuleTools::ProcessModuleLoadInfo(thread, currentModuleHdl, resolvedBinding, index);
116     }
117     if (resolvedBinding.IsResolvedIndexBinding()) {
118         ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
119         JSTaggedValue resolvedModule = binding->GetModule();
120         JSHandle<SourceTextModule> module(thread, resolvedModule);
121         ASSERT(resolvedModule.IsSourceTextModule());
122 
123         // Support for only modifying var value of HotReload.
124         // Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
125         EcmaContext *context = thread->GetCurrentEcmaContext();
126         if (context->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) {
127             const JSHandle<JSTaggedValue> resolvedModuleOfHotReload =
128                 context->FindPatchModule(module->GetEcmaModuleRecordNameString());
129             if (!resolvedModuleOfHotReload->IsHole()) {
130                 resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
131                 JSHandle<SourceTextModule> moduleOfHotReload(thread, resolvedModule);
132                 return ModuleManagerHelper::GetModuleValue(thread, moduleOfHotReload, binding->GetIndex());
133             }
134         }
135         return ModuleManagerHelper::GetModuleValue(thread, module, binding->GetIndex());
136     }
137     if (resolvedBinding.IsResolvedBinding()) {
138         ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
139         JSTaggedValue resolvedModule = binding->GetModule();
140         JSHandle<SourceTextModule> module(thread, resolvedModule);
141         if (SourceTextModule::IsNativeModule(module->GetTypes())) {
142             return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
143                 thread, currentModuleHdl, module, index, binding->GetBindingName());
144         }
145         if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
146             return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
147                 thread, currentModuleHdl, module, index, binding->GetBindingName());
148         }
149     }
150     if (resolvedBinding.IsResolvedRecordIndexBinding()) {
151         return ModuleManagerHelper::GetModuleValueFromIndexBinding(thread, currentModuleHdl, resolvedBinding);
152     }
153     if (resolvedBinding.IsResolvedRecordBinding()) {
154         return ModuleManagerHelper::GetModuleValueFromRecordBinding(thread, currentModuleHdl, resolvedBinding);
155     }
156 
157     std::ostringstream oss;
158     currentModule.Dump(oss);
159     LOG_ECMA(FATAL) << "Get module value failed, mistaken ResolvedBinding"
160         << ", index: " << index << ", currentModule: " << oss.str();
161     UNREACHABLE();
162 }
163 
GetLazyModuleValueOutter(int32_t index,JSTaggedValue jsFunc)164 JSTaggedValue ModuleManager::GetLazyModuleValueOutter(int32_t index, JSTaggedValue jsFunc)
165 {
166     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
167     return GetLazyModuleValueOutterInternal(index, currentModule);
168 }
169 
GetLazyModuleValueOutterInternal(int32_t index,JSTaggedValue currentModule)170 JSTaggedValue ModuleManager::GetLazyModuleValueOutterInternal(int32_t index, JSTaggedValue currentModule)
171 {
172     JSThread *thread = vm_->GetJSThread();
173     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
174         LOG_FULL(FATAL) << "GetLazyModuleValueOutter currentModule failed";
175         UNREACHABLE();
176     }
177     JSHandle<SourceTextModule> currentModuleHdl(thread, currentModule);
178     JSTaggedValue moduleEnvironment = currentModuleHdl->GetEnvironment();
179     if (moduleEnvironment.IsUndefined()) {
180         return thread->GlobalConstants()->GetUndefined();
181     }
182     ASSERT(moduleEnvironment.IsTaggedArray());
183     JSTaggedValue resolvedBinding = TaggedArray::Cast(moduleEnvironment.GetTaggedObject())->Get(index);
184     if (resolvedBinding.IsResolvedIndexBinding()) {
185         JSHandle<ResolvedIndexBinding> binding(thread, resolvedBinding);
186         JSTaggedValue resolvedModule = binding->GetModule();
187         JSHandle<SourceTextModule> module(thread, resolvedModule);
188         ASSERT(resolvedModule.IsSourceTextModule());
189         // Support for only modifying var value of HotReload.
190         // Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
191         EcmaContext *context = thread->GetCurrentEcmaContext();
192         if (context->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) {
193             const JSHandle<JSTaggedValue> resolvedModuleOfHotReload =
194                 context->FindPatchModule(module->GetEcmaModuleRecordNameString());
195             if (!resolvedModuleOfHotReload->IsHole()) {
196                 resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
197                 JSHandle<SourceTextModule> moduleOfHotReload(thread, resolvedModule);
198                 SourceTextModule::Evaluate(thread, moduleOfHotReload, nullptr);
199                 RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
200                 return ModuleManagerHelper::GetModuleValue(thread, moduleOfHotReload, binding->GetIndex());
201             }
202         }
203         SourceTextModule::Evaluate(thread, module, nullptr);
204         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
205         return ModuleManagerHelper::GetModuleValue(thread, module, binding->GetIndex());
206     }
207     if (resolvedBinding.IsResolvedBinding()) {
208         JSHandle<ResolvedBinding> binding(thread, resolvedBinding);
209         JSTaggedValue resolvedModule = binding->GetModule();
210         JSHandle<SourceTextModule> module(thread, resolvedModule);
211         ModuleStatus status = module->GetStatus();
212         ModuleTypes moduleType = module->GetTypes();
213         if (SourceTextModule::IsNativeModule(moduleType)) {
214             SourceTextModule::EvaluateNativeModule(thread, module, moduleType);
215             return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
216                 thread, currentModuleHdl, module, index, binding->GetBindingName());
217         }
218         if (moduleType == ModuleTypes::CJS_MODULE) {
219             if (status != ModuleStatus::EVALUATED) {
220                 SourceTextModule::ModuleExecution(thread, module, nullptr, 0);
221                 module->SetStatus(ModuleStatus::EVALUATED);
222             }
223             return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
224                 thread, currentModuleHdl, module, index, binding->GetBindingName());
225         }
226     }
227     if (resolvedBinding.IsResolvedRecordIndexBinding()) {
228         return ModuleManagerHelper::GetLazyModuleValueFromIndexBinding(thread, currentModuleHdl, resolvedBinding);
229     }
230     if (resolvedBinding.IsResolvedRecordBinding()) {
231         return ModuleManagerHelper::GetLazyModuleValueFromRecordBinding(thread, currentModuleHdl, resolvedBinding);
232     }
233     LOG_ECMA(FATAL) << "Get module value failed, mistaken ResolvedBinding";
234     UNREACHABLE();
235 }
236 
StoreModuleValue(int32_t index,JSTaggedValue value)237 void ModuleManager::StoreModuleValue(int32_t index, JSTaggedValue value)
238 {
239     JSThread *thread = vm_->GetJSThread();
240     JSHandle<SourceTextModule> currentModule(thread, GetCurrentModule());
241     StoreModuleValueInternal(currentModule, index, value);
242 }
243 
StoreModuleValue(int32_t index,JSTaggedValue value,JSTaggedValue jsFunc)244 void ModuleManager::StoreModuleValue(int32_t index, JSTaggedValue value, JSTaggedValue jsFunc)
245 {
246     JSThread *thread = vm_->GetJSThread();
247     JSHandle<SourceTextModule> currentModule(thread, JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule());
248     StoreModuleValueInternal(currentModule, index, value);
249 }
250 
StoreModuleValueInternal(JSHandle<SourceTextModule> & currentModule,int32_t index,JSTaggedValue value)251 void ModuleManager::StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
252                                              int32_t index, JSTaggedValue value)
253 {
254     if (currentModule.GetTaggedValue().IsUndefined()) { // LCOV_EXCL_BR_LINE
255         LOG_FULL(FATAL) << "StoreModuleValue currentModule failed";
256         UNREACHABLE();
257     }
258     JSThread *thread = vm_->GetJSThread();
259     JSHandle<JSTaggedValue> valueHandle(thread, value);
260     currentModule->StoreModuleValue(thread, index, valueHandle);
261 }
262 
GetModuleValueInner(JSTaggedValue key)263 JSTaggedValue ModuleManager::GetModuleValueInner(JSTaggedValue key)
264 {
265     JSTaggedValue currentModule = GetCurrentModule();
266     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
267         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
268         UNREACHABLE();
269     }
270     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), key, false);
271 }
272 
GetModuleValueInner(JSTaggedValue key,JSTaggedValue jsFunc)273 JSTaggedValue ModuleManager::GetModuleValueInner(JSTaggedValue key, JSTaggedValue jsFunc)
274 {
275     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
276     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
277         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
278         UNREACHABLE();
279     }
280     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), key, false);
281 }
282 
GetModuleValueOutter(JSTaggedValue key)283 JSTaggedValue ModuleManager::GetModuleValueOutter(JSTaggedValue key)
284 {
285     JSTaggedValue currentModule = GetCurrentModule();
286     return GetModuleValueOutterInternal(key, currentModule);
287 }
288 
GetModuleValueOutter(JSTaggedValue key,JSTaggedValue jsFunc)289 JSTaggedValue ModuleManager::GetModuleValueOutter(JSTaggedValue key, JSTaggedValue jsFunc)
290 {
291     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
292     return GetModuleValueOutterInternal(key, currentModule);
293 }
294 
GetModuleValueOutterInternal(JSTaggedValue key,JSTaggedValue currentModule)295 JSTaggedValue ModuleManager::GetModuleValueOutterInternal(JSTaggedValue key, JSTaggedValue currentModule)
296 {
297     JSThread *thread = vm_->GetJSThread();
298     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
299         LOG_FULL(FATAL) << "GetModuleValueOutter currentModule failed";
300         UNREACHABLE();
301     }
302     JSTaggedValue moduleEnvironment = SourceTextModule::Cast(currentModule.GetTaggedObject())->GetEnvironment();
303     if (moduleEnvironment.IsUndefined()) {
304         return thread->GlobalConstants()->GetUndefined();
305     }
306     int entry = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->FindEntry(key);
307     if (entry == -1) {
308         return thread->GlobalConstants()->GetUndefined();
309     }
310     JSTaggedValue resolvedBinding = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->GetValue(entry);
311     ASSERT(resolvedBinding.IsResolvedBinding());
312     ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
313     JSTaggedValue resolvedModule = binding->GetModule();
314     ASSERT(resolvedModule.IsSourceTextModule());
315     SourceTextModule *module = SourceTextModule::Cast(resolvedModule.GetTaggedObject());
316     if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
317         CString cjsModuleName = SourceTextModule::GetModuleName(JSTaggedValue(module));
318         JSHandle<JSTaggedValue> moduleNameHandle(thread->GetEcmaVM()->GetFactory()->NewFromUtf8(cjsModuleName));
319         return CjsModule::SearchFromModuleCache(thread, moduleNameHandle).GetTaggedValue();
320     }
321     return module->GetModuleValue(thread, binding->GetBindingName(), false);
322 }
323 
StoreModuleValue(JSTaggedValue key,JSTaggedValue value)324 void ModuleManager::StoreModuleValue(JSTaggedValue key, JSTaggedValue value)
325 {
326     JSThread *thread = vm_->GetJSThread();
327     JSHandle<SourceTextModule> currentModule(thread, GetCurrentModule());
328     StoreModuleValueInternal(currentModule, key, value);
329 }
330 
StoreModuleValue(JSTaggedValue key,JSTaggedValue value,JSTaggedValue jsFunc)331 void ModuleManager::StoreModuleValue(JSTaggedValue key, JSTaggedValue value, JSTaggedValue jsFunc)
332 {
333     JSThread *thread = vm_->GetJSThread();
334     JSHandle<SourceTextModule> currentModule(thread, JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule());
335     StoreModuleValueInternal(currentModule, key, value);
336 }
337 
StoreModuleValueInternal(JSHandle<SourceTextModule> & currentModule,JSTaggedValue key,JSTaggedValue value)338 void ModuleManager::StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
339                                              JSTaggedValue key, JSTaggedValue value)
340 {
341     if (currentModule.GetTaggedValue().IsUndefined()) { // LCOV_EXCL_BR_LINE
342         LOG_FULL(FATAL) << "StoreModuleValue currentModule failed";
343         UNREACHABLE();
344     }
345     JSThread *thread = vm_->GetJSThread();
346     JSHandle<JSTaggedValue> keyHandle(thread, key);
347     JSHandle<JSTaggedValue> valueHandle(thread, value);
348     currentModule->StoreModuleValue(thread, keyHandle, valueHandle);
349 }
GetImportedModule(const CString & referencing)350 JSHandle<SourceTextModule> ModuleManager::GetImportedModule(const CString &referencing)
351 {
352     auto thread = vm_->GetJSThread();
353     if (!IsLocalModuleLoaded(referencing)) {
354         return SharedModuleManager::GetInstance()->GetSModule(thread, referencing);
355     } else {
356         return HostGetImportedModule(referencing);
357     }
358 }
359 
HostGetImportedModule(const CString & referencing)360 JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(const CString &referencing)
361 {
362     auto entry = resolvedModules_.find(referencing);
363     if (entry == resolvedModules_.end()) { // LCOV_EXCL_BR_LINE
364         LOG_ECMA(FATAL) << "Can not get module: " << referencing;
365     }
366     return JSHandle<SourceTextModule>(vm_->GetJSThread(), entry->second);
367 }
368 
HostGetImportedModule(void * src)369 JSTaggedValue ModuleManager::HostGetImportedModule(void *src)
370 {
371     const char *str = reinterpret_cast<char *>(src);
372     CString referencing(str, strlen(str));
373     LOG_FULL(INFO) << "current str during module deregister process : " << referencing;
374     auto entry = resolvedModules_.find(referencing);
375     if (entry == resolvedModules_.end()) {
376         LOG_FULL(INFO) << "The module has been unloaded, " << referencing;
377         return JSTaggedValue::Undefined();
378     }
379     JSTaggedValue result = entry->second;
380     return result;
381 }
382 
IsLocalModuleLoaded(const CString & referencing)383 bool ModuleManager::IsLocalModuleLoaded(const CString& referencing)
384 {
385     auto entry = resolvedModules_.find(referencing);
386     if (entry == resolvedModules_.end()) {
387         return false;
388     }
389     return true;
390 }
391 
IsSharedModuleLoaded(const CString & referencing)392 bool ModuleManager::IsSharedModuleLoaded(const CString &referencing)
393 {
394     SharedModuleManager* sharedModuleManager = SharedModuleManager::GetInstance();
395     return sharedModuleManager->SearchInSModuleManager(vm_->GetJSThread(), referencing);
396 }
397 
IsModuleLoaded(const CString & referencing)398 bool ModuleManager::IsModuleLoaded(const CString &referencing)
399 {
400     if (IsLocalModuleLoaded(referencing)) {
401         return true;
402     }
403     SharedModuleManager* sharedModuleManager = SharedModuleManager::GetInstance();
404     return sharedModuleManager->SearchInSModuleManager(vm_->GetJSThread(), referencing);
405 }
406 
IsEvaluatedModule(const CString & referencing)407 bool ModuleManager::IsEvaluatedModule(const CString &referencing)
408 {
409     auto entry = resolvedModules_.find(referencing);
410     if (entry == resolvedModules_.end()) {
411         return false;
412     }
413     JSTaggedValue result = entry->second;
414     if (SourceTextModule::Cast(result.GetTaggedObject())->GetStatus() ==
415         ModuleStatus::EVALUATED) {
416             return true;
417     }
418     return false;
419 }
420 
421 // This function assumes that referencing already existed in resolvedModules_/resolvedSharedModules_.
IsInstantiatedModule(const CString & referencing)422 bool ModuleManager::IsInstantiatedModule(const CString &referencing)
423 {
424     JSHandle<SourceTextModule> module = GetImportedModule(referencing);
425     return module->GetStatus() == ModuleStatus::INSTANTIATED;
426 }
427 
IsLocalModuleInstantiated(const CString & referencing)428 bool ModuleManager::IsLocalModuleInstantiated(const CString &referencing)
429 {
430     JSHandle<SourceTextModule> module = HostGetImportedModule(referencing);
431     return module->GetStatus() == ModuleStatus::INSTANTIATED;
432 }
433 
HostResolveImportedModuleWithMerge(const CString & moduleFileName,const CString & recordName,bool executeFromJob)434 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModuleWithMerge(const CString &moduleFileName,
435     const CString &recordName, bool executeFromJob)
436 {
437     auto entry = resolvedModules_.find(recordName);
438     if (entry != resolvedModules_.end()) {
439         return JSHandle<JSTaggedValue>(vm_->GetJSThread(), entry->second);
440     }
441     return CommonResolveImportedModuleWithMerge(moduleFileName, recordName, executeFromJob);
442 }
443 
HostResolveImportedModuleWithMergeForHotReload(const CString & moduleFileName,const CString & recordName,bool executeFromJob)444 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModuleWithMergeForHotReload(const CString &moduleFileName,
445     const CString &recordName, bool executeFromJob)
446 {
447     JSThread *thread = vm_->GetJSThread();
448     std::shared_ptr<JSPandaFile> jsPandaFile =
449         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, recordName, false);
450     if (jsPandaFile == nullptr) { // LCOV_EXCL_BR_LINE
451         LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << moduleFileName;
452     }
453     JSHandle<JSTaggedValue> moduleRecord = ResolveModuleWithMerge(thread,
454         jsPandaFile.get(), recordName, executeFromJob);
455     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
456     UpdateResolveImportedModule(recordName, moduleRecord.GetTaggedValue());
457     return moduleRecord;
458 }
459 
CommonResolveImportedModuleWithMerge(const CString & moduleFileName,const CString & recordName,bool executeFromJob)460 JSHandle<JSTaggedValue> ModuleManager::CommonResolveImportedModuleWithMerge(const CString &moduleFileName,
461     const CString &recordName, bool executeFromJob)
462 {
463     JSThread *thread = vm_->GetJSThread();
464     std::shared_ptr<JSPandaFile> jsPandaFile =
465         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, recordName, false);
466     if (jsPandaFile == nullptr) { // LCOV_EXCL_BR_LINE
467         LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << moduleFileName;
468     }
469     JSHandle<JSTaggedValue> moduleRecord = ResolveModuleWithMerge(thread,
470         jsPandaFile.get(), recordName, executeFromJob);
471     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
472     AddResolveImportedModule(recordName, moduleRecord.GetTaggedValue());
473     return moduleRecord;
474 }
475 
HostResolveImportedModule(const CString & referencingModule,bool executeFromJob)476 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const CString &referencingModule, bool executeFromJob)
477 {
478     JSThread *thread = vm_->GetJSThread();
479 
480     CString moduleFileName = referencingModule;
481     if (vm_->IsBundlePack()) {
482         if (!AOTFileManager::GetAbsolutePath(referencingModule, moduleFileName)) {
483             CString msg = "Parse absolute " + referencingModule + " path failed";
484             THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
485         }
486     }
487 
488     auto entry = resolvedModules_.find(moduleFileName);
489     if (entry != resolvedModules_.end()) {
490         return JSHandle<JSTaggedValue>(thread, entry->second);
491     }
492 
493     std::shared_ptr<JSPandaFile> jsPandaFile =
494         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, JSPandaFile::ENTRY_MAIN_FUNCTION);
495     if (jsPandaFile == nullptr) { // LCOV_EXCL_BR_LINE
496         LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << moduleFileName;
497     }
498 
499     return ResolveModule(thread, jsPandaFile.get(), executeFromJob);
500 }
501 
502 // The security interface needs to be modified accordingly.
HostResolveImportedModule(const void * buffer,size_t size,const CString & filename)503 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const void *buffer, size_t size,
504                                                                  const CString &filename)
505 {
506     JSThread *thread = vm_->GetJSThread();
507 
508     auto entry = resolvedModules_.find(filename);
509     if (entry != resolvedModules_.end()) {
510         return JSHandle<JSTaggedValue>(thread, entry->second);
511     }
512 
513     std::shared_ptr<JSPandaFile> jsPandaFile =
514         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, filename,
515                                                            JSPandaFile::ENTRY_MAIN_FUNCTION, buffer, size);
516     if (jsPandaFile == nullptr) { // LCOV_EXCL_BR_LINE
517         LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << filename;
518     }
519 
520     return ResolveModule(thread, jsPandaFile.get());
521 }
522 
ResolveModule(JSThread * thread,const JSPandaFile * jsPandaFile,bool executeFromJob)523 JSHandle<JSTaggedValue> ModuleManager::ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile,
524     bool executeFromJob)
525 {
526     CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
527     JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
528     JSRecordInfo recordInfo = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(JSPandaFile::ENTRY_FUNCTION_NAME);
529     if (jsPandaFile->IsModule(&recordInfo)) {
530         moduleRecord = ModuleDataExtractor::ParseModule(
531             thread, jsPandaFile, moduleFileName, moduleFileName, &recordInfo);
532     } else {
533         ASSERT(jsPandaFile->IsCjs(&recordInfo));
534         moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
535     }
536     // json file can not be compiled into isolate abc.
537     ASSERT(!jsPandaFile->IsJson(&recordInfo));
538     ModuleDeregister::InitForDeregisterModule(moduleRecord, executeFromJob);
539     AddResolveImportedModule(moduleFileName, moduleRecord.GetTaggedValue());
540     return moduleRecord;
541 }
542 
ResolveNativeModule(const CString & moduleRequest,const CString & baseFileName,ModuleTypes moduleType)543 JSHandle<JSTaggedValue> ModuleManager::ResolveNativeModule(const CString &moduleRequest,
544     const CString &baseFileName, ModuleTypes moduleType)
545 {
546     JSThread *thread = vm_->GetJSThread();
547     JSHandle<JSTaggedValue> moduleRecord = ModuleDataExtractor::ParseNativeModule(thread,
548         moduleRequest, baseFileName, moduleType);
549     AddResolveImportedModule(moduleRequest, moduleRecord.GetTaggedValue());
550     return moduleRecord;
551 }
552 
ResolveModuleWithMerge(JSThread * thread,const JSPandaFile * jsPandaFile,const CString & recordName,bool executeFromJob)553 JSHandle<JSTaggedValue> ModuleManager::ResolveModuleWithMerge(
554     JSThread *thread, const JSPandaFile *jsPandaFile, const CString &recordName, bool executeFromJob)
555 {
556     CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
557     JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
558     JSRecordInfo *recordInfo = nullptr;
559     bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(recordName, &recordInfo);
560     if (!hasRecord) {
561         JSHandle<JSTaggedValue> exp(thread, JSTaggedValue::Exception());
562         THROW_MODULE_NOT_FOUND_ERROR_WITH_RETURN_VALUE(thread, recordName, moduleFileName, exp);
563     }
564     if (jsPandaFile->IsModule(recordInfo)) {
565         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
566         moduleRecord = ModuleDataExtractor::ParseModule(thread, jsPandaFile, recordName, moduleFileName, recordInfo);
567     } else if (jsPandaFile->IsJson(recordInfo)) {
568         moduleRecord = ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, moduleFileName, recordName);
569     } else {
570         ASSERT(jsPandaFile->IsCjs(recordInfo));
571         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
572         moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
573     }
574 
575     JSHandle<SourceTextModule>::Cast(moduleRecord)->SetEcmaModuleRecordNameString(recordName);
576     ModuleDeregister::InitForDeregisterModule(moduleRecord, executeFromJob);
577     return moduleRecord;
578 }
579 
AddToInstantiatingSModuleList(const CString & record)580 void ModuleManager::AddToInstantiatingSModuleList(const CString &record)
581 {
582     InstantiatingSModuleList_.push_back(record);
583 }
584 
GetInstantiatingSModuleList()585 CVector<CString> ModuleManager::GetInstantiatingSModuleList()
586 {
587     return InstantiatingSModuleList_;
588 }
589 
ClearInstantiatingSModuleList()590 void ModuleManager::ClearInstantiatingSModuleList()
591 {
592     InstantiatingSModuleList_.clear();
593 }
594 
GetModuleNamespace(int32_t index)595 JSTaggedValue ModuleManager::GetModuleNamespace(int32_t index)
596 {
597     JSTaggedValue currentModule = GetCurrentModule();
598     return GetModuleNamespaceInternal(index, currentModule);
599 }
600 
GetModuleNamespace(int32_t index,JSTaggedValue currentFunc)601 JSTaggedValue ModuleManager::GetModuleNamespace(int32_t index, JSTaggedValue currentFunc)
602 {
603     JSTaggedValue currentModule = JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule();
604     return GetModuleNamespaceInternal(index, currentModule);
605 }
606 
GetModuleNamespaceInternal(int32_t index,JSTaggedValue currentModule)607 JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedValue currentModule)
608 {
609     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
610         LOG_FULL(FATAL) << "GetModuleNamespace currentModule failed";
611         UNREACHABLE();
612     }
613     JSThread *thread = vm_->GetJSThread();
614     SourceTextModule *module = SourceTextModule::Cast(currentModule.GetTaggedObject());
615     JSTaggedValue requestedModule = module->GetRequestedModules();
616     JSTaggedValue moduleName = TaggedArray::Cast(requestedModule.GetTaggedObject())->Get(index);
617     CString moduleRecordName = module->GetEcmaModuleRecordNameString();
618     JSHandle<JSTaggedValue> requiredModule;
619     if (moduleRecordName.empty()) {
620         requiredModule = SourceTextModule::HostResolveImportedModule(thread,
621             JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
622     } else {
623         requiredModule = SourceTextModule::HostResolveImportedModuleWithMerge(thread,
624             JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
625     }
626     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
627     JSHandle<SourceTextModule> requiredModuleST = JSHandle<SourceTextModule>::Cast(requiredModule);
628     ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
629     if (moduleLogger != nullptr) {
630         return ModuleTools::ProcessModuleNameSpaceLoadInfo(thread,
631             JSHandle<SourceTextModule>(thread, module), requiredModuleST);
632     }
633     ModuleTypes moduleType = requiredModuleST->GetTypes();
634     // if requiredModuleST is Native module
635     if (SourceTextModule::IsNativeModule(moduleType)) {
636         return SourceTextModule::Cast(requiredModuleST.GetTaggedValue())->GetModuleValue(thread, 0, false);
637     }
638     // if requiredModuleST is CommonJS
639     if (moduleType == ModuleTypes::CJS_MODULE) {
640         CString cjsModuleName = SourceTextModule::GetModuleName(requiredModuleST.GetTaggedValue());
641         JSHandle<JSTaggedValue> moduleNameHandle(thread->GetEcmaVM()->GetFactory()->NewFromUtf8(cjsModuleName));
642         return CjsModule::SearchFromModuleCache(thread, moduleNameHandle).GetTaggedValue();
643     }
644     // if requiredModuleST is ESM
645     JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModuleST);
646     ASSERT(moduleNamespace->IsModuleNamespace());
647     return moduleNamespace.GetTaggedValue();
648 }
649 
GetModuleNamespace(JSTaggedValue localName)650 JSTaggedValue ModuleManager::GetModuleNamespace(JSTaggedValue localName)
651 {
652     JSTaggedValue currentModule = GetCurrentModule();
653     return GetModuleNamespaceInternal(localName, currentModule);
654 }
655 
GetModuleNamespace(JSTaggedValue localName,JSTaggedValue currentFunc)656 JSTaggedValue ModuleManager::GetModuleNamespace(JSTaggedValue localName, JSTaggedValue currentFunc)
657 {
658     JSTaggedValue currentModule = JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule();
659     return GetModuleNamespaceInternal(localName, currentModule);
660 }
661 
GetModuleNamespaceInternal(JSTaggedValue localName,JSTaggedValue currentModule)662 JSTaggedValue ModuleManager::GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule)
663 {
664     if (currentModule.IsUndefined()) { // LCOV_EXCL_BR_LINE
665         LOG_FULL(FATAL) << "GetModuleNamespace currentModule failed";
666         UNREACHABLE();
667     }
668     JSTaggedValue moduleEnvironment = SourceTextModule::Cast(currentModule.GetTaggedObject())->GetEnvironment();
669     if (moduleEnvironment.IsUndefined()) {
670         return vm_->GetJSThread()->GlobalConstants()->GetUndefined();
671     }
672     int entry = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->FindEntry(localName);
673     if (entry == -1) {
674         return vm_->GetJSThread()->GlobalConstants()->GetUndefined();
675     }
676     JSTaggedValue moduleNamespace = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->GetValue(entry);
677     ASSERT(moduleNamespace.IsModuleNamespace());
678     return moduleNamespace;
679 }
680 
Iterate(const RootVisitor & v)681 void ModuleManager::Iterate(const RootVisitor &v)
682 {
683     for (auto &it : resolvedModules_) {
684         ObjectSlot slot(reinterpret_cast<uintptr_t>(&it.second));
685         v(Root::ROOT_VM, slot);
686         ASSERT(slot.GetTaggedValue() == it.second);
687     }
688 }
689 
GetRecordName(JSTaggedValue module)690 CString ModuleManager::GetRecordName(JSTaggedValue module)
691 {
692     CString entry = "";
693     if (module.IsString()) {
694         entry = ModulePathHelper::Utf8ConvertToString(module);
695     }
696     if (module.IsSourceTextModule()) {
697         SourceTextModule *sourceTextModule = SourceTextModule::Cast(module.GetTaggedObject());
698         CString recordName = sourceTextModule->GetEcmaModuleRecordNameString();
699         if (!recordName.empty()) {
700             return recordName;
701         }
702     }
703     return entry;
704 }
705 
GetExportObjectIndex(EcmaVM * vm,JSHandle<SourceTextModule> ecmaModule,const CString & key)706 int ModuleManager::GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule,
707                                         const CString &key)
708 {
709     JSThread *thread = vm->GetJSThread();
710     if (ecmaModule->GetLocalExportEntries().IsUndefined()) {
711         CString msg = "No export named '" + key;
712         if (!ecmaModule->GetEcmaModuleRecordNameString().empty()) {
713             msg += "' which exported by '" + ecmaModule->GetEcmaModuleRecordNameString() + "'";
714         } else {
715             msg += "' which exported by '" + ecmaModule->GetEcmaModuleFilenameString() + "'";
716         }
717         ObjectFactory *factory = vm->GetFactory();
718         JSTaggedValue error = factory->GetJSError(ErrorType::SYNTAX_ERROR, msg.c_str(),
719                                                   StackCheck::NO).GetTaggedValue();
720         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, 0);
721     }
722     JSHandle<TaggedArray> localExportEntries(thread, ecmaModule->GetLocalExportEntries());
723     size_t exportEntriesLen = localExportEntries->GetLength();
724     // 0: There's only one export value "default"
725     int index = 0;
726     JSMutableHandle<LocalExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
727     if (exportEntriesLen > 1) { // 1:  The number of export objects exceeds 1
728         for (size_t idx = 0; idx < exportEntriesLen; idx++) {
729             ee.Update(localExportEntries->Get(idx));
730             if (EcmaStringAccessor(ee->GetExportName()).Utf8ConvertToString() == key) {
731                 ASSERT(idx <= static_cast<size_t>(INT_MAX));
732                 index = static_cast<int>(ee->GetLocalIndex());
733                 break;
734             }
735         }
736     }
737     return index;
738 }
739 
HostResolveImportedModule(const JSPandaFile * jsPandaFile,const CString & filename)740 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const JSPandaFile *jsPandaFile,
741                                                                  const CString &filename)
742 {
743     if (jsPandaFile == nullptr) { // LCOV_EXCL_BR_LINE
744         LOG_FULL(FATAL) << "Load current file's panda file failed. Current file is " << filename;
745     }
746     JSThread *thread = vm_->GetJSThread();
747     auto entry = resolvedModules_.find(filename);
748     if (entry == resolvedModules_.end()) {
749         return ResolveModule(thread, jsPandaFile);
750     }
751     return JSHandle<JSTaggedValue>(thread, entry->second);
752 }
753 
LoadNativeModule(JSThread * thread,const CString & key)754 JSHandle<JSTaggedValue> ModuleManager::LoadNativeModule(JSThread *thread, const CString &key)
755 {
756     JSHandle<SourceTextModule> ecmaModule = JSHandle<SourceTextModule>::Cast(ExecuteNativeModule(thread, key));
757     ASSERT(ecmaModule->GetIsNewBcVersion());
758     int index = GetExportObjectIndex(vm_, ecmaModule, key);
759     JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
760     return JSHandle<JSTaggedValue>(thread, result);
761 }
762 
ExecuteNativeModuleMayThrowError(JSThread * thread,const CString & recordName)763 JSHandle<JSTaggedValue> ModuleManager::ExecuteNativeModuleMayThrowError(JSThread *thread, const CString &recordName)
764 {
765     JSMutableHandle<JSTaggedValue> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
766     if (IsEvaluatedModule(recordName)) {
767         JSHandle<SourceTextModule> moduleRecord = HostGetImportedModule(recordName);
768         return JSHandle<JSTaggedValue>(thread, moduleRecord->GetModuleValue(thread, 0, false));
769     }
770 
771     auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(recordName);
772     JSHandle<JSTaggedValue> moduleRecord = ModuleDataExtractor::ParseNativeModule(thread,
773         recordName, "", moduleType);
774     JSHandle<SourceTextModule> nativeModule =
775         JSHandle<SourceTextModule>::Cast(moduleRecord);
776     auto exportObject = SourceTextModule::LoadNativeModuleMayThrowError(thread, nativeModule, moduleType);
777     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread,
778         JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
779     nativeModule->SetStatus(ModuleStatus::EVALUATED);
780     nativeModule->SetLoadingTypes(LoadingTypes::STABLE_MODULE);
781     nativeModule->StoreModuleValue(thread, 0, JSNApiHelper::ToJSHandle(exportObject));
782     AddResolveImportedModule(recordName, moduleRecord.GetTaggedValue());
783     return JSNApiHelper::ToJSHandle(exportObject);
784 }
785 
ExecuteNativeModule(JSThread * thread,const CString & recordName)786 JSHandle<JSTaggedValue> ModuleManager::ExecuteNativeModule(JSThread *thread, const CString &recordName)
787 {
788     JSMutableHandle<JSTaggedValue> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
789     if (IsEvaluatedModule(recordName)) {
790         JSHandle<SourceTextModule> moduleRecord = HostGetImportedModule(recordName);
791         requiredModule.Update(moduleRecord);
792     } else if (IsLocalModuleLoaded(recordName)) {
793         JSHandle<SourceTextModule> nativeModule = HostGetImportedModule(recordName);
794         if (!SourceTextModule::LoadNativeModule(thread, nativeModule, nativeModule->GetTypes())) {
795             LOG_FULL(ERROR) << "loading native module " << recordName << " failed";
796         }
797         nativeModule->SetStatus(ModuleStatus::EVALUATED);
798         nativeModule->SetLoadingTypes(LoadingTypes::STABLE_MODULE);
799         requiredModule.Update(nativeModule);
800     } else {
801         auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(recordName);
802         JSHandle<JSTaggedValue> nativeModuleHandle =
803             ResolveNativeModule(recordName, "", moduleType);
804         JSHandle<SourceTextModule> nativeModule =
805             JSHandle<SourceTextModule>::Cast(nativeModuleHandle);
806         if (!SourceTextModule::LoadNativeModule(thread, nativeModule, moduleType)) {
807             LOG_FULL(ERROR) << "loading native module " << recordName << " failed";
808         }
809         nativeModule->SetStatus(ModuleStatus::EVALUATED);
810         nativeModule->SetLoadingTypes(LoadingTypes::STABLE_MODULE);
811         requiredModule.Update(nativeModule);
812     }
813     AddResolveImportedModule(recordName, requiredModule.GetTaggedValue());
814     return requiredModule;
815 }
816 
ExecuteJsonModule(JSThread * thread,const CString & recordName,const CString & filename,const JSPandaFile * jsPandaFile)817 JSHandle<JSTaggedValue> ModuleManager::ExecuteJsonModule(JSThread *thread, const CString &recordName,
818     const CString &filename, const JSPandaFile *jsPandaFile)
819 {
820     JSMutableHandle<JSTaggedValue> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
821     if (IsEvaluatedModule(recordName)) {
822         JSHandle<SourceTextModule> moduleRecord = HostGetImportedModule(recordName);
823         requiredModule.Update(moduleRecord);
824     } else {
825         JSHandle<SourceTextModule> moduleRecord =
826             JSHandle<SourceTextModule>::Cast(ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, filename,
827                                                                                   recordName));
828         moduleRecord->SetStatus(ModuleStatus::EVALUATED);
829         requiredModule.Update(moduleRecord);
830         UpdateResolveImportedModule(recordName, moduleRecord.GetTaggedValue());
831     }
832     return requiredModule;
833 }
834 
ExecuteCjsModule(JSThread * thread,const CString & recordName,const JSPandaFile * jsPandaFile)835 JSHandle<JSTaggedValue> ModuleManager::ExecuteCjsModule(JSThread *thread, const CString &recordName,
836     const JSPandaFile *jsPandaFile)
837 {
838     CString entryPoint = JSPandaFile::ENTRY_FUNCTION_NAME;
839     CString moduleRecord = jsPandaFile->GetJSPandaFileDesc();
840     if (!jsPandaFile->IsBundlePack()) {
841         entryPoint = recordName;
842         moduleRecord = recordName;
843     }
844 
845     JSMutableHandle<JSTaggedValue> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
846     if (IsEvaluatedModule(moduleRecord)) {
847         requiredModule.Update(HostGetImportedModule(moduleRecord));
848     } else {
849         JSHandle<SourceTextModule> module =
850             JSHandle<SourceTextModule>::Cast(ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile));
851         module->SetEcmaModuleRecordNameString(moduleRecord);
852         requiredModule.Update(module);
853         AddResolveImportedModule(recordName, module.GetTaggedValue());
854         JSPandaFileExecutor::Execute(thread, jsPandaFile, entryPoint);
855         RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, requiredModule);
856         module->SetStatus(ModuleStatus::EVALUATED);
857         UpdateResolveImportedModule(recordName, module.GetTaggedValue());
858     }
859     return requiredModule;
860 }
861 
GetModuleNameSpaceFromFile(JSThread * thread,const CString & recordName,const CString & baseFileName)862 JSHandle<JSTaggedValue> ModuleManager::GetModuleNameSpaceFromFile(
863     JSThread *thread, const CString &recordName, const CString &baseFileName)
864 {
865     // IsInstantiatedModule is for lazy module to execute
866     if (!IsLocalModuleLoaded(recordName) || IsLocalModuleInstantiated(recordName)) {
867         if (!ecmascript::JSPandaFileExecutor::ExecuteFromAbcFile(
868             thread, baseFileName, recordName, false, true)) {
869             LOG_ECMA(ERROR) << "LoadModuleNameSpaceFromFile:Cannot execute module: "<< baseFileName <<
870                 ", recordName: " << recordName;
871             return thread->GlobalConstants()->GetHandledUndefinedString();
872         }
873     }
874     JSHandle<ecmascript::SourceTextModule> moduleRecord = GetImportedModule(recordName);
875     moduleRecord->SetLoadingTypes(ecmascript::LoadingTypes::STABLE_MODULE);
876     return ecmascript::SourceTextModule::GetModuleNamespace(
877         thread, JSHandle<ecmascript::SourceTextModule>(moduleRecord));
878 }
879 
TryGetImportedModule(const CString & referencing)880 JSHandle<JSTaggedValue> ModuleManager::TryGetImportedModule(const CString& referencing)
881 {
882     JSThread *thread = vm_->GetJSThread();
883     auto entry = resolvedModules_.find(referencing);
884     if (entry == resolvedModules_.end()) {
885         return thread->GlobalConstants()->GetHandledUndefined();
886     }
887     return JSHandle<JSTaggedValue>(thread, entry->second);
888 }
889 
RemoveModuleFromCache(const CString & recordName)890 void ModuleManager::RemoveModuleFromCache(const CString& recordName)
891 {
892     auto entry = resolvedModules_.find(recordName);
893     if (entry == resolvedModules_.end()) { // LCOV_EXCL_BR_LINE
894         LOG_ECMA(FATAL) << "Can not get module: " << recordName <<
895             ", when try to remove the module";
896     }
897     JSTaggedValue result = entry->second;
898     SourceTextModule::Cast(result)->DestoryLazyImportArray();
899     SourceTextModule::Cast(result)->DestoryEcmaModuleFilenameString();
900     SourceTextModule::Cast(result)->DestoryEcmaModuleRecordNameString();
901     resolvedModules_.erase(recordName);
902 }
903 
904 // this function only remove module's name from resolvedModules List, it's content still needed by sharedmodule
RemoveModuleNameFromList(const CString & recordName)905 void ModuleManager::RemoveModuleNameFromList(const CString& recordName)
906 {
907     auto entry = resolvedModules_.find(recordName);
908     if (entry == resolvedModules_.end()) { // LCOV_EXCL_BR_LINE
909         LOG_ECMA(FATAL) << "Can not get module: " << recordName <<
910             ", when try to remove the module";
911     }
912     resolvedModules_.erase(recordName);
913 }
914 } // namespace panda::ecmascript
915