1 /*
2 * Copyright (c) 2024 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 "abc_module_array_processor.h"
17
18 namespace panda::abc2program {
19
AbcModuleArrayProcessor(panda_file::File::EntityId entity_id, Abc2ProgramEntityContainer &entity_container)20 AbcModuleArrayProcessor::AbcModuleArrayProcessor(panda_file::File::EntityId entity_id,
21 Abc2ProgramEntityContainer &entity_container)
22 : AbcFileEntityProcessor(entity_id, entity_container)
23 {
24 module_data_accessor_ = std::make_unique<panda_file::ModuleDataAccessor>(*file_, entity_id_);
25 }
26
FillProgramData()27 void AbcModuleArrayProcessor::FillProgramData()
28 {
29 const std::vector<uint32_t> &request_modules_offset = module_data_accessor_->getRequestModules();
30 std::vector<panda::pandasm::LiteralArray::Literal> literal_vec;
31 FillModuleRequests(literal_vec, request_modules_offset);
32 uint32_t regular_import_num = 0;
33 uint32_t namespace_import_num = 0;
34 uint32_t local_export_num = 0;
35 uint32_t indirect_export_num = 0;
36 uint32_t star_export_num = 0;
37 module_data_accessor_->EnumerateModuleRecord([&](panda_file::ModuleTag tag, uint32_t export_name_offset,
38 uint32_t request_module_idx, uint32_t import_name_offset, uint32_t local_name_offset) {
39 switch (tag) {
40 case panda_file::ModuleTag::REGULAR_IMPORT:
41 FillRegularImportEntry(literal_vec, request_module_idx, import_name_offset, local_name_offset);
42 ++regular_import_num;
43 break;
44 case panda_file::ModuleTag::NAMESPACE_IMPORT:
45 FillNamespaceImportEntry(literal_vec, request_module_idx, local_name_offset);
46 ++namespace_import_num;
47 break;
48 case panda_file::ModuleTag::LOCAL_EXPORT:
49 FillLocalExportEntry(literal_vec, export_name_offset, local_name_offset);
50 ++local_export_num;
51 break;
52 case panda_file::ModuleTag::INDIRECT_EXPORT:
53 FillIndirectExportEntry(literal_vec, export_name_offset, request_module_idx, import_name_offset);
54 ++indirect_export_num;
55 break;
56 case panda_file::ModuleTag::STAR_EXPORT:
57 FillStarExportEntry(literal_vec, request_module_idx);
58 ++star_export_num;
59 break;
60 default: {
61 UNREACHABLE();
62 }
63 }
64 });
65 std::vector<uint32_t> num_vec = {request_modules_offset.size(), regular_import_num, namespace_import_num,
66 local_export_num, indirect_export_num, star_export_num};
67 FillEntrySize(literal_vec, num_vec);
68 auto module_array = panda::pandasm::LiteralArray(std::move(literal_vec));
69 program_->literalarray_table.emplace(entity_container_.GetLiteralArrayIdName(entity_id_.GetOffset()),
70 std::move(module_array));
71 }
72
FillModuleRequests(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, const std::vector<uint32_t> &request_modules_offset)73 void AbcModuleArrayProcessor::FillModuleRequests(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
74 const std::vector<uint32_t> &request_modules_offset)
75 {
76 panda::pandasm::LiteralArray::Literal module_size = {
77 .tag_ = panda::panda_file::LiteralTag::INTEGER,
78 .value_ = static_cast<uint32_t>(request_modules_offset.size())
79 };
80 literal_vec.emplace_back(module_size);
81 for (auto &request : request_modules_offset) {
82 panda::pandasm::LiteralArray::Literal module_request = {
83 .tag_ = panda::panda_file::LiteralTag::STRING,
84 .value_ = GetStringById(panda_file::File::EntityId{request})
85 };
86 literal_vec.emplace_back(module_request);
87 }
88 }
89
FillRegularImportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, uint32_t &request_module_idx, uint32_t &import_name_offset, uint32_t &local_name_offset)90 void AbcModuleArrayProcessor::FillRegularImportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
91 uint32_t &request_module_idx, uint32_t &import_name_offset, uint32_t &local_name_offset)
92 {
93 panda::pandasm::LiteralArray::Literal local_name = {
94 .tag_ = panda::panda_file::LiteralTag::STRING,
95 .value_ = GetStringById(panda_file::File::EntityId{local_name_offset})
96 };
97 literal_vec.emplace_back(local_name);
98 panda::pandasm::LiteralArray::Literal import_name = {
99 .tag_ = panda::panda_file::LiteralTag::STRING,
100 .value_ = GetStringById(panda_file::File::EntityId{import_name_offset})
101 };
102 literal_vec.emplace_back(import_name);
103 panda::pandasm::LiteralArray::Literal module_request = {
104 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
105 .value_ = static_cast<uint16_t>(request_module_idx)
106 };
107 literal_vec.emplace_back(module_request);
108 }
109
FillNamespaceImportEntry( std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, uint32_t &request_module_idx, uint32_t &local_name_offset)110 void AbcModuleArrayProcessor::FillNamespaceImportEntry(
111 std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
112 uint32_t &request_module_idx, uint32_t &local_name_offset)
113 {
114 panda::pandasm::LiteralArray::Literal local_name = {
115 .tag_ = panda::panda_file::LiteralTag::STRING,
116 .value_ = GetStringById(panda_file::File::EntityId{local_name_offset})
117 };
118 literal_vec.emplace_back(local_name);
119 panda::pandasm::LiteralArray::Literal module_request = {
120 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
121 .value_ = static_cast<uint16_t>(request_module_idx)
122 };
123 literal_vec.emplace_back(module_request);
124 }
125
FillLocalExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, uint32_t export_name_offset, uint32_t &local_name_offset)126 void AbcModuleArrayProcessor::FillLocalExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
127 uint32_t export_name_offset, uint32_t &local_name_offset)
128 {
129 panda::pandasm::LiteralArray::Literal local_name = {
130 .tag_ = panda::panda_file::LiteralTag::STRING,
131 .value_ = GetStringById(panda_file::File::EntityId{local_name_offset})
132 };
133 literal_vec.emplace_back(local_name);
134 panda::pandasm::LiteralArray::Literal export_name = {
135 .tag_ = panda::panda_file::LiteralTag::STRING,
136 .value_ = GetStringById(panda_file::File::EntityId{export_name_offset})
137 };
138 literal_vec.emplace_back(export_name);
139 }
140
FillIndirectExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, uint32_t export_name_offset, uint32_t request_module_idx, uint32_t import_name_offset)141 void AbcModuleArrayProcessor::FillIndirectExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
142 uint32_t export_name_offset, uint32_t request_module_idx, uint32_t import_name_offset)
143 {
144 panda::pandasm::LiteralArray::Literal export_name = {
145 .tag_ = panda::panda_file::LiteralTag::STRING,
146 .value_ = GetStringById(panda_file::File::EntityId{export_name_offset})
147 };
148 literal_vec.emplace_back(export_name);
149 panda::pandasm::LiteralArray::Literal import_name = {
150 .tag_ = panda::panda_file::LiteralTag::STRING,
151 .value_ = GetStringById(panda_file::File::EntityId{import_name_offset})
152 };
153 literal_vec.emplace_back(import_name);
154 panda::pandasm::LiteralArray::Literal module_request = {
155 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
156 .value_ = static_cast<uint16_t>(request_module_idx)
157 };
158 literal_vec.emplace_back(module_request);
159 }
160
FillStarExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, uint32_t request_module_idx)161 void AbcModuleArrayProcessor::FillStarExportEntry(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
162 uint32_t request_module_idx)
163 {
164 panda::pandasm::LiteralArray::Literal module_request = {
165 .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE,
166 .value_ = static_cast<uint16_t>(request_module_idx)
167 };
168 literal_vec.emplace_back(module_request);
169 }
170
171 // Add the literal of the size of various attributes in the module literal array.
FillEntrySize(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec, const std::vector<uint32_t> &num_vec)172 void AbcModuleArrayProcessor::FillEntrySize(std::vector<panda::pandasm::LiteralArray::Literal> &literal_vec,
173 const std::vector<uint32_t> &num_vec)
174 {
175 // Insert literals of regular_import_num, namespace_import_num, local_export_num,
176 // indirect_export_num, star_export_num to literal_vec.
177 uint32_t idx_num = num_vec[0] + 1;
178 for (size_t index = 1; index < num_vec.size(); ++index) {
179 auto num = num_vec[index];
180 panda::pandasm::LiteralArray::Literal entry_size = {
181 .tag_ = panda::panda_file::LiteralTag::INTEGER,
182 .value_ = static_cast<uint32_t>(num)
183 };
184 literal_vec.insert(literal_vec.begin() + idx_num, entry_size);
185 // '1' stands for each entry_size, which has been inserted into literal vec
186 idx_num += 1;
187 ASSERT(index - 1 < sizeof(LITERAL_NUMS)/sizeof(LITERAL_NUMS[0]));
188 // skip total num of module literals for each module kind
189 idx_num += LITERAL_NUMS[index-1] * num;
190 }
191 }
192 } // namespace panda::abc2program