1 /*
2 * Copyright (c) 2021 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 "moduleRecordEmitter.h"
17
18 namespace panda::es2panda::compiler {
GenModuleRequests()19 void ModuleRecordEmitter::GenModuleRequests()
20 {
21 ASSERT(moduleRecord_ != nullptr);
22 auto &moduleRequests = moduleRecord_->GetModuleRequests();
23 panda::pandasm::LiteralArray::Literal moduleSize = {
24 .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast<uint32_t>(moduleRequests.size())};
25 buffer_.emplace_back(moduleSize);
26 for (auto request : moduleRequests) {
27 panda::pandasm::LiteralArray::Literal moduleRequest = {
28 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = (request.source_).Mutf8()};
29 buffer_.emplace_back(moduleRequest);
30
31 if (!NeedEmitPhaseRecord()) {
32 continue;
33 }
34 panda::pandasm::LiteralArray::Literal moduleRequestPhase = {
35 .tag_ = panda::panda_file::LiteralTag::INTEGER_8, .value_ = static_cast<uint8_t>(request.isLazy_)};
36 phaseBuffer_.emplace_back(moduleRequestPhase);
37 }
38 }
39
GenRegularImportEntries()40 void ModuleRecordEmitter::GenRegularImportEntries()
41 {
42 ASSERT(moduleRecord_ != nullptr);
43 auto ®ularImportEntries = moduleRecord_->GetRegularImportEntries();
44 panda::pandasm::LiteralArray::Literal entrySize = {
45 .tag_ = panda::panda_file::LiteralTag::INTEGER,
46 .value_ = static_cast<uint32_t>(regularImportEntries.size())};
47 buffer_.emplace_back(entrySize);
48 for (auto it = regularImportEntries.begin(); it != regularImportEntries.end(); ++it) {
49 auto *entry = it->second;
50 panda::pandasm::LiteralArray::Literal localName = {
51 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->localName_.Mutf8()};
52 buffer_.emplace_back(localName);
53 panda::pandasm::LiteralArray::Literal importName = {
54 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->importName_.Mutf8()};
55 buffer_.emplace_back(importName);
56 panda::pandasm::LiteralArray::Literal moduleRequest = {
57 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
58 .value_ = static_cast<uint16_t>(entry->moduleRequestIdx_)};
59 buffer_.emplace_back(moduleRequest);
60 }
61 }
62
GenNamespaceImportEntries()63 void ModuleRecordEmitter::GenNamespaceImportEntries()
64 {
65 ASSERT(moduleRecord_ != nullptr);
66 auto &namespaceImportEntries = moduleRecord_->GetNamespaceImportEntries();
67 panda::pandasm::LiteralArray::Literal entrySize = {
68 .tag_ = panda::panda_file::LiteralTag::INTEGER,
69 .value_ = static_cast<uint32_t>(namespaceImportEntries.size())};
70 buffer_.emplace_back(entrySize);
71 for (const auto *entry : namespaceImportEntries) {
72 panda::pandasm::LiteralArray::Literal localName = {
73 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->localName_.Mutf8()};
74 buffer_.emplace_back(localName);
75 panda::pandasm::LiteralArray::Literal moduleRequest = {
76 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
77 .value_ = static_cast<uint16_t>(entry->moduleRequestIdx_)};
78 buffer_.emplace_back(moduleRequest);
79 }
80 }
81
GenLocalExportEntries()82 void ModuleRecordEmitter::GenLocalExportEntries()
83 {
84 ASSERT(moduleRecord_ != nullptr);
85 auto &localExportEntries = moduleRecord_->GetLocalExportEntries();
86 panda::pandasm::LiteralArray::Literal entrySize = {
87 .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast<uint32_t>(localExportEntries.size())};
88 buffer_.emplace_back(entrySize);
89 std::unordered_set<std::string> local_export_local_names;
90 for (auto it = localExportEntries.begin(); it != localExportEntries.end(); ++it) {
91 auto *entry = it->second;
92 panda::pandasm::LiteralArray::Literal localName = {
93 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->localName_.Mutf8()};
94 buffer_.emplace_back(localName);
95 panda::pandasm::LiteralArray::Literal exportName = {
96 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->exportName_.Mutf8()};
97 buffer_.emplace_back(exportName);
98 // Slot of stmodulevar/ldlocalmodulevar is the index of its local name, while
99 // one local name can match multiple external names with "export...as...".
100 // Local export entries are sorted by their local name, thus using an unrodered_set
101 // can get the correct index form (size - 1) (starts from 0).
102 // See SourceTextModuleRecord::AssignIndexToModuleVariable for more details
103 local_export_local_names.emplace(entry->localName_);
104 if (entry->isConstant_) {
105 constant_local_export_slots_.emplace(local_export_local_names.size() - 1);
106 }
107 }
108 }
109
GenIndirectExportEntries()110 void ModuleRecordEmitter::GenIndirectExportEntries()
111 {
112 ASSERT(moduleRecord_ != nullptr);
113 auto &indirectExportEntries = moduleRecord_->GetIndirectExportEntries();
114 panda::pandasm::LiteralArray::Literal entrySize = {
115 .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast<uint32_t>(indirectExportEntries.size())};
116 buffer_.emplace_back(entrySize);
117 for (const auto *entry : indirectExportEntries) {
118 panda::pandasm::LiteralArray::Literal exportName = {
119 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->exportName_.Mutf8()};
120 buffer_.emplace_back(exportName);
121 panda::pandasm::LiteralArray::Literal importName = {
122 .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = entry->importName_.Mutf8()};
123 buffer_.emplace_back(importName);
124 panda::pandasm::LiteralArray::Literal moduleRequest = {
125 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
126 .value_ = static_cast<uint16_t>(entry->moduleRequestIdx_)};
127 buffer_.emplace_back(moduleRequest);
128 }
129 }
130
GenStarExportEntries()131 void ModuleRecordEmitter::GenStarExportEntries()
132 {
133 ASSERT(moduleRecord_ != nullptr);
134 auto &starExportEntries = moduleRecord_->GetStarExportEntries();
135 panda::pandasm::LiteralArray::Literal entrySize = {
136 .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast<uint32_t>(starExportEntries.size())};
137 buffer_.emplace_back(entrySize);
138 for (const auto *entry : starExportEntries) {
139 panda::pandasm::LiteralArray::Literal moduleRequest = {
140 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
141 .value_ = static_cast<uint16_t>(entry->moduleRequestIdx_)};
142 buffer_.emplace_back(moduleRequest);
143 }
144 }
145
Generate()146 void ModuleRecordEmitter::Generate()
147 {
148 GenModuleRequests();
149 GenRegularImportEntries();
150 GenNamespaceImportEntries();
151 GenLocalExportEntries();
152 GenIndirectExportEntries();
153 GenStarExportEntries();
154 }
155 } // namespace panda::es2panda::compiler
156