• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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