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