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 "typeRecorder.h"
17
18 #include <ir/astDump.h>
19
20 namespace panda::es2panda::extractor {
21
22 template <typename M, typename K, typename V>
FindValue(const M & map,const K & key,const V & value)23 static V FindValue(const M &map, const K &key, const V &value)
24 {
25 auto t = map.find(key);
26 if (t != map.end()) {
27 return t->second;
28 }
29 return value;
30 }
31
TypeRecorder(ArenaAllocator * allocator,compiler::CompilerContext * context)32 TypeRecorder::TypeRecorder(ArenaAllocator *allocator, compiler::CompilerContext *context)
33 : allocator_(allocator), context_(context), buffStorage_(allocator_->Adapter())
34 {
35 }
36
Allocator() const37 ArenaAllocator *TypeRecorder::Allocator() const
38 {
39 return allocator_;
40 }
41
BuffStorage() const42 const ArenaVector<compiler::LiteralBuffer *> &TypeRecorder::BuffStorage() const
43 {
44 return buffStorage_;
45 }
46
NodeTypeIndex() const47 const std::unordered_map<const ir::AstNode *, int64_t> &TypeRecorder::NodeTypeIndex() const
48 {
49 return nodeTypeIndex_;
50 }
51
VariableTypeIndex() const52 const std::unordered_map<const binder::Variable *, int64_t> &TypeRecorder::VariableTypeIndex() const
53 {
54 return variableTypeIndex_;
55 }
56
ExportType() const57 const std::unordered_map<std::string, int64_t> &TypeRecorder::ExportType() const
58 {
59 return exportType_;
60 }
61
DeclareType() const62 const std::unordered_map<std::string, int64_t> &TypeRecorder::DeclareType() const
63 {
64 return declareType_;
65 }
66
NewLiteralBuffer()67 compiler::LiteralBuffer *TypeRecorder::NewLiteralBuffer()
68 {
69 return allocator_->New<compiler::LiteralBuffer>(allocator_);
70 }
71
AddLiteralBuffer(compiler::LiteralBuffer * buffer)72 int64_t TypeRecorder::AddLiteralBuffer(compiler::LiteralBuffer *buffer)
73 {
74 buffStorage_.push_back(buffer);
75 buffer->SetIndex(context_->NewLiteralIndex());
76 return buffer->Index();
77 }
78
GetLiteralBuffer(int64_t index) const79 compiler::LiteralBuffer *TypeRecorder::GetLiteralBuffer(int64_t index) const
80 {
81 auto res = std::find_if(buffStorage_.begin(), buffStorage_.end(),
82 [&index](const auto &t) { return t->Index() == index; });
83 return (res != buffStorage_.end()) ? *res : nullptr;
84 }
85
SetLiteralBuffer(int64_t index,compiler::LiteralBuffer * buffer)86 void TypeRecorder::SetLiteralBuffer(int64_t index, compiler::LiteralBuffer *buffer)
87 {
88 std::replace_if(buffStorage_.begin(), buffStorage_.end(),
89 [&index](const auto &t) { return t->Index() == index; }, buffer);
90 buffer->SetIndex(index);
91 }
92
GetAnonymousFunctionNames(const ir::ScriptFunction * func) const93 util::StringView TypeRecorder::GetAnonymousFunctionNames(const ir::ScriptFunction *func) const
94 {
95 const auto &m = context_->Binder()->AnonymousFunctionNames();
96 auto res = m.find(func);
97 return (res != m.end()) ? std::move(res->second) : std::move(DEFAULT_NAME);
98 }
99
CalculateUserType() const100 int64_t TypeRecorder::CalculateUserType() const
101 {
102 return userType_.size();
103 }
104
AddUserType(int64_t index)105 void TypeRecorder::AddUserType(int64_t index)
106 {
107 userType_.insert(index);
108 }
109
GetTypeSummaryIndex() const110 int64_t TypeRecorder::GetTypeSummaryIndex() const
111 {
112 return typeSummaryIndex_;
113 }
114
SetTypeSummaryIndex(int64_t index)115 void TypeRecorder::SetTypeSummaryIndex(int64_t index)
116 {
117 typeSummaryIndex_ = index;
118 }
119
GetUserTypeIndexShift() const120 int64_t TypeRecorder::GetUserTypeIndexShift() const
121 {
122 return userTypeIndexShift_;
123 }
124
SetUserTypeIndexShift(int64_t index)125 void TypeRecorder::SetUserTypeIndexShift(int64_t index)
126 {
127 userTypeIndexShift_ = index;
128 }
129
GetNodeTypeIndex(const ir::AstNode * node) const130 int64_t TypeRecorder::GetNodeTypeIndex(const ir::AstNode *node) const
131 {
132 return FindValue(nodeTypeIndex_, node, PRIMITIVETYPE_ANY);
133 }
134
SetNodeTypeIndex(const ir::AstNode * node,int64_t index)135 void TypeRecorder::SetNodeTypeIndex(const ir::AstNode *node, int64_t index)
136 {
137 if (node == nullptr || GetNodeTypeIndex(node) != PRIMITIVETYPE_ANY) {
138 return;
139 }
140
141 nodeTypeIndex_[node] = index;
142 }
143
GetVariableTypeIndex(const binder::Variable * variable) const144 int64_t TypeRecorder::GetVariableTypeIndex(const binder::Variable *variable) const
145 {
146 return FindValue(variableTypeIndex_, variable, PRIMITIVETYPE_ANY);
147 }
148
SetVariableTypeIndex(const binder::Variable * variable,int64_t index)149 void TypeRecorder::SetVariableTypeIndex(const binder::Variable *variable, int64_t index)
150 {
151 if (variable == nullptr || GetVariableTypeIndex(variable) != PRIMITIVETYPE_ANY) {
152 return;
153 }
154
155 variableTypeIndex_[variable] = index;
156 }
157
SetIdentifierTypeIndex(const ir::Identifier * identifier,int64_t index)158 void TypeRecorder::SetIdentifierTypeIndex(const ir::Identifier *identifier, int64_t index)
159 {
160 if (identifier == nullptr) {
161 return;
162 }
163 SetNodeTypeIndex(identifier, index);
164 SetVariableTypeIndex(identifier->Variable(), index);
165 }
166
GetBuiltinInst(const std::vector<int64_t> & allTypes) const167 int64_t TypeRecorder::GetBuiltinInst(const std::vector<int64_t> &allTypes) const
168 {
169 return FindValue(builtinInst_, allTypes, PRIMITIVETYPE_ANY);
170 }
171
SetBuiltinInst(const std::vector<int64_t> & allTypes,int64_t instIndex)172 void TypeRecorder::SetBuiltinInst(const std::vector<int64_t> &allTypes, int64_t instIndex)
173 {
174 builtinInst_[allTypes] = instIndex;
175 }
176
GetClassInst(int64_t classIndex) const177 int64_t TypeRecorder::GetClassInst(int64_t classIndex) const
178 {
179 return FindValue(classInst_, classIndex, PRIMITIVETYPE_ANY);
180 }
181
SetClassInst(int64_t classIndex,int64_t instIndex)182 void TypeRecorder::SetClassInst(int64_t classIndex, int64_t instIndex)
183 {
184 if (classIndex == PRIMITIVETYPE_ANY) {
185 return;
186 }
187 classInst_[classIndex] = instIndex;
188 }
189
GetClassType(int64_t instIndex) const190 int64_t TypeRecorder::GetClassType(int64_t instIndex) const
191 {
192 // Here we always return the original type rather than instance type
193 // If `instIndex` is not in `classType_`, it means `instIndex` does not come from new instance
194 return FindValue(classType_, instIndex, instIndex);
195 }
196
SetClassType(int64_t instIndex,int64_t classIndex)197 void TypeRecorder::SetClassType(int64_t instIndex, int64_t classIndex)
198 {
199 if (instIndex == PRIMITIVETYPE_ANY) {
200 return;
201 }
202 classType_[instIndex] = classIndex;
203 }
204
GetArrayType(int64_t contentIndex) const205 int64_t TypeRecorder::GetArrayType(int64_t contentIndex) const
206 {
207 return FindValue(arrayType_, contentIndex, PRIMITIVETYPE_ANY);
208 }
209
SetArrayType(int64_t contentIndex,int64_t arrayIndex)210 void TypeRecorder::SetArrayType(int64_t contentIndex, int64_t arrayIndex)
211 {
212 arrayType_[contentIndex] = arrayIndex;
213 }
214
GetUnionType(const std::string & unionStr) const215 int64_t TypeRecorder::GetUnionType(const std::string &unionStr) const
216 {
217 return FindValue(unionType_, unionStr, PRIMITIVETYPE_ANY);
218 }
219
SetUnionType(const std::string & unionStr,int64_t unionIndex)220 void TypeRecorder::SetUnionType(const std::string &unionStr, int64_t unionIndex)
221 {
222 unionType_[unionStr] = unionIndex;
223 }
224
GetObjectType(const std::string & objectStr) const225 int64_t TypeRecorder::GetObjectType(const std::string &objectStr) const
226 {
227 return FindValue(objectType_, objectStr, PRIMITIVETYPE_ANY);
228 }
229
SetObjectType(const std::string & objectStr,int64_t objectIndex)230 void TypeRecorder::SetObjectType(const std::string &objectStr, int64_t objectIndex)
231 {
232 objectType_[objectStr] = objectIndex;
233 }
234
GetExportType(const std::string & exportStr) const235 int64_t TypeRecorder::GetExportType(const std::string &exportStr) const
236 {
237 return FindValue(exportType_, exportStr, PRIMITIVETYPE_ANY);
238 }
239
SetExportType(const std::string & exportStr,int64_t exportIndex)240 void TypeRecorder::SetExportType(const std::string &exportStr, int64_t exportIndex)
241 {
242 exportType_[exportStr] = exportIndex;
243 }
244
GetDeclareType(const std::string & declareStr) const245 int64_t TypeRecorder::GetDeclareType(const std::string &declareStr) const
246 {
247 return FindValue(declareType_, declareStr, PRIMITIVETYPE_ANY);
248 }
249
SetDeclareType(const std::string & declareStr,int64_t declareIndex)250 void TypeRecorder::SetDeclareType(const std::string &declareStr, int64_t declareIndex)
251 {
252 declareType_[declareStr] = declareIndex;
253 }
254
GetNamespaceType(const std::string & namespaceStr) const255 int64_t TypeRecorder::GetNamespaceType(const std::string &namespaceStr) const
256 {
257 return FindValue(namespaceType_, namespaceStr, PRIMITIVETYPE_ANY);
258 }
259
SetNamespaceType(const std::string & namespaceStr,int64_t namespaceIndex)260 void TypeRecorder::SetNamespaceType(const std::string &namespaceStr, int64_t namespaceIndex)
261 {
262 namespaceType_[namespaceStr] = namespaceIndex;
263 }
264
GetNamespacePath(const std::string & namespaceStr) const265 std::string TypeRecorder::GetNamespacePath(const std::string &namespaceStr) const
266 {
267 return FindValue(namespacePath_, namespaceStr, std::string());
268 }
269
SetNamespacePath(const std::string & namespaceStr,const std::string & filePath)270 void TypeRecorder::SetNamespacePath(const std::string &namespaceStr, const std::string &filePath)
271 {
272 namespacePath_[namespaceStr] = filePath;
273 }
274
GetAnonymousReExport() const275 const std::set<util::StringView> &TypeRecorder::GetAnonymousReExport() const
276 {
277 return anonymousReExport_;
278 }
279
AddAnonymousReExport(const util::StringView & reExportStr)280 void TypeRecorder::AddAnonymousReExport(const util::StringView &reExportStr)
281 {
282 anonymousReExport_.insert(reExportStr);
283 }
284
Dump(const parser::Program * program) const285 ALWAYS_INLINE void TypeRecorder::Dump(const parser::Program *program) const
286 {
287 #ifndef NDEBUG
288 std::cout << "========== TypeExtractor ==========" << std::endl;
289 std::cout << "---------- userType_ ----------" << std::endl;
290 std::stringstream ss;
291 for (const auto &t : userType_) {
292 ss << t << " | ";
293 }
294 std::cout << ss.str() << std::endl;
295 std::cout << "---------- nodeTypeIndex_ ----------" << std::endl;
296 for (const auto &t : nodeTypeIndex_) {
297 ir::AstDumper dumper(t.first);
298 std::cout << dumper.Str() << " : " << t.second << std::endl;
299 }
300 std::cout << "---------- variableTypeIndex_ ----------" << std::endl;
301 for (const auto &t : variableTypeIndex_) {
302 std::cout << t.first->Name() << " : " << t.second << std::endl;
303 }
304 std::cout << "---------- builtinInst_ ----------" << std::endl;
305 for (const auto &t : builtinInst_) {
306 for (const auto &p : t.first) {
307 std::cout << p << " ";
308 }
309 std::cout << t.second << std::endl;
310 }
311
312 auto fn = [](const auto &map) {
313 for (const auto &t : map) {
314 std::cout << t.first << " : " << t.second << std::endl;
315 }
316 };
317 std::cout << "---------- classInst_ ----------" << std::endl;
318 std::cout << "---- class ---- | ---- inst ----" << std::endl;
319 fn(classInst_);
320 std::cout << "---------- classType_ ----------" << std::endl;
321 std::cout << "---- inst ---- | ---- class ----" << std::endl;
322 fn(classType_);
323 std::cout << "---------- arrayType_ ----------" << std::endl;
324 fn(arrayType_);
325 std::cout << "---------- unionType_ ----------" << std::endl;
326 fn(unionType_);
327 std::cout << "---------- objectType_ ----------" << std::endl;
328 fn(objectType_);
329 std::cout << "---------- exportType_ ----------" << std::endl;
330 fn(exportType_);
331 std::cout << "---------- declareType_ ----------" << std::endl;
332 fn(declareType_);
333 std::cout << "---------- namespaceType_ ----------" << std::endl;
334 fn(namespaceType_);
335 std::cout << "---------- namespacePath_ ----------" << std::endl;
336 fn(namespacePath_);
337 std::cout << "---------- anonymousReExport_ ----------" << std::endl;
338 for (const auto &t : anonymousReExport_) {
339 std::cout << std::string(t) << std::endl;
340 }
341 std::cout << "========== TypeExtractor ==========" << std::endl;
342 #endif
343 }
344
345 } // namespace panda::es2panda::extractor
346