OLD | NEW |
| (Empty) |
1 // Copyright 2012 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "src/v8.h" | |
6 | |
7 #include "src/ast.h" | |
8 #include "src/ast-numbering.h" | |
9 #include "src/compiler.h" | |
10 #include "src/scopes.h" | |
11 | |
12 namespace v8 { | |
13 namespace internal { | |
14 | |
15 | |
16 class AstNumberingVisitor FINAL : public AstVisitor { | |
17 public: | |
18 explicit AstNumberingVisitor(Zone* zone) | |
19 : AstVisitor(), next_id_(BailoutId::FirstUsable().ToInt()) { | |
20 InitializeAstVisitor(zone); | |
21 } | |
22 | |
23 void Renumber(FunctionLiteral* node); | |
24 | |
25 private: | |
26 // AST node visitor interface. | |
27 #define DEFINE_VISIT(type) virtual void Visit##type(type* node); | |
28 AST_NODE_LIST(DEFINE_VISIT) | |
29 #undef DEFINE_VISIT | |
30 | |
31 void VisitStatements(ZoneList<Statement*>* statements); | |
32 void VisitDeclarations(ZoneList<Declaration*>* declarations); | |
33 void VisitArguments(ZoneList<Expression*>* arguments); | |
34 void VisitObjectLiteralProperty(ObjectLiteralProperty* property); | |
35 | |
36 int ReserveIdRange(int n) { | |
37 int tmp = next_id_; | |
38 next_id_ += n; | |
39 return tmp; | |
40 } | |
41 | |
42 int next_id_; | |
43 | |
44 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | |
45 DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor); | |
46 }; | |
47 | |
48 | |
49 void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) { | |
50 VisitVariableProxy(node->proxy()); | |
51 } | |
52 | |
53 | |
54 void AstNumberingVisitor::VisitExportDeclaration(ExportDeclaration* node) { | |
55 VisitVariableProxy(node->proxy()); | |
56 } | |
57 | |
58 | |
59 void AstNumberingVisitor::VisitModuleUrl(ModuleUrl* node) {} | |
60 | |
61 | |
62 void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {} | |
63 | |
64 | |
65 void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {} | |
66 | |
67 | |
68 void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {} | |
69 | |
70 | |
71 void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) { | |
72 node->set_base_id(ReserveIdRange(DebuggerStatement::num_ids())); | |
73 } | |
74 | |
75 | |
76 void AstNumberingVisitor::VisitNativeFunctionLiteral( | |
77 NativeFunctionLiteral* node) { | |
78 node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids())); | |
79 } | |
80 | |
81 | |
82 void AstNumberingVisitor::VisitLiteral(Literal* node) { | |
83 node->set_base_id(ReserveIdRange(Literal::num_ids())); | |
84 } | |
85 | |
86 | |
87 void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) { | |
88 node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids())); | |
89 } | |
90 | |
91 | |
92 void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) { | |
93 node->set_base_id(ReserveIdRange(VariableProxy::num_ids())); | |
94 } | |
95 | |
96 | |
97 void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) { | |
98 node->set_base_id(ReserveIdRange(ThisFunction::num_ids())); | |
99 } | |
100 | |
101 | |
102 void AstNumberingVisitor::VisitSuperReference(SuperReference* node) { | |
103 node->set_base_id(ReserveIdRange(SuperReference::num_ids())); | |
104 Visit(node->this_var()); | |
105 } | |
106 | |
107 | |
108 void AstNumberingVisitor::VisitModuleDeclaration(ModuleDeclaration* node) { | |
109 VisitVariableProxy(node->proxy()); | |
110 Visit(node->module()); | |
111 } | |
112 | |
113 | |
114 void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) { | |
115 VisitVariableProxy(node->proxy()); | |
116 Visit(node->module()); | |
117 } | |
118 | |
119 | |
120 void AstNumberingVisitor::VisitModuleVariable(ModuleVariable* node) { | |
121 Visit(node->proxy()); | |
122 } | |
123 | |
124 | |
125 void AstNumberingVisitor::VisitModulePath(ModulePath* node) { | |
126 Visit(node->module()); | |
127 } | |
128 | |
129 | |
130 void AstNumberingVisitor::VisitModuleStatement(ModuleStatement* node) { | |
131 Visit(node->body()); | |
132 } | |
133 | |
134 | |
135 void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) { | |
136 Visit(node->expression()); | |
137 } | |
138 | |
139 | |
140 void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) { | |
141 Visit(node->expression()); | |
142 } | |
143 | |
144 | |
145 void AstNumberingVisitor::VisitYield(Yield* node) { | |
146 node->set_base_id(ReserveIdRange(Yield::num_ids())); | |
147 Visit(node->generator_object()); | |
148 Visit(node->expression()); | |
149 } | |
150 | |
151 | |
152 void AstNumberingVisitor::VisitThrow(Throw* node) { | |
153 node->set_base_id(ReserveIdRange(Throw::num_ids())); | |
154 Visit(node->exception()); | |
155 } | |
156 | |
157 | |
158 void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) { | |
159 node->set_base_id(ReserveIdRange(UnaryOperation::num_ids())); | |
160 Visit(node->expression()); | |
161 } | |
162 | |
163 | |
164 void AstNumberingVisitor::VisitCountOperation(CountOperation* node) { | |
165 node->set_base_id(ReserveIdRange(CountOperation::num_ids())); | |
166 Visit(node->expression()); | |
167 } | |
168 | |
169 | |
170 void AstNumberingVisitor::VisitBlock(Block* node) { | |
171 node->set_base_id(ReserveIdRange(Block::num_ids())); | |
172 if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations()); | |
173 VisitStatements(node->statements()); | |
174 } | |
175 | |
176 | |
177 void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) { | |
178 VisitVariableProxy(node->proxy()); | |
179 VisitFunctionLiteral(node->fun()); | |
180 } | |
181 | |
182 | |
183 void AstNumberingVisitor::VisitModuleLiteral(ModuleLiteral* node) { | |
184 VisitBlock(node->body()); | |
185 } | |
186 | |
187 | |
188 void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) { | |
189 node->set_base_id(ReserveIdRange(CallRuntime::num_ids())); | |
190 VisitArguments(node->arguments()); | |
191 } | |
192 | |
193 | |
194 void AstNumberingVisitor::VisitWithStatement(WithStatement* node) { | |
195 Visit(node->expression()); | |
196 Visit(node->statement()); | |
197 } | |
198 | |
199 | |
200 void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) { | |
201 node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids())); | |
202 Visit(node->body()); | |
203 Visit(node->cond()); | |
204 } | |
205 | |
206 | |
207 void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) { | |
208 node->set_base_id(ReserveIdRange(WhileStatement::num_ids())); | |
209 Visit(node->cond()); | |
210 Visit(node->body()); | |
211 } | |
212 | |
213 | |
214 void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) { | |
215 Visit(node->try_block()); | |
216 Visit(node->catch_block()); | |
217 } | |
218 | |
219 | |
220 void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) { | |
221 Visit(node->try_block()); | |
222 Visit(node->finally_block()); | |
223 } | |
224 | |
225 | |
226 void AstNumberingVisitor::VisitProperty(Property* node) { | |
227 node->set_base_id(ReserveIdRange(Property::num_ids())); | |
228 Visit(node->key()); | |
229 Visit(node->obj()); | |
230 } | |
231 | |
232 | |
233 void AstNumberingVisitor::VisitAssignment(Assignment* node) { | |
234 node->set_base_id(ReserveIdRange(Assignment::num_ids())); | |
235 if (node->is_compound()) VisitBinaryOperation(node->binary_operation()); | |
236 Visit(node->target()); | |
237 Visit(node->value()); | |
238 } | |
239 | |
240 | |
241 void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) { | |
242 node->set_base_id(ReserveIdRange(BinaryOperation::num_ids())); | |
243 Visit(node->left()); | |
244 Visit(node->right()); | |
245 } | |
246 | |
247 | |
248 void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) { | |
249 node->set_base_id(ReserveIdRange(CompareOperation::num_ids())); | |
250 Visit(node->left()); | |
251 Visit(node->right()); | |
252 } | |
253 | |
254 | |
255 void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) { | |
256 node->set_base_id(ReserveIdRange(ForInStatement::num_ids())); | |
257 Visit(node->each()); | |
258 Visit(node->enumerable()); | |
259 Visit(node->body()); | |
260 } | |
261 | |
262 | |
263 void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) { | |
264 node->set_base_id(ReserveIdRange(ForOfStatement::num_ids())); | |
265 Visit(node->assign_iterator()); | |
266 Visit(node->next_result()); | |
267 Visit(node->result_done()); | |
268 Visit(node->assign_each()); | |
269 Visit(node->body()); | |
270 } | |
271 | |
272 | |
273 void AstNumberingVisitor::VisitConditional(Conditional* node) { | |
274 node->set_base_id(ReserveIdRange(Conditional::num_ids())); | |
275 Visit(node->condition()); | |
276 Visit(node->then_expression()); | |
277 Visit(node->else_expression()); | |
278 } | |
279 | |
280 | |
281 void AstNumberingVisitor::VisitIfStatement(IfStatement* node) { | |
282 node->set_base_id(ReserveIdRange(IfStatement::num_ids())); | |
283 Visit(node->condition()); | |
284 Visit(node->then_statement()); | |
285 if (node->HasElseStatement()) { | |
286 Visit(node->else_statement()); | |
287 } | |
288 } | |
289 | |
290 | |
291 void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) { | |
292 node->set_base_id(ReserveIdRange(SwitchStatement::num_ids())); | |
293 Visit(node->tag()); | |
294 ZoneList<CaseClause*>* cases = node->cases(); | |
295 for (int i = 0; i < cases->length(); i++) { | |
296 VisitCaseClause(cases->at(i)); | |
297 } | |
298 } | |
299 | |
300 | |
301 void AstNumberingVisitor::VisitCaseClause(CaseClause* node) { | |
302 node->set_base_id(ReserveIdRange(CaseClause::num_ids())); | |
303 if (!node->is_default()) Visit(node->label()); | |
304 VisitStatements(node->statements()); | |
305 } | |
306 | |
307 | |
308 void AstNumberingVisitor::VisitForStatement(ForStatement* node) { | |
309 node->set_base_id(ReserveIdRange(ForStatement::num_ids())); | |
310 if (node->init() != NULL) Visit(node->init()); | |
311 if (node->cond() != NULL) Visit(node->cond()); | |
312 if (node->next() != NULL) Visit(node->next()); | |
313 Visit(node->body()); | |
314 } | |
315 | |
316 | |
317 void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) { | |
318 node->set_base_id(ReserveIdRange(ClassLiteral::num_ids())); | |
319 if (node->extends()) Visit(node->extends()); | |
320 if (node->constructor()) Visit(node->constructor()); | |
321 for (int i = 0; i < node->properties()->length(); i++) { | |
322 VisitObjectLiteralProperty(node->properties()->at(i)); | |
323 } | |
324 } | |
325 | |
326 | |
327 void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) { | |
328 node->set_base_id(ReserveIdRange(ObjectLiteral::num_ids())); | |
329 for (int i = 0; i < node->properties()->length(); i++) { | |
330 VisitObjectLiteralProperty(node->properties()->at(i)); | |
331 } | |
332 } | |
333 | |
334 | |
335 void AstNumberingVisitor::VisitObjectLiteralProperty( | |
336 ObjectLiteralProperty* node) { | |
337 Visit(node->key()); | |
338 Visit(node->value()); | |
339 } | |
340 | |
341 | |
342 void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) { | |
343 node->set_base_id(ReserveIdRange(node->num_ids())); | |
344 for (int i = 0; i < node->values()->length(); i++) { | |
345 Visit(node->values()->at(i)); | |
346 } | |
347 } | |
348 | |
349 | |
350 void AstNumberingVisitor::VisitCall(Call* node) { | |
351 node->set_base_id(ReserveIdRange(Call::num_ids())); | |
352 Visit(node->expression()); | |
353 VisitArguments(node->arguments()); | |
354 } | |
355 | |
356 | |
357 void AstNumberingVisitor::VisitCallNew(CallNew* node) { | |
358 node->set_base_id(ReserveIdRange(CallNew::num_ids())); | |
359 Visit(node->expression()); | |
360 VisitArguments(node->arguments()); | |
361 } | |
362 | |
363 | |
364 void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) { | |
365 if (statements == NULL) return; | |
366 for (int i = 0; i < statements->length(); i++) { | |
367 Visit(statements->at(i)); | |
368 } | |
369 } | |
370 | |
371 | |
372 void AstNumberingVisitor::VisitDeclarations( | |
373 ZoneList<Declaration*>* declarations) { | |
374 for (int i = 0; i < declarations->length(); i++) { | |
375 Visit(declarations->at(i)); | |
376 } | |
377 } | |
378 | |
379 | |
380 void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) { | |
381 for (int i = 0; i < arguments->length(); i++) { | |
382 Visit(arguments->at(i)); | |
383 } | |
384 } | |
385 | |
386 | |
387 void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) { | |
388 node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids())); | |
389 // We don't recurse into the declarations or body of the function literal: | |
390 // you have to separately Renumber() each FunctionLiteral that you compile. | |
391 } | |
392 | |
393 | |
394 void AstNumberingVisitor::Renumber(FunctionLiteral* node) { | |
395 if (node->scope()->HasIllegalRedeclaration()) { | |
396 node->scope()->VisitIllegalRedeclaration(this); | |
397 return; | |
398 } | |
399 | |
400 Scope* scope = node->scope(); | |
401 VisitDeclarations(scope->declarations()); | |
402 if (scope->is_function_scope() && scope->function() != NULL) { | |
403 // Visit the name of the named function expression. | |
404 Visit(scope->function()); | |
405 } | |
406 VisitStatements(node->body()); | |
407 } | |
408 | |
409 | |
410 bool AstNumbering::Renumber(FunctionLiteral* function, Zone* zone) { | |
411 AstNumberingVisitor visitor(zone); | |
412 visitor.Renumber(function); | |
413 return !visitor.HasStackOverflow(); | |
414 } | |
415 } | |
416 } // namespace v8::internal | |
OLD | NEW |