1 /*
2 * Copyright (c) 2022 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/jspandafile/accessor/module_data_accessor.h"
17 #include "ecmascript/global_env_constants-inl.h"
18 #include "ecmascript/jspandafile/js_pandafile_manager.h"
19 #include "ecmascript/shared_objects/js_shared_array.h"
20
21 namespace panda::ecmascript {
ModuleDataAccessor(const JSPandaFile *pandaFile, EntityId moduleDataId)22 ModuleDataAccessor::ModuleDataAccessor(const JSPandaFile *pandaFile, EntityId moduleDataId)
23 : pandaFile_(pandaFile), moduleDataId_(moduleDataId)
24 {
25 auto &pf = *pandaFile_->GetPandaFile();
26 auto sp = pf.GetSpanFromId(moduleDataId);
27
28 auto moduleSp = sp.SubSpan(panda_file::ID_SIZE); // skip literalnum
29
30 numModuleRequests_ = panda_file::helpers::Read<panda_file::ID_SIZE>(&moduleSp);
31
32 for (size_t idx = 0; idx < numModuleRequests_; idx++) {
33 auto value = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&moduleSp));
34 moduleRequests_.emplace_back(value);
35 }
36
37 entryDataSp_ = moduleSp;
38 }
39
CreatEntries(JSThread *thread, uint32_t regularImportNum, SharedTypes sharedType)40 JSHandle<TaggedArray> ModuleDataAccessor::CreatEntries(JSThread *thread, uint32_t regularImportNum,
41 SharedTypes sharedType)
42 {
43 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
44 JSHandle<TaggedArray> regularImportEntries;
45 if (sharedType == SharedTypes::SHARED_MODULE) {
46 regularImportEntries = factory->NewSTaggedArray(regularImportNum, JSTaggedValue::Hole(),
47 MemSpaceType::SHARED_OLD_SPACE);
48 } else {
49 regularImportEntries = factory->NewTaggedArray(regularImportNum);
50 }
51 return regularImportEntries;
52 }
53
EnumerateImportEntry(JSThread *thread, const JSHandle<TaggedArray> &requestModuleArray, JSHandle<SourceTextModule> &moduleRecord)54 void ModuleDataAccessor::EnumerateImportEntry(JSThread *thread,
55 const JSHandle<TaggedArray> &requestModuleArray,
56 JSHandle<SourceTextModule> &moduleRecord)
57 {
58 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
59 auto globalConstants = thread->GlobalConstants();
60 auto sp = entryDataSp_;
61 SharedTypes sharedType = moduleRecord->GetSharedType();
62 auto regularImportNum = panda_file::helpers::Read<panda_file::ID_SIZE>(&sp);
63 JSHandle<TaggedArray> regularImportEntries = CreatEntries(thread, regularImportNum, sharedType);
64
65 JSMutableHandle<JSTaggedValue> importName(thread, globalConstants->GetUndefined());
66 JSMutableHandle<JSTaggedValue> localName(thread, globalConstants->GetUndefined());
67 JSMutableHandle<JSTaggedValue> moduleRequest(thread, globalConstants->GetUndefined());
68
69 for (size_t idx = 0; idx < regularImportNum; idx++) {
70 ReadRegularImportEntry(&sp, factory, requestModuleArray, importName, localName, moduleRequest);
71 JSHandle<ImportEntry> importEntry = factory->NewImportEntry(moduleRequest, importName, localName,
72 sharedType);
73 regularImportEntries->Set(thread, idx, importEntry);
74 }
75
76 auto namespaceImportNum = panda_file::helpers::Read<panda_file::ID_SIZE>(&sp);
77 auto totalSize = regularImportNum + namespaceImportNum;
78 if (totalSize == 0) {
79 entryDataSp_ = sp;
80 return;
81 }
82 JSHandle<TaggedArray> importEntries;
83 if (sharedType == SharedTypes::SHARED_MODULE) {
84 importEntries = JSSharedArray::SetCapacity(thread, regularImportEntries, totalSize);
85 } else {
86 importEntries = TaggedArray::SetCapacity(thread, regularImportEntries, totalSize);
87 }
88
89 importName.Update(globalConstants->GetHandledStarString());
90
91 for (size_t idx = regularImportNum; idx < totalSize; idx++) {
92 ReadNamespaceImportEntry(&sp, factory, requestModuleArray, localName, moduleRequest);
93 JSHandle<ImportEntry> importEntry = factory->NewImportEntry(moduleRequest, importName, localName,
94 sharedType);
95 importEntries->Set(thread, idx, importEntry);
96 }
97 entryDataSp_ = sp;
98 moduleRecord->SetImportEntries(thread, importEntries);
99 }
100
ReadRegularImportEntry(Span<const uint8_t> *sp, ObjectFactory *factory, const JSHandle<TaggedArray> &requestModuleArray, JSMutableHandle<JSTaggedValue> &importName, JSMutableHandle<JSTaggedValue> &localName, JSMutableHandle<JSTaggedValue> &moduleRequest)101 void ModuleDataAccessor::ReadRegularImportEntry(Span<const uint8_t> *sp, ObjectFactory *factory,
102 const JSHandle<TaggedArray> &requestModuleArray,
103 JSMutableHandle<JSTaggedValue> &importName,
104 JSMutableHandle<JSTaggedValue> &localName,
105 JSMutableHandle<JSTaggedValue> &moduleRequest)
106 {
107 size_t requestArraySize = requestModuleArray->GetLength();
108
109 auto localNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(sp));
110 auto importNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(sp));
111 auto moduleRequestIdx = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint16_t)>(sp));
112 auto sd = pandaFile_->GetStringData(panda_file::File::EntityId(localNameOffset));
113 localName.Update(JSTaggedValue(factory->GetRawStringFromStringTable(sd)));
114
115 sd = pandaFile_->GetStringData(panda_file::File::EntityId(importNameOffset));
116 importName.Update(JSTaggedValue(factory->GetRawStringFromStringTable(sd)));
117
118 if (requestArraySize != 0) {
119 moduleRequest.Update(requestModuleArray->Get(moduleRequestIdx));
120 }
121 }
122
ReadNamespaceImportEntry(Span<const uint8_t> *sp, ObjectFactory *factory, const JSHandle<TaggedArray> &requestModuleArray, JSMutableHandle<JSTaggedValue> &localName, JSMutableHandle<JSTaggedValue> &moduleRequest)123 void ModuleDataAccessor::ReadNamespaceImportEntry(Span<const uint8_t> *sp, ObjectFactory *factory,
124 const JSHandle<TaggedArray> &requestModuleArray,
125 JSMutableHandle<JSTaggedValue> &localName,
126 JSMutableHandle<JSTaggedValue> &moduleRequest)
127 {
128 size_t requestArraySize = requestModuleArray->GetLength();
129
130 auto localNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(sp));
131 auto moduleRequestIdx = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint16_t)>(sp));
132 auto sd = pandaFile_->GetStringData(panda_file::File::EntityId(localNameOffset));
133 localName.Update(JSTaggedValue(factory->GetRawStringFromStringTable(sd)));
134
135 if (requestArraySize != 0) {
136 moduleRequest.Update(requestModuleArray->Get(moduleRequestIdx));
137 }
138 }
139
EnumerateLocalExportEntry(JSThread *thread, JSHandle<SourceTextModule> &moduleRecord)140 void ModuleDataAccessor::EnumerateLocalExportEntry(JSThread *thread, JSHandle<SourceTextModule> &moduleRecord)
141 {
142 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
143 auto sp = entryDataSp_;
144 auto localExportNum = panda_file::helpers::Read<panda_file::ID_SIZE>(&sp);
145 if (localExportNum == 0) {
146 entryDataSp_ = sp;
147 return;
148 }
149 SharedTypes sharedType = moduleRecord->GetSharedType();
150 JSHandle<TaggedArray> localExportEntries = CreatEntries(thread, localExportNum, sharedType);
151
152 uint32_t localIndex = -1;
153 JSMutableHandle<JSTaggedValue> distinctLocalName(thread, JSTaggedValue::Undefined());
154 for (size_t idx = 0; idx < localExportNum; idx++) {
155 auto localNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&sp));
156 auto exportNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&sp));
157 auto sd = pandaFile_->GetStringData(panda_file::File::EntityId(localNameOffset));
158 JSHandle<JSTaggedValue> localName(thread, factory->GetRawStringFromStringTable(sd));
159
160 sd = pandaFile_->GetStringData(panda_file::File::EntityId(exportNameOffset));
161 JSHandle<JSTaggedValue> exportName(thread, factory->GetRawStringFromStringTable(sd));
162
163 if (!JSTaggedValue::StrictEqual(thread, distinctLocalName, localName)) {
164 distinctLocalName.Update(localName);
165 localIndex++;
166 }
167 JSHandle<LocalExportEntry> localExportEntry = factory->NewLocalExportEntry(exportName, localName, localIndex,
168 sharedType);
169 localExportEntries->Set(thread, idx, localExportEntry);
170 }
171 entryDataSp_ = sp;
172 moduleRecord->SetLocalExportEntries(thread, localExportEntries);
173 }
174
EnumerateIndirectExportEntry(JSThread *thread, const JSHandle<TaggedArray> &requestModuleArray, JSHandle<SourceTextModule> &moduleRecord)175 void ModuleDataAccessor::EnumerateIndirectExportEntry(JSThread *thread, const JSHandle<TaggedArray> &requestModuleArray,
176 JSHandle<SourceTextModule> &moduleRecord)
177 {
178 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
179 auto globalConstants = thread->GlobalConstants();
180 auto sp = entryDataSp_;
181 size_t requestArraySize = requestModuleArray->GetLength();
182
183 auto indirectExportNum = panda_file::helpers::Read<panda_file::ID_SIZE>(&sp);
184 if (indirectExportNum == 0) {
185 entryDataSp_ = sp;
186 return;
187 }
188
189 SharedTypes sharedType = moduleRecord->GetSharedType();
190 JSHandle<TaggedArray> indirectExportEntries = CreatEntries(thread, indirectExportNum, sharedType);
191 JSMutableHandle<JSTaggedValue> moduleRequest(thread, globalConstants->GetUndefined());
192 for (size_t idx = 0; idx < indirectExportNum; idx++) {
193 auto exportNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&sp));
194 auto importNameOffset = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint32_t)>(&sp));
195 auto moduleRequestIdx = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint16_t)>(&sp));
196 auto sd = pandaFile_->GetStringData(panda_file::File::EntityId(exportNameOffset));
197 JSHandle<JSTaggedValue> exportName(thread, factory->GetRawStringFromStringTable(sd));
198
199 sd = pandaFile_->GetStringData(panda_file::File::EntityId(importNameOffset));
200 JSHandle<JSTaggedValue> importName(thread, factory->GetRawStringFromStringTable(sd));
201
202 if (requestArraySize != 0) {
203 moduleRequest.Update(requestModuleArray->Get(moduleRequestIdx));
204 }
205 JSHandle<IndirectExportEntry> indirectExportEntry = factory->NewIndirectExportEntry(exportName,
206 moduleRequest, importName, sharedType);
207 indirectExportEntries->Set(thread, idx, indirectExportEntry);
208 }
209 entryDataSp_ = sp;
210 moduleRecord->SetIndirectExportEntries(thread, indirectExportEntries);
211 }
212
EnumerateStarExportEntry(JSThread *thread, const JSHandle<TaggedArray> &requestModuleArray, JSHandle<SourceTextModule> &moduleRecord)213 void ModuleDataAccessor::EnumerateStarExportEntry(JSThread *thread, const JSHandle<TaggedArray> &requestModuleArray,
214 JSHandle<SourceTextModule> &moduleRecord)
215 {
216 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
217 auto globalConstants = thread->GlobalConstants();
218 auto sp = entryDataSp_;
219 size_t requestArraySize = requestModuleArray->GetLength();
220
221 auto starExportNum = panda_file::helpers::Read<panda_file::ID_SIZE>(&sp);
222 if (starExportNum == 0) {
223 entryDataSp_ = sp;
224 return;
225 }
226
227 SharedTypes sharedType = moduleRecord->GetSharedType();
228 JSHandle<TaggedArray> starExportEntries = CreatEntries(thread, starExportNum, sharedType);
229 JSMutableHandle<JSTaggedValue> moduleRequest(thread, globalConstants->GetUndefined());
230 for (size_t idx = 0; idx < starExportNum; idx++) {
231 auto moduleRequestIdx = static_cast<uint32_t>(panda_file::helpers::Read<sizeof(uint16_t)>(&sp));
232 if (requestArraySize != 0) {
233 moduleRequest.Update(requestModuleArray->Get(moduleRequestIdx));
234 }
235
236 JSHandle<StarExportEntry> starExportEntry = factory->NewStarExportEntry(moduleRequest, sharedType);
237 starExportEntries->Set(thread, idx, starExportEntry.GetTaggedValue());
238 }
239 entryDataSp_ = sp;
240 moduleRecord->SetStarExportEntries(thread, starExportEntries);
241 }
242 } // namespace panda::ecmascript
243