1 /*
2 * Copyright (c) 2024 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
16 #include "ecmascript/module/module_tools.h"
17
18 #include "ecmascript/ecma_context.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/module/js_shared_module.h"
21 #include "ecmascript/module/module_logger.h"
22 #include "ecmascript/module/module_manager_helper.h"
23 #include "ecmascript/require/js_cjs_module.h"
24
25
26 namespace panda::ecmascript {
27
GetModuleValueFromIndexBindingForLog(JSThread * thread,JSHandle<SourceTextModule> module,JSTaggedValue resolvedBinding,int32_t index)28 JSTaggedValue ModuleTools::GetModuleValueFromIndexBindingForLog(
29 JSThread *thread, JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index)
30 {
31 JSHandle<ResolvedRecordIndexBinding> binding(thread, resolvedBinding);
32 JSHandle<SourceTextModule> resolvedModule =
33 ModuleManagerHelper::GetResolvedRecordIndexBindingModule(thread, module, binding);
34 ModuleLogger *moduleLogger =
35 thread->GetCurrentEcmaContext()->GetModuleLogger();
36 moduleLogger->InsertModuleLoadInfo(module, resolvedModule, index);
37 return ModuleManagerHelper::GetModuleValue(thread, resolvedModule, binding->GetIndex());
38 }
39
40 // use for moduleLogger is not nullptr
GetModuleValueFromRecordBindingForLog(JSThread * thread,JSHandle<SourceTextModule> module,JSTaggedValue resolvedBinding,int32_t index)41 JSTaggedValue ModuleTools::GetModuleValueFromRecordBindingForLog(
42 JSThread *thread, JSHandle<SourceTextModule> module, JSTaggedValue resolvedBinding, int32_t index)
43 {
44 JSHandle<ResolvedRecordBinding> binding(thread, resolvedBinding);
45 JSHandle<SourceTextModule> resolvedModule =
46 ModuleManagerHelper::GetResolvedRecordBindingModule(thread, module, binding);
47 ModuleLogger *moduleLogger =
48 thread->GetCurrentEcmaContext()->GetModuleLogger();
49 moduleLogger->InsertModuleLoadInfo(module, resolvedModule, index);
50 return ModuleManagerHelper::GetModuleValue(thread, resolvedModule, binding->GetBindingName());
51 }
52
53 // use for moduleLogger is not nullptr
ProcessModuleLoadInfo(JSThread * thread,JSHandle<SourceTextModule> currentModule,JSTaggedValue resolvedBinding,int32_t index)54 JSTaggedValue ModuleTools::ProcessModuleLoadInfo(JSThread *thread, JSHandle<SourceTextModule> currentModule,
55 JSTaggedValue resolvedBinding, int32_t index)
56 {
57 ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
58 JSMutableHandle<JSTaggedValue> res(thread, thread->GlobalConstants()->GetUndefined());
59 if (resolvedBinding.IsResolvedIndexBinding()) {
60 ResolvedIndexBinding *binding = ResolvedIndexBinding::Cast(resolvedBinding.GetTaggedObject());
61 JSTaggedValue resolvedModule = binding->GetModule();
62 JSHandle<SourceTextModule> module(thread, resolvedModule);
63 ASSERT(resolvedModule.IsSourceTextModule());
64
65 // Support for only modifying var value of HotReload.
66 // Cause patchFile exclude the record of importing modifying var. Can't reresolve moduleRecord.
67 EcmaContext *context = thread->GetCurrentEcmaContext();
68 if (context->GetStageOfHotReload() == StageOfHotReload::LOAD_END_EXECUTE_PATCHMAIN) {
69 const JSHandle<JSTaggedValue> resolvedModuleOfHotReload =
70 context->FindPatchModule(module->GetEcmaModuleRecordNameString());
71 if (!resolvedModuleOfHotReload->IsHole()) {
72 resolvedModule = resolvedModuleOfHotReload.GetTaggedValue();
73 JSHandle<SourceTextModule> moduleOfHotReload(thread, resolvedModule);
74 moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
75 return ModuleManagerHelper::GetModuleValue(thread, moduleOfHotReload, binding->GetIndex());
76 }
77 }
78 moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
79 return ModuleManagerHelper::GetModuleValue(thread, module, binding->GetIndex());
80 }
81 if (resolvedBinding.IsResolvedBinding()) {
82 ResolvedBinding *binding = ResolvedBinding::Cast(resolvedBinding.GetTaggedObject());
83 JSTaggedValue resolvedModule = binding->GetModule();
84 JSHandle<SourceTextModule> module(thread, resolvedModule);
85 if (SourceTextModule::IsNativeModule(module->GetTypes())) {
86 moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
87 return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
88 thread, currentModule, module, index, binding->GetBindingName());
89 }
90 if (module->GetTypes() == ModuleTypes::CJS_MODULE) {
91 moduleLogger->InsertModuleLoadInfo(currentModule, module, index);
92 return ModuleManagerHelper::UpdateBindingAndGetModuleValue(
93 thread, currentModule, module, index, binding->GetBindingName());
94 }
95 }
96 if (resolvedBinding.IsResolvedRecordIndexBinding()) {
97 return GetModuleValueFromIndexBindingForLog(thread, currentModule, resolvedBinding, index);
98 }
99 if (resolvedBinding.IsResolvedRecordBinding()) {
100 return GetModuleValueFromRecordBindingForLog(thread, currentModule, resolvedBinding, index);
101 }
102 LOG_ECMA(FATAL) << "Get module value failed, mistaken ResolvedBinding";
103 UNREACHABLE();
104 }
105
ProcessModuleNameSpaceLoadInfo(JSThread * thread,JSHandle<SourceTextModule> currentModule,JSHandle<SourceTextModule> requiredModule)106 JSTaggedValue ModuleTools::ProcessModuleNameSpaceLoadInfo(
107 JSThread *thread, JSHandle<SourceTextModule> currentModule, JSHandle<SourceTextModule> requiredModule)
108 {
109 ModuleTypes moduleType = requiredModule->GetTypes();
110 ModuleLogger *moduleLogger = thread->GetCurrentEcmaContext()->GetModuleLogger();
111 // if requiredModule is Native module
112 if (SourceTextModule::IsNativeModule(moduleType)) {
113 moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
114 return SourceTextModule::Cast(requiredModule.GetTaggedValue())->GetModuleValue(thread, 0, false);
115 }
116 // if requiredModule is CommonJS
117 if (moduleType == ModuleTypes::CJS_MODULE) {
118 moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
119 CString cjsModuleName = SourceTextModule::GetModuleName(requiredModule.GetTaggedValue());
120 JSHandle<JSTaggedValue> moduleNameHandle(thread->GetEcmaVM()->GetFactory()->NewFromUtf8(cjsModuleName));
121 return CjsModule::SearchFromModuleCache(thread, moduleNameHandle).GetTaggedValue();
122 }
123 // if requiredModule is ESM
124 moduleLogger->InsertModuleLoadInfo(currentModule, requiredModule, -1);
125 JSHandle<JSTaggedValue> moduleNamespace = SourceTextModule::GetModuleNamespace(thread, requiredModule);
126 ASSERT(moduleNamespace->IsModuleNamespace());
127 return moduleNamespace.GetTaggedValue();
128 }
129 } // namespace panda::ecmascript
130