• 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 
16 #ifndef ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H
17 #define ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H
18 
19 #include "ecmascript/base/string_helper.h"
20 #include "ecmascript/mem/c_containers.h"
21 #include "ecmascript/module/js_module_record.h"
22 #include "ecmascript/module/js_module_entry.h"
23 #include "ecmascript/tagged_array.h"
24 
25 namespace panda::ecmascript {
26 enum class ModuleStatus : uint8_t { UNINSTANTIATED = 0x01, INSTANTIATING, INSTANTIATED, EVALUATING, EVALUATED };
27 
28 enum class ModuleTypes : uint8_t {
29     ECMA_MODULE = 0x01,
30     CJS_MODULE,
31     JSON_MODULE,
32     NATIVE_MODULE,
33     OHOS_MODULE,
34     APP_MODULE,
35     INTERNAL_MODULE,
36     UNKNOWN
37 };
38 
39 enum class LoadingTypes : uint8_t {
40     STABLE_MODULE = 0x01,
41     DYNAMITC_MODULE,
42     OTHERS
43 };
44 
45 class SourceTextModule final : public ModuleRecord {
46 public:
47     static constexpr int UNDEFINED_INDEX = -1;
48     static constexpr size_t DEFAULT_DICTIONART_CAPACITY = 2;
49     static constexpr size_t DEFAULT_ARRAY_CAPACITY = 2;
50     static constexpr uint8_t DEREGISTER_MODULE_TAG = 1;
51 
52     CAST_CHECK(SourceTextModule, IsSourceTextModule);
53 
54     // 15.2.1.17 Runtime Semantics: HostResolveImportedModule ( referencingModule, specifier )
55     static JSHandle<JSTaggedValue> HostResolveImportedModule(JSThread *thread,
56                                                              const JSHandle<SourceTextModule> &module,
57                                                              const JSHandle<JSTaggedValue> &moduleRequest);
58     static JSHandle<JSTaggedValue> HostResolveImportedModuleWithMerge(JSThread *thread,
59                                                                       const JSHandle<SourceTextModule> &module,
60                                                                       const JSHandle<JSTaggedValue> &moduleRequest);
61 
62     // 15.2.1.16.2 GetExportedNames(exportStarSet)
63     static CVector<std::string> GetExportedNames(JSThread *thread, const JSHandle<SourceTextModule> &module,
64                                                  const JSHandle<TaggedArray> &exportStarSet);
65 
66     // 15.2.1.16.3 ResolveExport(exportName, resolveVector)
67     static JSHandle<JSTaggedValue> ResolveExport(JSThread *thread, const JSHandle<SourceTextModule> &module,
68         const JSHandle<JSTaggedValue> &exportName,
69         CVector<std::pair<JSHandle<SourceTextModule>, JSHandle<JSTaggedValue>>> &resolveVector);
70     static JSHandle<JSTaggedValue> ResolveExportObject(JSThread *thread, const JSHandle<SourceTextModule> &module,
71                                                        const JSHandle<JSTaggedValue> &exportObject,
72                                                        const JSHandle<JSTaggedValue> &exportName);
73     // 15.2.1.16.4.1 InnerModuleInstantiation ( module, stack, index )
74     static int InnerModuleInstantiation(JSThread *thread,
75         const JSHandle<ModuleRecord> &moduleRecord, CVector<JSHandle<SourceTextModule>> &stack,
76         int index, bool excuteFromJob = false);
77 
78     // 15.2.1.16.4.2 ModuleDeclarationEnvironmentSetup ( module )
79     static void ModuleDeclarationEnvironmentSetup(JSThread *thread, const JSHandle<SourceTextModule> &module);
80     static void ModuleDeclarationArrayEnvironmentSetup(JSThread *thread, const JSHandle<SourceTextModule> &module);
81 
82     // 15.2.1.16.5.1 InnerModuleEvaluation ( module, stack, index )
83     static int InnerModuleEvaluation(JSThread *thread, const JSHandle<ModuleRecord> &moduleRecord,
84         CVector<JSHandle<SourceTextModule>> &stack, int index, const void *buffer = nullptr,
85         size_t size = 0, bool excuteFromJob = false);
86     static int ModuleEvaluation(JSThread *thread, const JSHandle<ModuleRecord> &moduleRecord,
87                                 CVector<JSHandle<SourceTextModule>> &stack, int index);
88 
89     // 15.2.1.16.5.2 ModuleExecution ( module )
90     static void ModuleExecution(JSThread *thread, const JSHandle<SourceTextModule> &module,
91                                 const void *buffer = nullptr, size_t size = 0, bool excuteFromJob = false);
92 
93     // 15.2.1.18 Runtime Semantics: GetModuleNamespace ( module )
94     static JSHandle<JSTaggedValue> GetModuleNamespace(JSThread *thread, const JSHandle<SourceTextModule> &module);
95 
96     static void AddImportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module,
97                                const JSHandle<ImportEntry> &importEntry, size_t idx, uint32_t len);
98     static void AddLocalExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module,
99                                     const JSHandle<LocalExportEntry> &exportEntry, size_t idx, uint32_t len);
100     static void AddIndirectExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module,
101                                        const JSHandle<IndirectExportEntry> &exportEntry, size_t idx, uint32_t len);
102     static void AddStarExportEntry(JSThread *thread, const JSHandle<SourceTextModule> &module,
103                                    const JSHandle<StarExportEntry> &exportEntry, size_t idx, uint32_t len);
104     static std::pair<bool, ModuleTypes> CheckNativeModule(const CString &moduleRequestName);
105     static Local<JSValueRef> GetRequireNativeModuleFunc(EcmaVM *vm, ModuleTypes moduleType);
106     static void MakeAppArgs(const EcmaVM *vm, std::vector<Local<JSValueRef>> &arguments, const CString &moduleName);
107     static void MakeInternalArgs(const EcmaVM *vm, std::vector<Local<JSValueRef>> &arguments,
108                                  const CString &moduleRequestName);
109     static bool LoadNativeModule(JSThread *thread, JSHandle<SourceTextModule> &requiredModule,
110                                  const JSHandle<JSTaggedValue> &moduleRequest, ModuleTypes moduleType);
IsNativeModule(ModuleTypes moduleType)111     inline static bool IsNativeModule(ModuleTypes moduleType)
112     {
113         return moduleType == ModuleTypes::OHOS_MODULE ||
114                moduleType == ModuleTypes::APP_MODULE ||
115                moduleType == ModuleTypes::NATIVE_MODULE ||
116                moduleType == ModuleTypes::INTERNAL_MODULE;
117     }
118 
119     static constexpr size_t SOURCE_TEXT_MODULE_OFFSET = ModuleRecord::SIZE;
120     ACCESSORS(Environment, SOURCE_TEXT_MODULE_OFFSET, NAMESPACE_OFFSET);
121     ACCESSORS(Namespace, NAMESPACE_OFFSET, ECMA_MODULE_FILENAME);
122     ACCESSORS(EcmaModuleFilename, ECMA_MODULE_FILENAME, ECMA_MODULE_RECORDNAME);
123     ACCESSORS(EcmaModuleRecordName, ECMA_MODULE_RECORDNAME, REQUESTED_MODULES_OFFSET);
124     ACCESSORS(RequestedModules, REQUESTED_MODULES_OFFSET, IMPORT_ENTRIES_OFFSET);
125     ACCESSORS(ImportEntries, IMPORT_ENTRIES_OFFSET, LOCAL_EXPORT_ENTTRIES_OFFSET);
126     ACCESSORS(LocalExportEntries, LOCAL_EXPORT_ENTTRIES_OFFSET, INDIRECT_EXPORT_ENTTRIES_OFFSET);
127     ACCESSORS(IndirectExportEntries, INDIRECT_EXPORT_ENTTRIES_OFFSET, START_EXPORT_ENTTRIES_OFFSET);
128     ACCESSORS(StarExportEntries, START_EXPORT_ENTTRIES_OFFSET, NAME_DICTIONARY_OFFSET);
129     ACCESSORS(NameDictionary, NAME_DICTIONARY_OFFSET, EVALUATION_ERROR_OFFSET);
130     ACCESSORS_PRIMITIVE_FIELD(EvaluationError, int32_t, EVALUATION_ERROR_OFFSET, DFS_ANCESTOR_INDEX_OFFSET);
131     ACCESSORS_PRIMITIVE_FIELD(DFSAncestorIndex, int32_t, DFS_ANCESTOR_INDEX_OFFSET, DFS_INDEX_OFFSET);
132     ACCESSORS_PRIMITIVE_FIELD(DFSIndex, int32_t, DFS_INDEX_OFFSET, BIT_FIELD_OFFSET);
133     ACCESSORS_BIT_FIELD(BitField, BIT_FIELD_OFFSET, LAST_OFFSET)
134 
135     DEFINE_ALIGN_SIZE(LAST_OFFSET);
136 
137     // define BitField
138     static constexpr size_t STATUS_BITS = 3;
139     static constexpr size_t MODULE_TYPE_BITS = 4;
140     static constexpr size_t IS_NEW_BC_VERSION_BITS = 1;
141     static constexpr size_t LOADING_TYPE_BITS = 3;
142     static constexpr uint16_t REGISTER_COUNTS = 16;
143 
144     FIRST_BIT_FIELD(BitField, Status, ModuleStatus, STATUS_BITS)
145     NEXT_BIT_FIELD(BitField, Types, ModuleTypes, MODULE_TYPE_BITS, Status)
146     NEXT_BIT_FIELD(BitField, IsNewBcVersion, bool, IS_NEW_BC_VERSION_BITS, Types)
147     NEXT_BIT_FIELD(BitField, LoadingTypes, LoadingTypes, LOADING_TYPE_BITS, IsNewBcVersion)
148     NEXT_BIT_FIELD(BitField, RegisterCounts, uint16_t, REGISTER_COUNTS, LoadingTypes)
149 
150     DECL_DUMP()
151     DECL_VISIT_OBJECT(SOURCE_TEXT_MODULE_OFFSET, EVALUATION_ERROR_OFFSET)
152 
153     // 15.2.1.16.5 Evaluate()
154     static int Evaluate(JSThread *thread, const JSHandle<SourceTextModule> &module,
155                         const void *buffer = nullptr, size_t size = 0, bool excuteFromJob = false);
156     static int EvaluateForConcurrent(JSThread *thread, const JSHandle<SourceTextModule> &module);
157 
158     // 15.2.1.16.4 Instantiate()
159     static int Instantiate(JSThread *thread, const JSHandle<JSTaggedValue> &moduleHdl,
160         bool excuteFromJob = false);
161     static void InstantiateCJS(JSThread *thread, const JSHandle<SourceTextModule> &currentModule,
162                                const JSHandle<SourceTextModule> &requiredModule);
163     static void InstantiateNativeModule(JSThread *thread, JSHandle<SourceTextModule> &currentModule,
164                                         JSHandle<SourceTextModule> &requiredModule,
165                                         const JSHandle<JSTaggedValue> &moduleRequest,
166                                         ModuleTypes moduleType);
167 
168     JSTaggedValue GetModuleValue(JSThread *thread, int32_t index, bool isThrow);
169     void StoreModuleValue(JSThread *thread, int32_t index, const JSHandle<JSTaggedValue> &value);
170 
171     JSTaggedValue GetModuleValue(JSThread *thread, JSTaggedValue key, bool isThrow);
172     void StoreModuleValue(JSThread *thread, const JSHandle<JSTaggedValue> &key, const JSHandle<JSTaggedValue> &value);
173     static JSHandle<JSTaggedValue> ResolveIndirectExport(JSThread *thread, const JSHandle<JSTaggedValue> &exportEntry,
174                                                          const JSHandle<JSTaggedValue> &exportName,
175                                                          const JSHandle<SourceTextModule> &module,
176                                                          CVector<std::pair<JSHandle<SourceTextModule>,
177                                                          JSHandle<JSTaggedValue>>> &resolveVector);
178     static JSTaggedValue GetModuleName(JSTaggedValue currentModule);
179 
180     static bool IsDynamicModule(LoadingTypes types);
181 private:
182     static void SetExportName(JSThread *thread,
183                               const JSHandle<JSTaggedValue> &moduleRequest, const JSHandle<SourceTextModule> &module,
184                               CVector<std::string> &exportedNames, JSHandle<TaggedArray> &newExportStarSet);
185     static JSHandle<JSTaggedValue> GetStarResolution(JSThread *thread, const JSHandle<JSTaggedValue> &exportName,
186                                                      const JSHandle<JSTaggedValue> &moduleRequest,
187                                                      const JSHandle<SourceTextModule> &module,
188                                                      JSMutableHandle<JSTaggedValue> &starResolution,
189                                                      CVector<std::pair<JSHandle<SourceTextModule>,
190                                                      JSHandle<JSTaggedValue>>> &resolveVector);
191     template <typename T>
192     static void AddExportName(JSThread *thread, const JSTaggedValue &exportEntry, CVector<std::string> &exportedNames);
193     static JSHandle<JSTaggedValue> ResolveLocalExport(JSThread *thread, const JSHandle<JSTaggedValue> &exportEntry,
194                                                       const JSHandle<JSTaggedValue> &exportName,
195                                                       const JSHandle<SourceTextModule> &module);
196     static JSHandle<JSTaggedValue> ResolveElementOfObject(JSThread *thread,
197                                                          const JSHandle<JSHClass> &hclass,
198                                                          const JSHandle<JSTaggedValue> &exportName,
199                                                          const JSHandle<SourceTextModule> &module);
200     static bool CheckCircularImport(const JSHandle<SourceTextModule> &module,
201         const JSHandle<JSTaggedValue> &exportName,
202         CVector<std::pair<JSHandle<SourceTextModule>, JSHandle<JSTaggedValue>>> &resolveVector);
203     static void InitializeEnvironment(JSThread *thread, const JSHandle<SourceTextModule> &currentModule,
204         JSHandle<JSTaggedValue> &moduleName, JSHandle<JSTaggedValue> &exports, bool isBundle);
205 
206     static void CheckResolvedBinding(JSThread *thread, const JSHandle<SourceTextModule> &module);
207     static void CheckResolvedIndexBinding(JSThread *thread, const JSHandle<SourceTextModule> &module);
208     static JSTaggedValue FindByExport(const JSTaggedValue &exportEntriesTv, const JSTaggedValue &key,
209                                       const JSTaggedValue &dictionary);
210     static JSHandle<SourceTextModule> GetModuleFromBinding(JSThread *thread, const JSTaggedValue &JSTaggedValue);
211 };
212 
213 class ResolvedBinding final : public Record {
214 public:
215     CAST_CHECK(ResolvedBinding, IsResolvedBinding);
216 
217     static constexpr size_t MODULE_OFFSET = Record::SIZE;
218     ACCESSORS(Module, MODULE_OFFSET, BINDING_NAME_OFFSET);
219     ACCESSORS(BindingName, BINDING_NAME_OFFSET, SIZE);
220 
221     DECL_DUMP()
222     DECL_VISIT_OBJECT(MODULE_OFFSET, SIZE)
223 };
224 class ResolvedIndexBinding final : public Record {
225 public:
226     CAST_CHECK(ResolvedIndexBinding, IsResolvedIndexBinding);
227 
228     static constexpr size_t MODULE_OFFSET = Record::SIZE;
229     ACCESSORS(Module, MODULE_OFFSET, INDEX_OFFSET);
230     ACCESSORS_PRIMITIVE_FIELD(Index, int32_t, INDEX_OFFSET, END_OFFSET);
231     DEFINE_ALIGN_SIZE(END_OFFSET);
232 
233     DECL_DUMP()
234     DECL_VISIT_OBJECT(MODULE_OFFSET, INDEX_OFFSET)
235 };
236 }  // namespace panda::ecmascript
237 #endif  // ECMASCRIPT_MODULE_JS_MODULE_SOURCE_TEXT_H
238