• 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/compiler/aot_file/aot_file_manager.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/interpreter/fast_runtime_stub-inl.h"
20 #include "ecmascript/interpreter/slow_runtime_stub.h"
21 #include "ecmascript/interpreter/frame_handler.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/jspandafile/js_pandafile.h"
24 #include "ecmascript/jspandafile/js_pandafile_executor.h"
25 #include "ecmascript/jspandafile/js_pandafile_manager.h"
26 #include "ecmascript/linked_hash_table.h"
27 #include "ecmascript/module/js_module_deregister.h"
28 #include "ecmascript/module/js_module_source_text.h"
29 #include "ecmascript/module/module_data_extractor.h"
30 #include "ecmascript/module/module_path_helper.h"
31 #include "ecmascript/require/js_cjs_module.h"
32 #include "ecmascript/tagged_dictionary.h"
33 #ifdef PANDA_TARGET_WINDOWS
34 #include <algorithm>
35 #endif
36 
37 namespace panda::ecmascript {
38 using StringHelper = base::StringHelper;
39 using JSPandaFile = ecmascript::JSPandaFile;
40 using JSRecordInfo = ecmascript::JSPandaFile::JSRecordInfo;
41 
ModuleManager(EcmaVM * vm)42 ModuleManager::ModuleManager(EcmaVM *vm) : vm_(vm)
43 {
44     resolvedModules_ = NameDictionary::Create(vm_->GetJSThread(), DEAULT_DICTIONART_CAPACITY).GetTaggedValue();
45 }
46 
GetCurrentModule()47 JSTaggedValue ModuleManager::GetCurrentModule()
48 {
49     FrameHandler frameHandler(vm_->GetJSThread());
50     Method *currentMethod = frameHandler.GetMethod();
51     return currentMethod->GetModule();
52 }
53 
GetModuleValueInner(int32_t index)54 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index)
55 {
56     JSTaggedValue currentModule = GetCurrentModule();
57     if (currentModule.IsUndefined()) {
58         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
59     }
60     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
61 }
62 
GetModuleValueInner(int32_t index,JSTaggedValue jsFunc)63 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index, JSTaggedValue jsFunc)
64 {
65     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
66     if (currentModule.IsUndefined()) {
67         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
68     }
69     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
70 }
71 
GetModuleValueInner(int32_t index,JSHandle<JSTaggedValue> currentModule)72 JSTaggedValue ModuleManager::GetModuleValueInner(int32_t index, JSHandle<JSTaggedValue> currentModule)
73 {
74     if (currentModule->IsUndefined()) {
75         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
76     }
77     return SourceTextModule::Cast(currentModule->GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), index, false);
78 }
79 
GetModuleValueOutter(int32_t index)80 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index)
81 {
82     JSTaggedValue currentModule = GetCurrentModule();
83     return GetModuleValueOutterInternal(index, currentModule);
84 }
85 
GetModuleValueOutter(int32_t index,JSTaggedValue jsFunc)86 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index, JSTaggedValue jsFunc)
87 {
88     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
89     return GetModuleValueOutterInternal(index, currentModule);
90 }
91 
GetModuleValueOutter(int32_t index,JSHandle<JSTaggedValue> currentModule)92 JSTaggedValue ModuleManager::GetModuleValueOutter(int32_t index, JSHandle<JSTaggedValue> currentModule)
93 {
94     return GetModuleValueOutterInternal(index, currentModule.GetTaggedValue());
95 }
96 
GetModuleValueOutterInternal(int32_t index,JSTaggedValue currentModule)97 JSTaggedValue ModuleManager::GetModuleValueOutterInternal(int32_t index, JSTaggedValue currentModule)
98 {
99     JSThread *thread = vm_->GetJSThread();
100     if (currentModule.IsUndefined()) {
101         LOG_FULL(FATAL) << "GetModuleValueOutter currentModule failed";
102         UNREACHABLE();
103     }
104     JSTaggedValue moduleEnvironment = SourceTextModule::Cast(currentModule.GetTaggedObject())->GetEnvironment();
105     if (moduleEnvironment.IsUndefined()) {
106         return thread->GlobalConstants()->GetUndefined();
107     }
108     ASSERT(moduleEnvironment.IsTaggedArray());
109     JSTaggedValue resolvedBinding = TaggedArray::Cast(moduleEnvironment.GetTaggedObject())->Get(index);
110     if (resolvedBinding.IsResolvedIndexBinding()) {
111         ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
112         JSTaggedValue resolvedModule = binding->GetModule();
113         ASSERT(resolvedModule.IsSourceTextModule());
114         SourceTextModule *module = SourceTextModule::Cast(resolvedModule.GetTaggedObject());
115 
116         // Support for only modifying var value of HotReload.
117         // Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
118         EcmaContext *context = thread->GetCurrentEcmaContext();
119         if (context->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) {
120             const JSHandle<JSTaggedValue> resolvedModuleOfHotReload =
121                 context->FindPatchModule(ConvertToString(module->GetEcmaModuleRecordName()));
122             if (!resolvedModuleOfHotReload->IsHole()) {
123                 resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
124             }
125         }
126 
127         ModuleTypes moduleType = module->GetTypes();
128         if (SourceTextModule::IsNativeModule(moduleType)) {
129             return GetNativeModuleValue(thread, currentModule, resolvedModule, binding);
130         }
131         if (moduleType == ModuleTypes::CJS_MODULE) {
132             return GetCJSModuleValue(thread, currentModule, resolvedModule, binding);
133         }
134         return SourceTextModule::Cast(
135             resolvedModule.GetTaggedObject())->GetModuleValue(thread, binding->GetIndex(), false);
136     }
137     ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
138     JSTaggedValue resolvedModule = binding->GetModule();
139     SourceTextModule *module = SourceTextModule::Cast(resolvedModule.GetTaggedObject());
140     if (SourceTextModule::IsNativeModule(module->GetTypes())) {
141         return GetNativeModuleValue(thread, currentModule, resolvedModule, binding);
142     }
143     if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
144         JSHandle<JSTaggedValue> cjsModuleName(thread, SourceTextModule::GetModuleName(JSTaggedValue(module)));
145         return CjsModule::SearchFromModuleCache(thread, cjsModuleName).GetTaggedValue();
146     }
147     LOG_ECMA(FATAL) << "Get module value failed, mistaken ResolvedBinding";
148     UNREACHABLE();
149 }
150 
GetNativeModuleValue(JSThread * thread,JSTaggedValue currentModule,JSTaggedValue resolvedModule,ResolvedBinding * binding)151 JSTaggedValue ModuleManager::GetNativeModuleValue(JSThread *thread, JSTaggedValue currentModule,
152     JSTaggedValue resolvedModule, ResolvedBinding *binding)
153 {
154     JSHandle<JSTaggedValue> nativeExports = JSHandle<JSTaggedValue>(thread,
155         SourceTextModule::Cast(resolvedModule.GetTaggedObject())->GetModuleValue(thread, 0, false));
156     if (!nativeExports->IsJSObject()) {
157         JSHandle<JSTaggedValue> nativeModuleName(thread, SourceTextModule::GetModuleName(resolvedModule));
158         JSHandle<JSTaggedValue> curModuleName(thread, SourceTextModule::Cast(
159             currentModule.GetTaggedObject())->GetEcmaModuleFilename());
160         LOG_FULL(WARN) << "GetNativeModuleValueByName: currentModule " +
161             ConvertToString(curModuleName.GetTaggedValue()) + ", find requireModule " +
162             ConvertToString(nativeModuleName.GetTaggedValue()) + " failed";
163         return nativeExports.GetTaggedValue();
164     }
165     if (UNLIKELY(JSTaggedValue::SameValue(binding->GetBindingName(),
166         thread->GlobalConstants()->GetHandledDefaultString().GetTaggedValue()))) {
167         return nativeExports.GetTaggedValue();
168     }
169     return JSHandle<JSTaggedValue>(thread, SlowRuntimeStub::LdObjByName(thread,
170                                                                         nativeExports.GetTaggedValue(),
171                                                                         binding->GetBindingName(),
172                                                                         false,
173                                                                         JSTaggedValue::Undefined())).GetTaggedValue();
174 }
175 
GetNativeModuleValue(JSThread * thread,JSTaggedValue currentModule,JSTaggedValue resolvedModule,ResolvedIndexBinding * binding)176 JSTaggedValue ModuleManager::GetNativeModuleValue(JSThread *thread, JSTaggedValue currentModule,
177     JSTaggedValue resolvedModule, ResolvedIndexBinding *binding)
178 {
179     JSHandle<JSTaggedValue> nativeExports = JSHandle<JSTaggedValue>(thread,
180         SourceTextModule::Cast(resolvedModule.GetTaggedObject())->GetModuleValue(thread, 0, false));
181     if (!nativeExports->IsJSObject()) {
182         JSHandle<JSTaggedValue> nativeModuleName(thread, SourceTextModule::GetModuleName(resolvedModule));
183         JSHandle<JSTaggedValue> curModuleName(thread, SourceTextModule::Cast(
184             currentModule.GetTaggedObject())->GetEcmaModuleFilename());
185         LOG_FULL(WARN) << "GetNativeModuleValueByIndex: currentModule " +
186             ConvertToString(curModuleName.GetTaggedValue()) + ", find requireModule " +
187             ConvertToString(nativeModuleName.GetTaggedValue()) + " failed";
188         return nativeExports.GetTaggedValue();
189     }
190     return GetValueFromExportObject(nativeExports, binding->GetIndex());
191 }
192 
GetCJSModuleValue(JSThread * thread,JSTaggedValue currentModule,JSTaggedValue resolvedModule,ResolvedIndexBinding * binding)193 JSTaggedValue ModuleManager::GetCJSModuleValue(JSThread *thread, JSTaggedValue currentModule,
194     JSTaggedValue resolvedModule, ResolvedIndexBinding *binding)
195 {
196     JSHandle<JSTaggedValue> cjsModuleName(thread, SourceTextModule::GetModuleName(resolvedModule));
197     JSHandle<JSTaggedValue> cjsExports = CjsModule::SearchFromModuleCache(thread, cjsModuleName);
198     // if cjsModule is not JSObject, means cjs uses default exports.
199     if (!cjsExports->IsJSObject()) {
200         if (cjsExports->IsHole()) {
201             ObjectFactory *factory = vm_->GetFactory();
202             JSHandle<JSTaggedValue> curModuleName(thread, SourceTextModule::Cast(
203                 currentModule.GetTaggedObject())->GetEcmaModuleFilename());
204             CString errorMsg = "GetCJSModuleValue: currentModule" + ConvertToString(curModuleName.GetTaggedValue()) +
205                                 "find requireModule" + ConvertToString(cjsModuleName.GetTaggedValue()) + "failed";
206             JSHandle<JSObject> syntaxError =
207                 factory->GetJSError(base::ErrorType::SYNTAX_ERROR, errorMsg.c_str());
208             THROW_NEW_ERROR_AND_RETURN_VALUE(thread, syntaxError.GetTaggedValue(), JSTaggedValue::Exception());
209         }
210         return cjsExports.GetTaggedValue();
211     }
212     return GetValueFromExportObject(cjsExports, binding->GetIndex());
213 }
214 
GetValueFromExportObject(JSHandle<JSTaggedValue> & exportObject,int32_t index)215 JSTaggedValue ModuleManager::GetValueFromExportObject(JSHandle<JSTaggedValue> &exportObject, int32_t index)
216 {
217     if (index == SourceTextModule::UNDEFINED_INDEX) {
218         return exportObject.GetTaggedValue();
219     }
220     JSTaggedValue value = JSTaggedValue::Hole();
221     JSObject *obj = JSObject::Cast(exportObject.GetTaggedValue());
222     TaggedArray *properties = TaggedArray::Cast(obj->GetProperties().GetTaggedObject());
223     if (!properties->IsDictionaryMode()) {
224         JSHClass *jsHclass = obj->GetJSHClass();
225         LayoutInfo *layoutInfo = LayoutInfo::Cast(jsHclass->GetLayout().GetTaggedObject());
226         PropertyAttributes attr = layoutInfo->GetAttr(index);
227         value = obj->GetProperty(jsHclass, attr);
228     } else {
229         NameDictionary *dict = NameDictionary::Cast(properties);
230         value = dict->GetValue(index);
231     }
232     if (UNLIKELY(value.IsAccessor())) {
233         return FastRuntimeStub::CallGetter(vm_->GetJSThread(), JSTaggedValue(obj), JSTaggedValue(obj), value);
234     }
235     ASSERT(!value.IsAccessor());
236     return value;
237 }
238 
StoreModuleValue(int32_t index,JSTaggedValue value)239 void ModuleManager::StoreModuleValue(int32_t index, JSTaggedValue value)
240 {
241     JSThread *thread = vm_->GetJSThread();
242     JSHandle<SourceTextModule> currentModule(thread, GetCurrentModule());
243     StoreModuleValueInternal(currentModule, index, value);
244 }
245 
StoreModuleValue(int32_t index,JSTaggedValue value,JSTaggedValue jsFunc)246 void ModuleManager::StoreModuleValue(int32_t index, JSTaggedValue value, JSTaggedValue jsFunc)
247 {
248     JSThread *thread = vm_->GetJSThread();
249     JSHandle<SourceTextModule> currentModule(thread, JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule());
250     StoreModuleValueInternal(currentModule, index, value);
251 }
252 
StoreModuleValueInternal(JSHandle<SourceTextModule> & currentModule,int32_t index,JSTaggedValue value)253 void ModuleManager::StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
254                                              int32_t index, JSTaggedValue value)
255 {
256     if (currentModule.GetTaggedValue().IsUndefined()) {
257         LOG_FULL(FATAL) << "StoreModuleValue currentModule failed";
258         UNREACHABLE();
259     }
260     JSThread *thread = vm_->GetJSThread();
261     JSHandle<JSTaggedValue> valueHandle(thread, value);
262     currentModule->StoreModuleValue(thread, index, valueHandle);
263 }
264 
GetModuleValueInner(JSTaggedValue key)265 JSTaggedValue ModuleManager::GetModuleValueInner(JSTaggedValue key)
266 {
267     JSTaggedValue currentModule = GetCurrentModule();
268     if (currentModule.IsUndefined()) {
269         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
270         UNREACHABLE();
271     }
272     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), key, false);
273 }
274 
GetModuleValueInner(JSTaggedValue key,JSTaggedValue jsFunc)275 JSTaggedValue ModuleManager::GetModuleValueInner(JSTaggedValue key, JSTaggedValue jsFunc)
276 {
277     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
278     if (currentModule.IsUndefined()) {
279         LOG_FULL(FATAL) << "GetModuleValueInner currentModule failed";
280         UNREACHABLE();
281     }
282     return SourceTextModule::Cast(currentModule.GetTaggedObject())->GetModuleValue(vm_->GetJSThread(), key, false);
283 }
284 
GetModuleValueOutter(JSTaggedValue key)285 JSTaggedValue ModuleManager::GetModuleValueOutter(JSTaggedValue key)
286 {
287     JSTaggedValue currentModule = GetCurrentModule();
288     return GetModuleValueOutterInternal(key, currentModule);
289 }
290 
GetModuleValueOutter(JSTaggedValue key,JSTaggedValue jsFunc)291 JSTaggedValue ModuleManager::GetModuleValueOutter(JSTaggedValue key, JSTaggedValue jsFunc)
292 {
293     JSTaggedValue currentModule = JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule();
294     return GetModuleValueOutterInternal(key, currentModule);
295 }
296 
GetModuleValueOutterInternal(JSTaggedValue key,JSTaggedValue currentModule)297 JSTaggedValue ModuleManager::GetModuleValueOutterInternal(JSTaggedValue key, JSTaggedValue currentModule)
298 {
299     JSThread *thread = vm_->GetJSThread();
300     if (currentModule.IsUndefined()) {
301         LOG_FULL(FATAL) << "GetModuleValueOutter currentModule failed";
302         UNREACHABLE();
303     }
304     JSTaggedValue moduleEnvironment = SourceTextModule::Cast(currentModule.GetTaggedObject())->GetEnvironment();
305     if (moduleEnvironment.IsUndefined()) {
306         return thread->GlobalConstants()->GetUndefined();
307     }
308     int entry = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->FindEntry(key);
309     if (entry == -1) {
310         return thread->GlobalConstants()->GetUndefined();
311     }
312     JSTaggedValue resolvedBinding = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->GetValue(entry);
313     ASSERT(resolvedBinding.IsResolvedBinding());
314     ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
315     JSTaggedValue resolvedModule = binding->GetModule();
316     ASSERT(resolvedModule.IsSourceTextModule());
317     SourceTextModule *module = SourceTextModule::Cast(resolvedModule.GetTaggedObject());
318     if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
319         JSHandle<JSTaggedValue> cjsModuleName(thread, SourceTextModule::GetModuleName(JSTaggedValue(module)));
320         return CjsModule::SearchFromModuleCache(thread, cjsModuleName).GetTaggedValue();
321     }
322     return module->GetModuleValue(thread, binding->GetBindingName(), false);
323 }
324 
StoreModuleValue(JSTaggedValue key,JSTaggedValue value)325 void ModuleManager::StoreModuleValue(JSTaggedValue key, JSTaggedValue value)
326 {
327     JSThread *thread = vm_->GetJSThread();
328     JSHandle<SourceTextModule> currentModule(thread, GetCurrentModule());
329     StoreModuleValueInternal(currentModule, key, value);
330 }
331 
StoreModuleValue(JSTaggedValue key,JSTaggedValue value,JSTaggedValue jsFunc)332 void ModuleManager::StoreModuleValue(JSTaggedValue key, JSTaggedValue value, JSTaggedValue jsFunc)
333 {
334     JSThread *thread = vm_->GetJSThread();
335     JSHandle<SourceTextModule> currentModule(thread, JSFunction::Cast(jsFunc.GetTaggedObject())->GetModule());
336     StoreModuleValueInternal(currentModule, key, value);
337 }
338 
StoreModuleValueInternal(JSHandle<SourceTextModule> & currentModule,JSTaggedValue key,JSTaggedValue value)339 void ModuleManager::StoreModuleValueInternal(JSHandle<SourceTextModule> &currentModule,
340                                              JSTaggedValue key, JSTaggedValue value)
341 {
342     if (currentModule.GetTaggedValue().IsUndefined()) {
343         LOG_FULL(FATAL) << "StoreModuleValue currentModule failed";
344         UNREACHABLE();
345     }
346     JSThread *thread = vm_->GetJSThread();
347     JSHandle<JSTaggedValue> keyHandle(thread, key);
348     JSHandle<JSTaggedValue> valueHandle(thread, value);
349     currentModule->StoreModuleValue(thread, keyHandle, valueHandle);
350 }
351 
HostGetImportedModule(const CString & referencingModule)352 JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(const CString &referencingModule)
353 {
354     ObjectFactory *factory = vm_->GetFactory();
355     JSHandle<EcmaString> referencingHandle = factory->NewFromUtf8(referencingModule);
356     return HostGetImportedModule(referencingHandle.GetTaggedValue());
357 }
358 
HostGetImportedModule(JSTaggedValue referencing)359 JSHandle<SourceTextModule> ModuleManager::HostGetImportedModule(JSTaggedValue referencing)
360 {
361     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
362     int entry = dict->FindEntry(referencing);
363     LOG_ECMA_IF(entry == -1, FATAL) << "Can not get module: "
364                                     << ConvertToString(referencing);
365     JSTaggedValue result = dict->GetValue(entry);
366     return JSHandle<SourceTextModule>(vm_->GetJSThread(), result);
367 }
368 
HostGetImportedModule(void * src)369 JSTaggedValue ModuleManager::HostGetImportedModule(void *src)
370 {
371     const char *str = reinterpret_cast<char *>(src);
372     const uint8_t *strData = reinterpret_cast<uint8_t *>(src);
373     LOG_FULL(INFO) << "current str during module deregister process : " << str;
374     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
375     int entry = dict->FindEntry(strData, strlen(str));
376     if (entry == -1) {
377         LOG_FULL(INFO) << "The module has been unloaded, " << str;
378         return JSTaggedValue::Undefined();
379     }
380     JSTaggedValue result = dict->GetValue(entry);
381     return result;
382 }
383 
IsImportedModuleLoaded(JSTaggedValue referencing)384 bool ModuleManager::IsImportedModuleLoaded(JSTaggedValue referencing)
385 {
386     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
387     int entry = dict->FindEntry(referencing);
388     if (entry == -1) {
389         return false;
390     }
391     JSTaggedValue result = dict->GetValue(entry).GetWeakRawValue();
392     dict->UpdateValue(vm_->GetJSThread(), entry, result);
393     return true;
394 }
395 
SkipDefaultBundleFile(const CString & moduleFileName) const396 bool ModuleManager::SkipDefaultBundleFile(const CString &moduleFileName) const
397 {
398     // relative file path like "../../xxxx" can't be loaded rightly in aot compilation phase
399     const char relativeFilePath[] = "..";
400     // just to skip misunderstanding error log in LoadJSPandaFile when we ignore Module Resolving Failure.
401     return !vm_->EnableReportModuleResolvingFailure() &&
402         (base::StringHelper::StringStartWith(moduleFileName, ModulePathHelper::BUNDLE_INSTALL_PATH) ||
403         base::StringHelper::StringStartWith(moduleFileName, relativeFilePath));
404 }
405 
ResolveModuleInMergedABC(JSThread * thread,const JSPandaFile * jsPandaFile,const CString & recordName,bool excuteFromJob)406 JSHandle<JSTaggedValue> ModuleManager::ResolveModuleInMergedABC(JSThread *thread, const JSPandaFile *jsPandaFile,
407     const CString &recordName, bool excuteFromJob)
408 {
409     // In static parse Phase, due to lack of some parameters, we will create a empty SourceTextModule which will
410     // be marked as INSTANTIATED to skip Dfs traversal of this import branch.
411     if (!vm_->EnableReportModuleResolvingFailure() && (jsPandaFile == nullptr ||
412         (jsPandaFile != nullptr && !jsPandaFile->HasRecord(recordName)))) {
413         return CreateEmptyModule();
414     } else {
415         return ResolveModuleWithMerge(thread, jsPandaFile, recordName, excuteFromJob);
416     }
417 }
418 
HostResolveImportedModuleWithMerge(const CString & moduleFileName,const CString & recordName,bool excuteFromJob)419 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModuleWithMerge(const CString &moduleFileName,
420     const CString &recordName, bool excuteFromJob)
421 {
422     JSHandle<EcmaString> recordNameHandle = vm_->GetFactory()->NewFromUtf8(recordName);
423     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
424     int entry = dict->FindEntry(recordNameHandle.GetTaggedValue());
425     if (entry != -1) {
426         return JSHandle<JSTaggedValue>(vm_->GetJSThread(), dict->GetValue(entry));
427     }
428     return CommonResolveImportedModuleWithMerge(moduleFileName, recordName, excuteFromJob);
429 }
430 
HostResolveImportedModuleWithMergeForHotReload(const CString & moduleFileName,const CString & recordName,bool excuteFromJob)431 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModuleWithMergeForHotReload(const CString &moduleFileName,
432     const CString &recordName, bool excuteFromJob)
433 {
434     return CommonResolveImportedModuleWithMerge(moduleFileName, recordName, excuteFromJob);
435 }
436 
CommonResolveImportedModuleWithMerge(const CString & moduleFileName,const CString & recordName,bool excuteFromJob)437 JSHandle<JSTaggedValue> ModuleManager::CommonResolveImportedModuleWithMerge(const CString &moduleFileName,
438     const CString &recordName, bool excuteFromJob)
439 {
440     JSThread *thread = vm_->GetJSThread();
441 
442     std::shared_ptr<JSPandaFile> jsPandaFile = SkipDefaultBundleFile(moduleFileName) ? nullptr :
443         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, recordName, false);
444     if (jsPandaFile == nullptr) {
445         // In Aot Module Instantiate, we miss some runtime parameters from framework like bundleName or moduleName
446         // which may cause wrong recordName parsing and we also can't load files not in this app hap. But in static
447         // phase, these should not be an error, just skip it is ok.
448         if (vm_->EnableReportModuleResolvingFailure()) {
449             CString msg = "Load file with filename '" + moduleFileName + "' failed, recordName '" + recordName + "'";
450             THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
451         }
452     }
453     JSHandle<JSTaggedValue> moduleRecord = ResolveModuleInMergedABC(thread,
454         jsPandaFile.get(), recordName, excuteFromJob);
455     RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
456     JSHandle<NameDictionary> handleDict(thread, resolvedModules_);
457     JSHandle<EcmaString> recordNameHandle= vm_->GetFactory()->NewFromUtf8(recordName);
458     resolvedModules_ = NameDictionary::Put(thread, handleDict, JSHandle<JSTaggedValue>(recordNameHandle),
459         moduleRecord, PropertyAttributes::Default()).GetTaggedValue();
460 
461     return moduleRecord;
462 }
463 
CreateEmptyModule()464 JSHandle<JSTaggedValue> ModuleManager::CreateEmptyModule()
465 {
466     if (!cachedEmptyModule_.IsHole()) {
467         return JSHandle<JSTaggedValue>(vm_->GetJSThread(), cachedEmptyModule_);
468     }
469     ObjectFactory *factory = vm_->GetFactory();
470     JSHandle<SourceTextModule> tmpModuleRecord = factory->NewSourceTextModule();
471     tmpModuleRecord->SetStatus(ModuleStatus::INSTANTIATED);
472     tmpModuleRecord->SetTypes(ModuleTypes::ECMA_MODULE);
473     tmpModuleRecord->SetIsNewBcVersion(true);
474     cachedEmptyModule_ = tmpModuleRecord.GetTaggedValue();
475     return JSHandle<JSTaggedValue>::Cast(tmpModuleRecord);
476 }
477 
HostResolveImportedModule(const CString & referencingModule,bool excuteFromJob)478 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const CString &referencingModule, bool excuteFromJob)
479 {
480     JSThread *thread = vm_->GetJSThread();
481     ObjectFactory *factory = vm_->GetFactory();
482 
483     JSHandle<EcmaString> referencingHandle = factory->NewFromUtf8(referencingModule);
484     CString moduleFileName = referencingModule;
485     if (vm_->IsBundlePack()) {
486         if (AOTFileManager::GetAbsolutePath(referencingModule, moduleFileName)) {
487             referencingHandle = factory->NewFromUtf8(moduleFileName);
488         } else {
489             CString msg = "Parse absolute " + referencingModule + " path failed";
490             THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
491         }
492     }
493 
494     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
495     int entry = dict->FindEntry(referencingHandle.GetTaggedValue());
496     if (entry != -1) {
497         return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
498     }
499 
500     std::shared_ptr<JSPandaFile> jsPandaFile =
501         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, moduleFileName, JSPandaFile::ENTRY_MAIN_FUNCTION);
502     if (jsPandaFile == nullptr) {
503         CString msg = "Load file with filename '" + moduleFileName + "' failed";
504         THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
505     }
506 
507     return ResolveModule(thread, jsPandaFile.get(), excuteFromJob);
508 }
509 
510 // The security interface needs to be modified accordingly.
HostResolveImportedModule(const void * buffer,size_t size,const CString & filename)511 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const void *buffer, size_t size,
512                                                                  const CString &filename)
513 {
514     JSThread *thread = vm_->GetJSThread();
515     ObjectFactory *factory = vm_->GetFactory();
516 
517     JSHandle<EcmaString> referencingHandle = factory->NewFromUtf8(filename);
518     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
519     int entry = dict->FindEntry(referencingHandle.GetTaggedValue());
520     if (entry != -1) {
521         return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
522     }
523 
524     std::shared_ptr<JSPandaFile> jsPandaFile =
525         JSPandaFileManager::GetInstance()->LoadJSPandaFile(thread, filename,
526                                                            JSPandaFile::ENTRY_MAIN_FUNCTION, buffer, size);
527     if (jsPandaFile == nullptr) {
528         CString msg = "Load file with filename '" + filename + "' failed";
529         THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
530     }
531 
532     return ResolveModule(thread, jsPandaFile.get());
533 }
534 
ResolveModule(JSThread * thread,const JSPandaFile * jsPandaFile,bool excuteFromJob)535 JSHandle<JSTaggedValue> ModuleManager::ResolveModule(JSThread *thread, const JSPandaFile *jsPandaFile,
536     bool excuteFromJob)
537 {
538     ObjectFactory *factory = vm_->GetFactory();
539     CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
540     JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
541     JSRecordInfo recordInfo = const_cast<JSPandaFile *>(jsPandaFile)->FindRecordInfo(JSPandaFile::ENTRY_FUNCTION_NAME);
542     if (jsPandaFile->IsModule(recordInfo)) {
543         moduleRecord = ModuleDataExtractor::ParseModule(thread, jsPandaFile, moduleFileName, moduleFileName);
544     } else if (jsPandaFile->IsJson(recordInfo)) {
545         moduleRecord = ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, moduleFileName);
546     } else {
547         ASSERT(jsPandaFile->IsCjs(recordInfo));
548         moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
549     }
550     ModuleDeregister::InitForDeregisterModule(thread, moduleRecord, excuteFromJob);
551     JSHandle<NameDictionary> dict(thread, resolvedModules_);
552     JSHandle<JSTaggedValue> referencingHandle = JSHandle<JSTaggedValue>::Cast(factory->NewFromUtf8(moduleFileName));
553     resolvedModules_ =
554         NameDictionary::Put(thread, dict, referencingHandle, moduleRecord, PropertyAttributes::Default())
555         .GetTaggedValue();
556     return moduleRecord;
557 }
558 
ResolveNativeModule(const CString & moduleRequestName,ModuleTypes moduleType)559 JSHandle<JSTaggedValue> ModuleManager::ResolveNativeModule(const CString &moduleRequestName, ModuleTypes moduleType)
560 {
561     ObjectFactory *factory = vm_->GetFactory();
562     JSThread *thread = vm_->GetJSThread();
563 
564     JSHandle<JSTaggedValue> referencingModule(factory->NewFromUtf8(moduleRequestName));
565     JSHandle<JSTaggedValue> moduleRecord = ModuleDataExtractor::ParseNativeModule(thread,
566         moduleRequestName, moduleType);
567     JSHandle<NameDictionary> dict(thread, resolvedModules_);
568     resolvedModules_ = NameDictionary::Put(thread, dict, referencingModule, moduleRecord,
569         PropertyAttributes::Default()).GetTaggedValue();
570     return moduleRecord;
571 }
572 
ResolveModuleWithMerge(JSThread * thread,const JSPandaFile * jsPandaFile,const CString & recordName,bool excuteFromJob)573 JSHandle<JSTaggedValue> ModuleManager::ResolveModuleWithMerge(
574     JSThread *thread, const JSPandaFile *jsPandaFile, const CString &recordName, bool excuteFromJob)
575 {
576     ObjectFactory *factory = vm_->GetFactory();
577     CString moduleFileName = jsPandaFile->GetJSPandaFileDesc();
578     JSHandle<JSTaggedValue> moduleRecord = thread->GlobalConstants()->GetHandledUndefined();
579     JSRecordInfo recordInfo;
580     bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(recordName, recordInfo);
581     if (!hasRecord) {
582         CString msg = "cannot find record '" + recordName + "', please check the request path.'"
583                       + moduleFileName + "'.";
584         LOG_FULL(ERROR) << msg;
585         THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
586     }
587     if (jsPandaFile->IsModule(recordInfo)) {
588         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
589         moduleRecord = ModuleDataExtractor::ParseModule(thread, jsPandaFile, recordName, moduleFileName);
590     } else if (jsPandaFile->IsJson(recordInfo)) {
591         moduleRecord = ModuleDataExtractor::ParseJsonModule(thread, jsPandaFile, moduleFileName, recordName);
592     } else {
593         ASSERT(jsPandaFile->IsCjs(recordInfo));
594         RETURN_HANDLE_IF_ABRUPT_COMPLETION(JSTaggedValue, thread);
595         moduleRecord = ModuleDataExtractor::ParseCjsModule(thread, jsPandaFile);
596     }
597 
598     JSHandle<JSTaggedValue> recordNameHandle = JSHandle<JSTaggedValue>::Cast(factory->NewFromUtf8(recordName));
599     JSHandle<SourceTextModule>::Cast(moduleRecord)->SetEcmaModuleRecordName(thread, recordNameHandle);
600     ModuleDeregister::InitForDeregisterModule(thread, moduleRecord, excuteFromJob);
601     return moduleRecord;
602 }
603 
AddResolveImportedModule(const JSPandaFile * jsPandaFile,const CString & referencingModule)604 void ModuleManager::AddResolveImportedModule(const JSPandaFile *jsPandaFile, const CString &referencingModule)
605 {
606     JSThread *thread = vm_->GetJSThread();
607     JSHandle<JSTaggedValue> moduleRecord =
608         ModuleDataExtractor::ParseModule(thread, jsPandaFile, referencingModule, referencingModule);
609     AddResolveImportedModule(referencingModule, moduleRecord);
610 }
611 
AddResolveImportedModule(const CString & referencingModule,JSHandle<JSTaggedValue> moduleRecord)612 void ModuleManager::AddResolveImportedModule(const CString &referencingModule, JSHandle<JSTaggedValue> moduleRecord)
613 {
614     JSThread *thread = vm_->GetJSThread();
615     ObjectFactory *factory = vm_->GetFactory();
616     JSHandle<JSTaggedValue> referencingHandle(factory->NewFromUtf8(referencingModule));
617     JSHandle<NameDictionary> dict(thread, resolvedModules_);
618     resolvedModules_ =
619         NameDictionary::Put(thread, dict, referencingHandle, moduleRecord, PropertyAttributes::Default())
620         .GetTaggedValue();
621 }
622 
GetModuleNamespace(int32_t index)623 JSTaggedValue ModuleManager::GetModuleNamespace(int32_t index)
624 {
625     JSTaggedValue currentModule = GetCurrentModule();
626     return GetModuleNamespaceInternal(index, currentModule);
627 }
628 
GetModuleNamespace(int32_t index,JSTaggedValue currentFunc)629 JSTaggedValue ModuleManager::GetModuleNamespace(int32_t index, JSTaggedValue currentFunc)
630 {
631     JSTaggedValue currentModule = JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule();
632     return GetModuleNamespaceInternal(index, currentModule);
633 }
634 
GetModuleNamespaceInternal(int32_t index,JSTaggedValue currentModule)635 JSTaggedValue ModuleManager::GetModuleNamespaceInternal(int32_t index, JSTaggedValue currentModule)
636 {
637     if (currentModule.IsUndefined()) {
638         LOG_FULL(FATAL) << "GetModuleNamespace currentModule failed";
639         UNREACHABLE();
640     }
641     JSThread *thread = vm_->GetJSThread();
642     SourceTextModule *module = SourceTextModule::Cast(currentModule.GetTaggedObject());
643     JSTaggedValue requestedModule = module->GetRequestedModules();
644     JSTaggedValue moduleName = TaggedArray::Cast(requestedModule.GetTaggedObject())->Get(index);
645     JSTaggedValue moduleRecordName = module->GetEcmaModuleRecordName();
646     JSHandle<JSTaggedValue> requiredModule;
647     if (moduleRecordName.IsUndefined()) {
648         requiredModule = SourceTextModule::HostResolveImportedModule(thread,
649             JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
650     } else {
651         ASSERT(moduleRecordName.IsString());
652         requiredModule = SourceTextModule::HostResolveImportedModuleWithMerge(thread,
653             JSHandle<SourceTextModule>(thread, module), JSHandle<JSTaggedValue>(thread, moduleName));
654     }
655     RETURN_VALUE_IF_ABRUPT_COMPLETION(thread, JSTaggedValue::Exception());
656     JSHandle<SourceTextModule> requiredModuleST = JSHandle<SourceTextModule>::Cast(requiredModule);
657     ModuleTypes moduleType = requiredModuleST->GetTypes();
658     // if requiredModuleST is Native module
659     if (SourceTextModule::IsNativeModule(moduleType)) {
660         return SourceTextModule::Cast(requiredModuleST.GetTaggedValue())->GetModuleValue(thread, 0, false);
661     }
662     // if requiredModuleST is CommonJS
663     if (moduleType == ModuleTypes::CJS_MODULE) {
664         JSHandle<JSTaggedValue> cjsModuleName(thread,
665             SourceTextModule::GetModuleName(requiredModuleST.GetTaggedValue()));
666         return CjsModule::SearchFromModuleCache(thread, cjsModuleName).GetTaggedValue();
667     }
668     // if requiredModuleST is ESM
669     JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModuleST);
670     ASSERT(moduleNamespace->IsModuleNamespace());
671     return moduleNamespace.GetTaggedValue();
672 }
673 
GetModuleNamespace(JSTaggedValue localName)674 JSTaggedValue ModuleManager::GetModuleNamespace(JSTaggedValue localName)
675 {
676     JSTaggedValue currentModule = GetCurrentModule();
677     return GetModuleNamespaceInternal(localName, currentModule);
678 }
679 
GetModuleNamespace(JSTaggedValue localName,JSTaggedValue currentFunc)680 JSTaggedValue ModuleManager::GetModuleNamespace(JSTaggedValue localName, JSTaggedValue currentFunc)
681 {
682     JSTaggedValue currentModule = JSFunction::Cast(currentFunc.GetTaggedObject())->GetModule();
683     return GetModuleNamespaceInternal(localName, currentModule);
684 }
685 
GetModuleNamespaceInternal(JSTaggedValue localName,JSTaggedValue currentModule)686 JSTaggedValue ModuleManager::GetModuleNamespaceInternal(JSTaggedValue localName, JSTaggedValue currentModule)
687 {
688     if (currentModule.IsUndefined()) {
689         LOG_FULL(FATAL) << "GetModuleNamespace currentModule failed";
690         UNREACHABLE();
691     }
692     JSTaggedValue moduleEnvironment = SourceTextModule::Cast(currentModule.GetTaggedObject())->GetEnvironment();
693     if (moduleEnvironment.IsUndefined()) {
694         return vm_->GetJSThread()->GlobalConstants()->GetUndefined();
695     }
696     int entry = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->FindEntry(localName);
697     if (entry == -1) {
698         return vm_->GetJSThread()->GlobalConstants()->GetUndefined();
699     }
700     JSTaggedValue moduleNamespace = NameDictionary::Cast(moduleEnvironment.GetTaggedObject())->GetValue(entry);
701     ASSERT(moduleNamespace.IsModuleNamespace());
702     return moduleNamespace;
703 }
704 
Iterate(const RootVisitor & v)705 void ModuleManager::Iterate(const RootVisitor &v)
706 {
707     v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&resolvedModules_)));
708     v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&cachedEmptyModule_)));
709 }
710 
GetRecordName(JSTaggedValue module)711 CString ModuleManager::GetRecordName(JSTaggedValue module)
712 {
713     CString entry = "";
714     if (module.IsString()) {
715         entry = ConvertToString(module);
716     }
717     if (module.IsSourceTextModule()) {
718         SourceTextModule *sourceTextModule = SourceTextModule::Cast(module.GetTaggedObject());
719         if (sourceTextModule->GetEcmaModuleRecordName().IsString()) {
720             entry = ConvertToString(sourceTextModule->GetEcmaModuleRecordName());
721         }
722     }
723     return entry;
724 }
725 
GetExportObjectIndex(EcmaVM * vm,JSHandle<SourceTextModule> ecmaModule,const std::string & key)726 int ModuleManager::GetExportObjectIndex(EcmaVM *vm, JSHandle<SourceTextModule> ecmaModule,
727                                         const std::string &key)
728 {
729     JSThread *thread = vm->GetJSThread();
730     if (ecmaModule->GetLocalExportEntries().IsUndefined()) {
731         CString msg = "No export named '" + ConvertToString(key);
732         if (!ecmaModule->GetEcmaModuleRecordName().IsUndefined()) {
733             msg += "' which exported by '" + ConvertToString(ecmaModule->GetEcmaModuleRecordName()) + "'";
734         } else {
735             msg += "' which exported by '" + ConvertToString(ecmaModule->GetEcmaModuleFilename()) + "'";
736         }
737         ObjectFactory *factory = vm->GetFactory();
738         JSTaggedValue error = factory->GetJSError(ErrorType::SYNTAX_ERROR, msg.c_str()).GetTaggedValue();
739         THROW_NEW_ERROR_AND_RETURN_VALUE(thread, error, 0);
740     }
741     JSHandle<TaggedArray> localExportEntries(thread, ecmaModule->GetLocalExportEntries());
742     size_t exportEntriesLen = localExportEntries->GetLength();
743     // 0: There's only one export value "default"
744     int index = 0;
745     JSMutableHandle<LocalExportEntry> ee(thread, thread->GlobalConstants()->GetUndefined());
746     if (exportEntriesLen > 1) { // 1:  The number of export objects exceeds 1
747         for (size_t idx = 0; idx < exportEntriesLen; idx++) {
748             ee.Update(localExportEntries->Get(idx));
749             if (EcmaStringAccessor(ee->GetExportName()).ToStdString() == key) {
750                 ASSERT(idx <= static_cast<size_t>(INT_MAX));
751                 index = static_cast<int>(ee->GetLocalIndex());
752                 break;
753             }
754         }
755     }
756     return index;
757 }
758 
HostResolveImportedModule(const JSPandaFile * jsPandaFile,const CString & filename)759 JSHandle<JSTaggedValue> ModuleManager::HostResolveImportedModule(const JSPandaFile *jsPandaFile,
760                                                                  const CString &filename)
761 {
762     JSThread *thread = vm_->GetJSThread();
763     JSHandle<EcmaString> referencingHandle = vm_->GetFactory()->NewFromUtf8(filename);
764     NameDictionary *dict = NameDictionary::Cast(resolvedModules_.GetTaggedObject());
765     int entry = dict->FindEntry(referencingHandle.GetTaggedValue());
766     if (entry != -1) {
767         return JSHandle<JSTaggedValue>(thread, dict->GetValue(entry));
768     }
769 
770     if (jsPandaFile == nullptr) {
771         CString msg = "Faild to resolve file '" + filename + "', please check the request path.";
772         THROW_NEW_ERROR_AND_RETURN_HANDLE(thread, ErrorType::REFERENCE_ERROR, JSTaggedValue, msg.c_str());
773     }
774     return ResolveModule(thread, jsPandaFile);
775 }
776 
LoadNativeModule(JSThread * thread,const std::string & key)777 JSHandle<JSTaggedValue> ModuleManager::LoadNativeModule(JSThread *thread, const std::string &key)
778 {
779     ObjectFactory *factory = vm_->GetFactory();
780     JSHandle<EcmaString> keyHandle = factory->NewFromASCII(key.c_str());
781     JSMutableHandle<JSTaggedValue> requiredModule(thread, thread->GlobalConstants()->GetUndefined());
782     if (IsImportedModuleLoaded(keyHandle.GetTaggedValue())) {
783         JSHandle<SourceTextModule> moduleRecord = HostGetImportedModule(keyHandle.GetTaggedValue());
784         requiredModule.Update(moduleRecord);
785     } else {
786         CString requestPath = ConvertToString(keyHandle.GetTaggedValue());
787         CString entryPoint = PathHelper::GetStrippedModuleName(requestPath);
788         auto [isNative, moduleType] = SourceTextModule::CheckNativeModule(requestPath);
789         JSHandle<JSTaggedValue> nativeModuleHandle = ResolveNativeModule(requestPath, moduleType);
790         JSHandle<SourceTextModule> nativeModule =
791             JSHandle<SourceTextModule>::Cast(nativeModuleHandle);
792         if (!SourceTextModule::LoadNativeModule(thread, nativeModule, moduleType)) {
793             LOG_FULL(ERROR) << "loading native module " << requestPath << " failed";
794         }
795         nativeModule->SetStatus(ModuleStatus::EVALUATED);
796         nativeModule->SetLoadingTypes(LoadingTypes::STABLE_MODULE);
797         requiredModule.Update(nativeModule);
798     }
799 
800     JSHandle<SourceTextModule> ecmaModule = JSHandle<SourceTextModule>::Cast(requiredModule);
801     if (ecmaModule->GetIsNewBcVersion()) {
802         int index = GetExportObjectIndex(vm_, ecmaModule, key);
803         JSTaggedValue result = ecmaModule->GetModuleValue(thread, index, false);
804         return JSHandle<JSTaggedValue>(thread, result);
805     }
806 
807     JSTaggedValue result = ecmaModule->GetModuleValue(thread, keyHandle.GetTaggedValue(), false);
808     return JSHandle<JSTaggedValue>(thread, result);
809 }
810 } // namespace panda::ecmascript
811