• 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 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