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
GetRecordName() const93 util::StringView TypeRecorder::GetRecordName() const
94 {
95 return context_->Binder()->Program()->RecordName();
96 }
97
GetAnonymousFunctionNames(const ir::ScriptFunction * func) const98 util::StringView TypeRecorder::GetAnonymousFunctionNames(const ir::ScriptFunction *func) const
99 {
100 const auto &m = context_->Binder()->AnonymousFunctionNames();
101 auto res = m.find(func);
102 return (res != m.end()) ? std::move(res->second) : std::move(DEFAULT_NAME);
103 }
104
GetUserType() const105 const std::set<int64_t> &TypeRecorder::GetUserType() const
106 {
107 return userType_;
108 }
109
AddUserType(int64_t index)110 void TypeRecorder::AddUserType(int64_t index)
111 {
112 if (index > TypeRecorder::USERTYPEINDEXHEAD) {
113 userType_.insert(index);
114 }
115 }
116
GetTypeSummaryIndex() const117 int64_t TypeRecorder::GetTypeSummaryIndex() const
118 {
119 return typeSummaryIndex_;
120 }
121
SetTypeSummaryIndex(int64_t index)122 void TypeRecorder::SetTypeSummaryIndex(int64_t index)
123 {
124 typeSummaryIndex_ = index;
125 }
126
GetUserTypeIndexShift() const127 int64_t TypeRecorder::GetUserTypeIndexShift() const
128 {
129 return userTypeIndexShift_;
130 }
131
SetUserTypeIndexShift(int64_t index)132 void TypeRecorder::SetUserTypeIndexShift(int64_t index)
133 {
134 userTypeIndexShift_ = index;
135 }
136
GetNodeTypeIndex(const ir::AstNode * node) const137 int64_t TypeRecorder::GetNodeTypeIndex(const ir::AstNode *node) const
138 {
139 return FindValue(nodeTypeIndex_, node, PRIMITIVETYPE_ANY);
140 }
141
SetNodeTypeIndex(const ir::AstNode * node,int64_t index)142 void TypeRecorder::SetNodeTypeIndex(const ir::AstNode *node, int64_t index)
143 {
144 if (node == nullptr || GetNodeTypeIndex(node) != PRIMITIVETYPE_ANY || index == PRIMITIVETYPE_ANY) {
145 return;
146 }
147
148 nodeTypeIndex_[node] = index;
149 ASSERT(GetNodeTypeIndex(node) == index);
150 }
151
UpdateNodeTypeIndex(const ir::AstNode * node,int64_t index)152 void TypeRecorder::UpdateNodeTypeIndex(const ir::AstNode *node, int64_t index)
153 {
154 if (node == nullptr) {
155 return;
156 }
157
158 nodeTypeIndex_[node] = index;
159 ASSERT(GetNodeTypeIndex(node) == index);
160 }
161
GetVariableTypeIndex(const binder::Variable * variable) const162 int64_t TypeRecorder::GetVariableTypeIndex(const binder::Variable *variable) const
163 {
164 return FindValue(variableTypeIndex_, variable, PRIMITIVETYPE_ANY);
165 }
166
SetVariableTypeIndex(const binder::Variable * variable,int64_t index)167 void TypeRecorder::SetVariableTypeIndex(const binder::Variable *variable, int64_t index)
168 {
169 if (variable == nullptr || GetVariableTypeIndex(variable) != PRIMITIVETYPE_ANY || index == PRIMITIVETYPE_ANY) {
170 return;
171 }
172
173 variableTypeIndex_[variable] = index;
174 ASSERT(GetVariableTypeIndex(variable) == index);
175 }
176
SetIdentifierTypeIndex(const ir::Identifier * identifier,int64_t index)177 void TypeRecorder::SetIdentifierTypeIndex(const ir::Identifier *identifier, int64_t index)
178 {
179 if (identifier == nullptr || index == PRIMITIVETYPE_ANY) {
180 return;
181 }
182 SetNodeTypeIndex(identifier, index);
183 SetVariableTypeIndex(identifier->Variable(), index);
184 }
185
GetBuiltinInst(const std::vector<int64_t> & allTypes) const186 int64_t TypeRecorder::GetBuiltinInst(const std::vector<int64_t> &allTypes) const
187 {
188 return FindValue(builtinInst_, allTypes, PRIMITIVETYPE_ANY);
189 }
190
SetBuiltinInst(const std::vector<int64_t> & allTypes,int64_t instIndex)191 void TypeRecorder::SetBuiltinInst(const std::vector<int64_t> &allTypes, int64_t instIndex)
192 {
193 builtinInst_[allTypes] = instIndex;
194 ASSERT(GetBuiltinInst(allTypes) == instIndex);
195 }
196
GetGenericInst(const std::vector<int64_t> & allTypes) const197 int64_t TypeRecorder::GetGenericInst(const std::vector<int64_t> &allTypes) const
198 {
199 return FindValue(genericInst_, allTypes, PRIMITIVETYPE_ANY);
200 }
201
SetGenericInst(const std::vector<int64_t> & allTypes,int64_t instIndex)202 void TypeRecorder::SetGenericInst(const std::vector<int64_t> &allTypes, int64_t instIndex)
203 {
204 genericInst_[allTypes] = instIndex;
205 ASSERT(GetGenericInst(allTypes) == instIndex);
206 }
207
GetIndexSig(int64_t refIndex) const208 int64_t TypeRecorder::GetIndexSig(int64_t refIndex) const
209 {
210 return FindValue(indexSig_, refIndex, PRIMITIVETYPE_ANY);
211 }
212
SetIndexSig(int64_t refIndex,int64_t indexSigIndex)213 void TypeRecorder::SetIndexSig(int64_t refIndex, int64_t indexSigIndex)
214 {
215 indexSig_[refIndex] = indexSigIndex;
216 ASSERT(GetIndexSig(refIndex) == indexSigIndex);
217 }
218
GetClassInst(int64_t classIndex) const219 int64_t TypeRecorder::GetClassInst(int64_t classIndex) const
220 {
221 return FindValue(classInst_, classIndex, PRIMITIVETYPE_ANY);
222 }
223
SetClassInst(int64_t classIndex,int64_t instIndex)224 void TypeRecorder::SetClassInst(int64_t classIndex, int64_t instIndex)
225 {
226 if (classIndex == PRIMITIVETYPE_ANY) {
227 return;
228 }
229 classInst_[classIndex] = instIndex;
230 ASSERT(GetClassInst(classIndex) == instIndex);
231 }
232
GetClassType(int64_t instIndex) const233 int64_t TypeRecorder::GetClassType(int64_t instIndex) const
234 {
235 // Here we always return the original type rather than instance type
236 // If `instIndex` is not in `classType_`, it means `instIndex` does not come from new instance
237 return FindValue(classType_, instIndex, instIndex);
238 }
239
SetClassType(int64_t instIndex,int64_t classIndex)240 void TypeRecorder::SetClassType(int64_t instIndex, int64_t classIndex)
241 {
242 if (instIndex == PRIMITIVETYPE_ANY) {
243 return;
244 }
245 classType_[instIndex] = classIndex;
246 ASSERT(GetClassType(instIndex) == classIndex);
247 }
248
GetArrayType(int64_t contentIndex) const249 int64_t TypeRecorder::GetArrayType(int64_t contentIndex) const
250 {
251 return FindValue(arrayType_, contentIndex, PRIMITIVETYPE_ANY);
252 }
253
SetArrayType(int64_t contentIndex,int64_t arrayIndex)254 void TypeRecorder::SetArrayType(int64_t contentIndex, int64_t arrayIndex)
255 {
256 arrayType_[contentIndex] = arrayIndex;
257 ASSERT(GetArrayType(contentIndex) == arrayIndex);
258 }
259
GetUnionType(const std::string & unionStr) const260 int64_t TypeRecorder::GetUnionType(const std::string &unionStr) const
261 {
262 return FindValue(unionType_, unionStr, PRIMITIVETYPE_ANY);
263 }
264
SetUnionType(const std::string & unionStr,int64_t unionIndex)265 void TypeRecorder::SetUnionType(const std::string &unionStr, int64_t unionIndex)
266 {
267 unionType_[unionStr] = unionIndex;
268 ASSERT(GetUnionType(unionStr) == unionIndex);
269 }
270
GetObjectType(const std::string & objectStr) const271 int64_t TypeRecorder::GetObjectType(const std::string &objectStr) const
272 {
273 return FindValue(objectType_, objectStr, PRIMITIVETYPE_ANY);
274 }
275
SetObjectType(const std::string & objectStr,int64_t objectIndex)276 void TypeRecorder::SetObjectType(const std::string &objectStr, int64_t objectIndex)
277 {
278 objectType_[objectStr] = objectIndex;
279 ASSERT(GetObjectType(objectStr) == objectIndex);
280 }
281
GetFunctionType(const std::string & functionStr) const282 int64_t TypeRecorder::GetFunctionType(const std::string &functionStr) const
283 {
284 return FindValue(functionType_, functionStr, PRIMITIVETYPE_ANY);
285 }
286
SetFunctionType(const std::string & functionStr,int64_t functionIndex)287 void TypeRecorder::SetFunctionType(const std::string &functionStr, int64_t functionIndex)
288 {
289 functionType_[functionStr] = functionIndex;
290 ASSERT(GetFunctionType(functionStr) == functionIndex);
291 }
292
GetExportType(const std::string & exportStr) const293 int64_t TypeRecorder::GetExportType(const std::string &exportStr) const
294 {
295 return FindValue(exportType_, exportStr, PRIMITIVETYPE_ANY);
296 }
297
SetExportType(const std::string & exportStr,int64_t exportIndex)298 void TypeRecorder::SetExportType(const std::string &exportStr, int64_t exportIndex)
299 {
300 exportType_[exportStr] = exportIndex;
301 ASSERT(GetExportType(exportStr) == exportIndex);
302 }
303
GetDeclareType(const std::string & declareStr) const304 int64_t TypeRecorder::GetDeclareType(const std::string &declareStr) const
305 {
306 return FindValue(declareType_, declareStr, PRIMITIVETYPE_ANY);
307 }
308
SetDeclareType(const std::string & declareStr,int64_t declareIndex)309 void TypeRecorder::SetDeclareType(const std::string &declareStr, int64_t declareIndex)
310 {
311 declareType_[declareStr] = declareIndex;
312 ASSERT(GetDeclareType(declareStr) == declareIndex);
313 }
314
GetNamespaceType(const std::string & namespaceStr) const315 int64_t TypeRecorder::GetNamespaceType(const std::string &namespaceStr) const
316 {
317 return FindValue(namespaceType_, namespaceStr, PRIMITIVETYPE_ANY);
318 }
319
SetNamespaceType(const std::string & namespaceStr,int64_t namespaceIndex)320 void TypeRecorder::SetNamespaceType(const std::string &namespaceStr, int64_t namespaceIndex)
321 {
322 namespaceType_[namespaceStr] = namespaceIndex;
323 ASSERT(GetNamespaceType(namespaceStr) == namespaceIndex);
324 }
325
GetNamespacePath(const std::string & namespaceStr) const326 std::string TypeRecorder::GetNamespacePath(const std::string &namespaceStr) const
327 {
328 return FindValue(namespacePath_, namespaceStr, std::string());
329 }
330
SetNamespacePath(const std::string & namespaceStr,const std::string & filePath)331 void TypeRecorder::SetNamespacePath(const std::string &namespaceStr, const std::string &filePath)
332 {
333 namespacePath_[namespaceStr] = filePath;
334 ASSERT(GetNamespacePath(namespaceStr) == filePath);
335 }
336
GetAnonymousReExport() const337 const std::set<util::StringView> &TypeRecorder::GetAnonymousReExport() const
338 {
339 return anonymousReExport_;
340 }
341
AddAnonymousReExport(const util::StringView & reExportStr)342 void TypeRecorder::AddAnonymousReExport(const util::StringView &reExportStr)
343 {
344 anonymousReExport_.insert(reExportStr);
345 }
346
Dump(const parser::Program * program) const347 ALWAYS_INLINE void TypeRecorder::Dump(const parser::Program *program) const
348 {
349 #ifndef NDEBUG
350 std::cout << "========== TypeExtractor ==========" << std::endl;
351 std::cout << "---------- userType_ ----------" << std::endl;
352 std::stringstream ss;
353 for (const auto &t : userType_) {
354 ss << t << " | ";
355 }
356 std::cout << ss.str() << std::endl;
357 std::cout << "---------- nodeTypeIndex_ ----------" << std::endl;
358 for (const auto &t : nodeTypeIndex_) {
359 ir::AstDumper dumper(t.first);
360 std::cout << dumper.Str() << " : " << t.second << std::endl;
361 }
362 std::cout << "---------- variableTypeIndex_ ----------" << std::endl;
363 for (const auto &t : variableTypeIndex_) {
364 std::cout << t.first->Name() << " : " << t.second << std::endl;
365 }
366 std::cout << "---------- builtinInst_ ----------" << std::endl;
367 for (const auto &t : builtinInst_) {
368 for (const auto &p : t.first) {
369 std::cout << p << " ";
370 }
371 std::cout << ": " << t.second << std::endl;
372 }
373 std::cout << "---------- genericInst_ ----------" << std::endl;
374 for (const auto &t : genericInst_) {
375 for (const auto &p : t.first) {
376 std::cout << p << " ";
377 }
378 std::cout << ": " << t.second << std::endl;
379 }
380
381 auto fn = [](const auto &map) {
382 for (const auto &t : map) {
383 std::cout << t.first << " : " << t.second << std::endl;
384 }
385 };
386 std::cout << "---------- indexSig_ ----------" << std::endl;
387 std::cout << "---- ref ---- | ---- indexSig ----" << std::endl;
388 fn(indexSig_);
389 std::cout << "---------- classInst_ ----------" << std::endl;
390 std::cout << "---- class ---- | ---- inst ----" << std::endl;
391 fn(classInst_);
392 std::cout << "---------- classType_ ----------" << std::endl;
393 std::cout << "---- inst ---- | ---- class ----" << std::endl;
394 fn(classType_);
395 std::cout << "---------- arrayType_ ----------" << std::endl;
396 fn(arrayType_);
397 std::cout << "---------- unionType_ ----------" << std::endl;
398 fn(unionType_);
399 std::cout << "---------- objectType_ ----------" << std::endl;
400 fn(objectType_);
401 std::cout << "---------- functionType_ ----------" << std::endl;
402 fn(functionType_);
403 std::cout << "---------- exportType_ ----------" << std::endl;
404 fn(exportType_);
405 std::cout << "---------- declareType_ ----------" << std::endl;
406 fn(declareType_);
407 std::cout << "---------- namespaceType_ ----------" << std::endl;
408 fn(namespaceType_);
409 std::cout << "---------- namespacePath_ ----------" << std::endl;
410 fn(namespacePath_);
411 std::cout << "---------- anonymousReExport_ ----------" << std::endl;
412 for (const auto &t : anonymousReExport_) {
413 std::cout << std::string(t) << std::endl;
414 }
415 std::cout << "========== TypeExtractor ==========" << std::endl;
416 #endif
417 }
418
419 } // namespace panda::es2panda::extractor
420