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