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