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> ¤tModule,
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> ¤tModule,
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