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