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