• 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 
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