Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/prettyprinter.cc

Issue 1481613002: Create ast/ and parsing/ subdirectories and move appropriate files (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/prettyprinter.h ('k') | src/profiler/profile-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/prettyprinter.h"
6
7 #include <stdarg.h>
8
9 #include "src/ast-value-factory.h"
10 #include "src/base/platform/platform.h"
11 #include "src/scopes.h"
12
13 namespace v8 {
14 namespace internal {
15
16 CallPrinter::CallPrinter(Isolate* isolate) {
17 output_ = NULL;
18 size_ = 0;
19 pos_ = 0;
20 position_ = 0;
21 found_ = false;
22 done_ = false;
23 InitializeAstVisitor(isolate);
24 }
25
26
27 CallPrinter::~CallPrinter() { DeleteArray(output_); }
28
29
30 const char* CallPrinter::Print(FunctionLiteral* program, int position) {
31 Init();
32 position_ = position;
33 Find(program);
34 return output_;
35 }
36
37
38 void CallPrinter::Find(AstNode* node, bool print) {
39 if (done_) return;
40 if (found_) {
41 if (print) {
42 int start = pos_;
43 Visit(node);
44 if (start != pos_) return;
45 }
46 Print("(intermediate value)");
47 } else {
48 Visit(node);
49 }
50 }
51
52
53 void CallPrinter::Init() {
54 if (size_ == 0) {
55 DCHECK(output_ == NULL);
56 const int initial_size = 256;
57 output_ = NewArray<char>(initial_size);
58 size_ = initial_size;
59 }
60 output_[0] = '\0';
61 pos_ = 0;
62 }
63
64
65 void CallPrinter::Print(const char* format, ...) {
66 if (!found_ || done_) return;
67 for (;;) {
68 va_list arguments;
69 va_start(arguments, format);
70 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, format, arguments);
71 va_end(arguments);
72
73 if (n >= 0) {
74 // there was enough space - we are done
75 pos_ += n;
76 return;
77 } else {
78 // there was not enough space - allocate more and try again
79 const int slack = 32;
80 int new_size = size_ + (size_ >> 1) + slack;
81 char* new_output = NewArray<char>(new_size);
82 MemCopy(new_output, output_, pos_);
83 DeleteArray(output_);
84 output_ = new_output;
85 size_ = new_size;
86 }
87 }
88 }
89
90
91 void CallPrinter::VisitBlock(Block* node) {
92 FindStatements(node->statements());
93 }
94
95
96 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
97
98
99 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
100
101
102 void CallPrinter::VisitImportDeclaration(ImportDeclaration* node) {
103 }
104
105
106 void CallPrinter::VisitExportDeclaration(ExportDeclaration* node) {}
107
108
109 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
110 Find(node->expression());
111 }
112
113
114 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
115
116
117 void CallPrinter::VisitSloppyBlockFunctionStatement(
118 SloppyBlockFunctionStatement* node) {
119 Find(node->statement());
120 }
121
122
123 void CallPrinter::VisitIfStatement(IfStatement* node) {
124 Find(node->condition());
125 Find(node->then_statement());
126 if (node->HasElseStatement()) {
127 Find(node->else_statement());
128 }
129 }
130
131
132 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
133
134
135 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
136
137
138 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
139 Find(node->expression());
140 }
141
142
143 void CallPrinter::VisitWithStatement(WithStatement* node) {
144 Find(node->expression());
145 Find(node->statement());
146 }
147
148
149 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
150 Find(node->tag());
151 ZoneList<CaseClause*>* cases = node->cases();
152 for (int i = 0; i < cases->length(); i++) Find(cases->at(i));
153 }
154
155
156 void CallPrinter::VisitCaseClause(CaseClause* clause) {
157 if (!clause->is_default()) {
158 Find(clause->label());
159 }
160 FindStatements(clause->statements());
161 }
162
163
164 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
165 Find(node->body());
166 Find(node->cond());
167 }
168
169
170 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
171 Find(node->cond());
172 Find(node->body());
173 }
174
175
176 void CallPrinter::VisitForStatement(ForStatement* node) {
177 if (node->init() != NULL) {
178 Find(node->init());
179 }
180 if (node->cond() != NULL) Find(node->cond());
181 if (node->next() != NULL) Find(node->next());
182 Find(node->body());
183 }
184
185
186 void CallPrinter::VisitForInStatement(ForInStatement* node) {
187 Find(node->each());
188 Find(node->enumerable());
189 Find(node->body());
190 }
191
192
193 void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
194 Find(node->each());
195 Find(node->iterable());
196 Find(node->body());
197 }
198
199
200 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
201 Find(node->try_block());
202 Find(node->catch_block());
203 }
204
205
206 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
207 Find(node->try_block());
208 Find(node->finally_block());
209 }
210
211
212 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
213
214
215 void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
216 FindStatements(node->body());
217 }
218
219
220 void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
221 if (node->extends()) Find(node->extends());
222 for (int i = 0; i < node->properties()->length(); i++) {
223 Find(node->properties()->at(i)->value());
224 }
225 }
226
227
228 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
229
230
231 void CallPrinter::VisitDoExpression(DoExpression* node) { Find(node->block()); }
232
233
234 void CallPrinter::VisitConditional(Conditional* node) {
235 Find(node->condition());
236 Find(node->then_expression());
237 Find(node->else_expression());
238 }
239
240
241 void CallPrinter::VisitLiteral(Literal* node) {
242 PrintLiteral(node->value(), true);
243 }
244
245
246 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
247 Print("/");
248 PrintLiteral(node->pattern(), false);
249 Print("/");
250 if (node->flags() & RegExp::kGlobal) Print("g");
251 if (node->flags() & RegExp::kIgnoreCase) Print("i");
252 if (node->flags() & RegExp::kMultiline) Print("m");
253 if (node->flags() & RegExp::kUnicode) Print("u");
254 if (node->flags() & RegExp::kSticky) Print("y");
255 }
256
257
258 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
259 for (int i = 0; i < node->properties()->length(); i++) {
260 Find(node->properties()->at(i)->value());
261 }
262 }
263
264
265 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
266 Print("[");
267 for (int i = 0; i < node->values()->length(); i++) {
268 if (i != 0) Print(",");
269 Find(node->values()->at(i), true);
270 }
271 Print("]");
272 }
273
274
275 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
276 PrintLiteral(node->name(), false);
277 }
278
279
280 void CallPrinter::VisitAssignment(Assignment* node) {
281 Find(node->target());
282 Find(node->value());
283 }
284
285
286 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
287
288
289 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
290
291
292 void CallPrinter::VisitProperty(Property* node) {
293 Expression* key = node->key();
294 Literal* literal = key->AsLiteral();
295 if (literal != NULL && literal->value()->IsInternalizedString()) {
296 Find(node->obj(), true);
297 Print(".");
298 PrintLiteral(literal->value(), false);
299 } else {
300 Find(node->obj(), true);
301 Print("[");
302 Find(key, true);
303 Print("]");
304 }
305 }
306
307
308 void CallPrinter::VisitCall(Call* node) {
309 bool was_found = !found_ && node->position() == position_;
310 if (was_found) found_ = true;
311 Find(node->expression(), true);
312 if (!was_found) Print("(...)");
313 FindArguments(node->arguments());
314 if (was_found) done_ = true;
315 }
316
317
318 void CallPrinter::VisitCallNew(CallNew* node) {
319 bool was_found = !found_ && node->position() == position_;
320 if (was_found) found_ = true;
321 Find(node->expression(), was_found);
322 FindArguments(node->arguments());
323 if (was_found) done_ = true;
324 }
325
326
327 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
328 if (!node->is_jsruntime() &&
329 node->function() ==
330 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper)) {
331 found_ = true;
332 Print("super");
333 done_ = true;
334 return;
335 }
336 FindArguments(node->arguments());
337 }
338
339
340 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
341 Token::Value op = node->op();
342 bool needsSpace =
343 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
344 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
345 Find(node->expression(), true);
346 Print(")");
347 }
348
349
350 void CallPrinter::VisitCountOperation(CountOperation* node) {
351 Print("(");
352 if (node->is_prefix()) Print("%s", Token::String(node->op()));
353 Find(node->expression(), true);
354 if (node->is_postfix()) Print("%s", Token::String(node->op()));
355 Print(")");
356 }
357
358
359 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
360 Print("(");
361 Find(node->left(), true);
362 Print(" %s ", Token::String(node->op()));
363 Find(node->right(), true);
364 Print(")");
365 }
366
367
368 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
369 Print("(");
370 Find(node->left(), true);
371 Print(" %s ", Token::String(node->op()));
372 Find(node->right(), true);
373 Print(")");
374 }
375
376
377 void CallPrinter::VisitSpread(Spread* node) {
378 Print("(...");
379 Find(node->expression(), true);
380 Print(")");
381 }
382
383
384 void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
385 UNREACHABLE();
386 }
387
388
389 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
390
391
392 void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
393
394
395 void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
396 Print("super");
397 }
398
399
400 void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
401 if (statements == NULL) return;
402 for (int i = 0; i < statements->length(); i++) {
403 Find(statements->at(i));
404 }
405 }
406
407
408 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) {
409 if (found_) return;
410 for (int i = 0; i < arguments->length(); i++) {
411 Find(arguments->at(i));
412 }
413 }
414
415
416 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
417 Object* object = *value;
418 if (object->IsString()) {
419 String* string = String::cast(object);
420 if (quote) Print("\"");
421 for (int i = 0; i < string->length(); i++) {
422 Print("%c", string->Get(i));
423 }
424 if (quote) Print("\"");
425 } else if (object->IsNull()) {
426 Print("null");
427 } else if (object->IsTrue()) {
428 Print("true");
429 } else if (object->IsFalse()) {
430 Print("false");
431 } else if (object->IsUndefined()) {
432 Print("undefined");
433 } else if (object->IsNumber()) {
434 Print("%g", object->Number());
435 }
436 }
437
438
439 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
440 PrintLiteral(value->string(), quote);
441 }
442
443
444 //-----------------------------------------------------------------------------
445
446
447 #ifdef DEBUG
448
449 // A helper for ast nodes that use FeedbackVectorSlots.
450 static int FormatSlotNode(Vector<char>* buf, Expression* node,
451 const char* node_name, FeedbackVectorSlot slot) {
452 int pos = SNPrintF(*buf, "%s", node_name);
453 if (!slot.IsInvalid()) {
454 pos = SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt());
455 }
456 return pos;
457 }
458
459
460 PrettyPrinter::PrettyPrinter(Isolate* isolate) {
461 output_ = NULL;
462 size_ = 0;
463 pos_ = 0;
464 InitializeAstVisitor(isolate);
465 }
466
467
468 PrettyPrinter::~PrettyPrinter() {
469 DeleteArray(output_);
470 }
471
472
473 void PrettyPrinter::VisitBlock(Block* node) {
474 if (!node->ignore_completion_value()) Print("{ ");
475 PrintStatements(node->statements());
476 if (node->statements()->length() > 0) Print(" ");
477 if (!node->ignore_completion_value()) Print("}");
478 }
479
480
481 void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
482 Print("var ");
483 PrintLiteral(node->proxy()->name(), false);
484 Print(";");
485 }
486
487
488 void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
489 Print("function ");
490 PrintLiteral(node->proxy()->name(), false);
491 Print(" = ");
492 PrintFunctionLiteral(node->fun());
493 Print(";");
494 }
495
496
497 void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
498 Print("import ");
499 PrintLiteral(node->proxy()->name(), false);
500 Print(" from ");
501 PrintLiteral(node->module_specifier()->string(), true);
502 Print(";");
503 }
504
505
506 void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
507 Print("export ");
508 PrintLiteral(node->proxy()->name(), false);
509 Print(";");
510 }
511
512
513 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
514 Visit(node->expression());
515 Print(";");
516 }
517
518
519 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
520 Print(";");
521 }
522
523
524 void PrettyPrinter::VisitSloppyBlockFunctionStatement(
525 SloppyBlockFunctionStatement* node) {
526 Visit(node->statement());
527 }
528
529
530 void PrettyPrinter::VisitIfStatement(IfStatement* node) {
531 Print("if (");
532 Visit(node->condition());
533 Print(") ");
534 Visit(node->then_statement());
535 if (node->HasElseStatement()) {
536 Print(" else ");
537 Visit(node->else_statement());
538 }
539 }
540
541
542 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
543 Print("continue");
544 ZoneList<const AstRawString*>* labels = node->target()->labels();
545 if (labels != NULL) {
546 Print(" ");
547 DCHECK(labels->length() > 0); // guaranteed to have at least one entry
548 PrintLiteral(labels->at(0), false); // any label from the list is fine
549 }
550 Print(";");
551 }
552
553
554 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
555 Print("break");
556 ZoneList<const AstRawString*>* labels = node->target()->labels();
557 if (labels != NULL) {
558 Print(" ");
559 DCHECK(labels->length() > 0); // guaranteed to have at least one entry
560 PrintLiteral(labels->at(0), false); // any label from the list is fine
561 }
562 Print(";");
563 }
564
565
566 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
567 Print("return ");
568 Visit(node->expression());
569 Print(";");
570 }
571
572
573 void PrettyPrinter::VisitWithStatement(WithStatement* node) {
574 Print("with (");
575 Visit(node->expression());
576 Print(") ");
577 Visit(node->statement());
578 }
579
580
581 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
582 PrintLabels(node->labels());
583 Print("switch (");
584 Visit(node->tag());
585 Print(") { ");
586 ZoneList<CaseClause*>* cases = node->cases();
587 for (int i = 0; i < cases->length(); i++)
588 Visit(cases->at(i));
589 Print("}");
590 }
591
592
593 void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
594 if (clause->is_default()) {
595 Print("default");
596 } else {
597 Print("case ");
598 Visit(clause->label());
599 }
600 Print(": ");
601 PrintStatements(clause->statements());
602 if (clause->statements()->length() > 0)
603 Print(" ");
604 }
605
606
607 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
608 PrintLabels(node->labels());
609 Print("do ");
610 Visit(node->body());
611 Print(" while (");
612 Visit(node->cond());
613 Print(");");
614 }
615
616
617 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
618 PrintLabels(node->labels());
619 Print("while (");
620 Visit(node->cond());
621 Print(") ");
622 Visit(node->body());
623 }
624
625
626 void PrettyPrinter::VisitForStatement(ForStatement* node) {
627 PrintLabels(node->labels());
628 Print("for (");
629 if (node->init() != NULL) {
630 Visit(node->init());
631 Print(" ");
632 } else {
633 Print("; ");
634 }
635 if (node->cond() != NULL) Visit(node->cond());
636 Print("; ");
637 if (node->next() != NULL) {
638 Visit(node->next()); // prints extra ';', unfortunately
639 // to fix: should use Expression for next
640 }
641 Print(") ");
642 Visit(node->body());
643 }
644
645
646 void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
647 PrintLabels(node->labels());
648 Print("for (");
649 Visit(node->each());
650 Print(" in ");
651 Visit(node->enumerable());
652 Print(") ");
653 Visit(node->body());
654 }
655
656
657 void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
658 PrintLabels(node->labels());
659 Print("for (");
660 Visit(node->each());
661 Print(" of ");
662 Visit(node->iterable());
663 Print(") ");
664 Visit(node->body());
665 }
666
667
668 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
669 Print("try ");
670 Visit(node->try_block());
671 Print(" catch (");
672 const bool quote = false;
673 PrintLiteral(node->variable()->name(), quote);
674 Print(") ");
675 Visit(node->catch_block());
676 }
677
678
679 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
680 Print("try ");
681 Visit(node->try_block());
682 Print(" finally ");
683 Visit(node->finally_block());
684 }
685
686
687 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
688 Print("debugger ");
689 }
690
691
692 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
693 Print("(");
694 PrintFunctionLiteral(node);
695 Print(")");
696 }
697
698
699 void PrettyPrinter::VisitClassLiteral(ClassLiteral* node) {
700 Print("(class ");
701 PrintLiteral(node->name(), false);
702 if (node->extends()) {
703 Print(" extends ");
704 Visit(node->extends());
705 }
706 Print(" { ");
707 for (int i = 0; i < node->properties()->length(); i++) {
708 PrintObjectLiteralProperty(node->properties()->at(i));
709 }
710 Print(" })");
711 }
712
713
714 void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
715 Print("(");
716 PrintLiteral(node->name(), false);
717 Print(")");
718 }
719
720
721 void PrettyPrinter::VisitDoExpression(DoExpression* node) {
722 Print("(do {");
723 PrintStatements(node->block()->statements());
724 Print("})");
725 }
726
727
728 void PrettyPrinter::VisitConditional(Conditional* node) {
729 Visit(node->condition());
730 Print(" ? ");
731 Visit(node->then_expression());
732 Print(" : ");
733 Visit(node->else_expression());
734 }
735
736
737 void PrettyPrinter::VisitLiteral(Literal* node) {
738 PrintLiteral(node->value(), true);
739 }
740
741
742 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
743 Print(" RegExp(");
744 PrintLiteral(node->pattern(), false);
745 Print(",");
746 if (node->flags() & RegExp::kGlobal) Print("g");
747 if (node->flags() & RegExp::kIgnoreCase) Print("i");
748 if (node->flags() & RegExp::kMultiline) Print("m");
749 if (node->flags() & RegExp::kUnicode) Print("u");
750 if (node->flags() & RegExp::kSticky) Print("y");
751 Print(") ");
752 }
753
754
755 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
756 Print("{ ");
757 for (int i = 0; i < node->properties()->length(); i++) {
758 if (i != 0) Print(",");
759 PrintObjectLiteralProperty(node->properties()->at(i));
760 }
761 Print(" }");
762 }
763
764
765 void PrettyPrinter::PrintObjectLiteralProperty(
766 ObjectLiteralProperty* property) {
767 // TODO(arv): Better printing of methods etc.
768 Print(" ");
769 Visit(property->key());
770 Print(": ");
771 Visit(property->value());
772 }
773
774
775 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
776 Print("[ ");
777 Print(" literal_index = %d", node->literal_index());
778 for (int i = 0; i < node->values()->length(); i++) {
779 if (i != 0) Print(",");
780 Visit(node->values()->at(i));
781 }
782 Print(" ]");
783 }
784
785
786 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
787 PrintLiteral(node->name(), false);
788 }
789
790
791 void PrettyPrinter::VisitAssignment(Assignment* node) {
792 Visit(node->target());
793 Print(" %s ", Token::String(node->op()));
794 Visit(node->value());
795 }
796
797
798 void PrettyPrinter::VisitYield(Yield* node) {
799 Print("yield ");
800 Visit(node->expression());
801 }
802
803
804 void PrettyPrinter::VisitThrow(Throw* node) {
805 Print("throw ");
806 Visit(node->exception());
807 }
808
809
810 void PrettyPrinter::VisitProperty(Property* node) {
811 Expression* key = node->key();
812 Literal* literal = key->AsLiteral();
813 if (literal != NULL && literal->value()->IsInternalizedString()) {
814 Print("(");
815 Visit(node->obj());
816 Print(").");
817 PrintLiteral(literal->value(), false);
818 } else {
819 Visit(node->obj());
820 Print("[");
821 Visit(key);
822 Print("]");
823 }
824 }
825
826
827 void PrettyPrinter::VisitCall(Call* node) {
828 Visit(node->expression());
829 PrintArguments(node->arguments());
830 }
831
832
833 void PrettyPrinter::VisitCallNew(CallNew* node) {
834 Print("new (");
835 Visit(node->expression());
836 Print(")");
837 PrintArguments(node->arguments());
838 }
839
840
841 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
842 Print("%%%s\n", node->debug_name());
843 PrintArguments(node->arguments());
844 }
845
846
847 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
848 Token::Value op = node->op();
849 bool needsSpace =
850 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
851 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
852 Visit(node->expression());
853 Print(")");
854 }
855
856
857 void PrettyPrinter::VisitCountOperation(CountOperation* node) {
858 Print("(");
859 if (node->is_prefix()) Print("%s", Token::String(node->op()));
860 Visit(node->expression());
861 if (node->is_postfix()) Print("%s", Token::String(node->op()));
862 Print(")");
863 }
864
865
866 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
867 Print("(");
868 Visit(node->left());
869 Print(" %s ", Token::String(node->op()));
870 Visit(node->right());
871 Print(")");
872 }
873
874
875 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
876 Print("(");
877 Visit(node->left());
878 Print(" %s ", Token::String(node->op()));
879 Visit(node->right());
880 Print(")");
881 }
882
883
884 void PrettyPrinter::VisitSpread(Spread* node) {
885 Print("(...");
886 Visit(node->expression());
887 Print(")");
888 }
889
890
891 void PrettyPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
892 Print("()");
893 }
894
895
896 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
897 Print("<this-function>");
898 }
899
900
901 void PrettyPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
902 Print("<super-property-reference>");
903 }
904
905
906 void PrettyPrinter::VisitSuperCallReference(SuperCallReference* node) {
907 Print("<super-call-reference>");
908 }
909
910
911 const char* PrettyPrinter::Print(AstNode* node) {
912 Init();
913 Visit(node);
914 return output_;
915 }
916
917
918 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
919 Init();
920 ExpressionStatement* statement =
921 program->body()->at(0)->AsExpressionStatement();
922 Visit(statement->expression());
923 return output_;
924 }
925
926
927 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
928 Init();
929 PrintStatements(program->body());
930 Print("\n");
931 return output_;
932 }
933
934
935 void PrettyPrinter::PrintOut(Isolate* isolate, AstNode* node) {
936 PrettyPrinter printer(isolate);
937 PrintF("%s\n", printer.Print(node));
938 }
939
940
941 void PrettyPrinter::Init() {
942 if (size_ == 0) {
943 DCHECK(output_ == NULL);
944 const int initial_size = 256;
945 output_ = NewArray<char>(initial_size);
946 size_ = initial_size;
947 }
948 output_[0] = '\0';
949 pos_ = 0;
950 }
951
952
953 void PrettyPrinter::Print(const char* format, ...) {
954 for (;;) {
955 va_list arguments;
956 va_start(arguments, format);
957 int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
958 format,
959 arguments);
960 va_end(arguments);
961
962 if (n >= 0) {
963 // there was enough space - we are done
964 pos_ += n;
965 return;
966 } else {
967 // there was not enough space - allocate more and try again
968 const int slack = 32;
969 int new_size = size_ + (size_ >> 1) + slack;
970 char* new_output = NewArray<char>(new_size);
971 MemCopy(new_output, output_, pos_);
972 DeleteArray(output_);
973 output_ = new_output;
974 size_ = new_size;
975 }
976 }
977 }
978
979
980 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
981 if (statements == NULL) return;
982 for (int i = 0; i < statements->length(); i++) {
983 if (i != 0) Print(" ");
984 Visit(statements->at(i));
985 }
986 }
987
988
989 void PrettyPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
990 if (labels != NULL) {
991 for (int i = 0; i < labels->length(); i++) {
992 PrintLiteral(labels->at(i), false);
993 Print(": ");
994 }
995 }
996 }
997
998
999 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
1000 Print("(");
1001 for (int i = 0; i < arguments->length(); i++) {
1002 if (i != 0) Print(", ");
1003 Visit(arguments->at(i));
1004 }
1005 Print(")");
1006 }
1007
1008
1009 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
1010 Object* object = *value;
1011 if (object->IsString()) {
1012 String* string = String::cast(object);
1013 if (quote) Print("\"");
1014 for (int i = 0; i < string->length(); i++) {
1015 Print("%c", string->Get(i));
1016 }
1017 if (quote) Print("\"");
1018 } else if (object->IsNull()) {
1019 Print("null");
1020 } else if (object->IsTrue()) {
1021 Print("true");
1022 } else if (object->IsFalse()) {
1023 Print("false");
1024 } else if (object->IsUndefined()) {
1025 Print("undefined");
1026 } else if (object->IsNumber()) {
1027 Print("%g", object->Number());
1028 } else if (object->IsJSObject()) {
1029 // regular expression
1030 if (object->IsJSFunction()) {
1031 Print("JS-Function");
1032 } else if (object->IsJSArray()) {
1033 Print("JS-array[%u]", JSArray::cast(object)->length());
1034 } else if (object->IsJSObject()) {
1035 Print("JS-Object");
1036 } else {
1037 Print("?UNKNOWN?");
1038 }
1039 } else if (object->IsFixedArray()) {
1040 Print("FixedArray");
1041 } else {
1042 Print("<unknown literal %p>", object);
1043 }
1044 }
1045
1046
1047 void PrettyPrinter::PrintLiteral(const AstRawString* value, bool quote) {
1048 PrintLiteral(value->string(), quote);
1049 }
1050
1051
1052 void PrettyPrinter::PrintParameters(Scope* scope) {
1053 Print("(");
1054 for (int i = 0; i < scope->num_parameters(); i++) {
1055 if (i > 0) Print(", ");
1056 PrintLiteral(scope->parameter(i)->name(), false);
1057 }
1058 Print(")");
1059 }
1060
1061
1062 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
1063 for (int i = 0; i < declarations->length(); i++) {
1064 if (i > 0) Print(" ");
1065 Visit(declarations->at(i));
1066 }
1067 }
1068
1069
1070 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
1071 Print("function ");
1072 PrintLiteral(function->name(), false);
1073 PrintParameters(function->scope());
1074 Print(" { ");
1075 PrintDeclarations(function->scope()->declarations());
1076 PrintStatements(function->body());
1077 Print(" }");
1078 }
1079
1080
1081 //-----------------------------------------------------------------------------
1082
1083 class IndentedScope BASE_EMBEDDED {
1084 public:
1085 IndentedScope(AstPrinter* printer, const char* txt)
1086 : ast_printer_(printer) {
1087 ast_printer_->PrintIndented(txt);
1088 ast_printer_->Print("\n");
1089 ast_printer_->inc_indent();
1090 }
1091
1092 IndentedScope(AstPrinter* printer, const char* txt, int pos)
1093 : ast_printer_(printer) {
1094 ast_printer_->PrintIndented(txt);
1095 ast_printer_->Print(" at %d\n", pos);
1096 ast_printer_->inc_indent();
1097 }
1098
1099 virtual ~IndentedScope() {
1100 ast_printer_->dec_indent();
1101 }
1102
1103 private:
1104 AstPrinter* ast_printer_;
1105 };
1106
1107
1108 //-----------------------------------------------------------------------------
1109
1110
1111 AstPrinter::AstPrinter(Isolate* isolate) : PrettyPrinter(isolate), indent_(0) {}
1112
1113
1114 AstPrinter::~AstPrinter() {
1115 DCHECK(indent_ == 0);
1116 }
1117
1118
1119 void AstPrinter::PrintIndented(const char* txt) {
1120 for (int i = 0; i < indent_; i++) {
1121 Print(". ");
1122 }
1123 Print(txt);
1124 }
1125
1126
1127 void AstPrinter::PrintLiteralIndented(const char* info,
1128 Handle<Object> value,
1129 bool quote) {
1130 PrintIndented(info);
1131 Print(" ");
1132 PrintLiteral(value, quote);
1133 Print("\n");
1134 }
1135
1136
1137 void AstPrinter::PrintLiteralWithModeIndented(const char* info,
1138 Variable* var,
1139 Handle<Object> value) {
1140 if (var == NULL) {
1141 PrintLiteralIndented(info, value, true);
1142 } else {
1143 EmbeddedVector<char, 256> buf;
1144 int pos = SNPrintF(buf, "%s (mode = %s", info,
1145 Variable::Mode2String(var->mode()));
1146 SNPrintF(buf + pos, ")");
1147 PrintLiteralIndented(buf.start(), value, true);
1148 }
1149 }
1150
1151
1152 void AstPrinter::PrintLabelsIndented(ZoneList<const AstRawString*>* labels) {
1153 if (labels == NULL || labels->length() == 0) return;
1154 PrintIndented("LABELS ");
1155 PrintLabels(labels);
1156 Print("\n");
1157 }
1158
1159
1160 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
1161 IndentedScope indent(this, s, node->position());
1162 Visit(node);
1163 }
1164
1165
1166 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
1167 Init();
1168 { IndentedScope indent(this, "FUNC", program->position());
1169 PrintLiteralIndented("NAME", program->name(), true);
1170 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
1171 PrintParameters(program->scope());
1172 PrintDeclarations(program->scope()->declarations());
1173 PrintStatements(program->body());
1174 }
1175 return Output();
1176 }
1177
1178
1179 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
1180 if (declarations->length() > 0) {
1181 IndentedScope indent(this, "DECLS");
1182 for (int i = 0; i < declarations->length(); i++) {
1183 Visit(declarations->at(i));
1184 }
1185 }
1186 }
1187
1188
1189 void AstPrinter::PrintParameters(Scope* scope) {
1190 if (scope->num_parameters() > 0) {
1191 IndentedScope indent(this, "PARAMS");
1192 for (int i = 0; i < scope->num_parameters(); i++) {
1193 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
1194 scope->parameter(i)->name());
1195 }
1196 }
1197 }
1198
1199
1200 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
1201 for (int i = 0; i < statements->length(); i++) {
1202 Visit(statements->at(i));
1203 }
1204 }
1205
1206
1207 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
1208 for (int i = 0; i < arguments->length(); i++) {
1209 Visit(arguments->at(i));
1210 }
1211 }
1212
1213
1214 void AstPrinter::VisitBlock(Block* node) {
1215 const char* block_txt =
1216 node->ignore_completion_value() ? "BLOCK NOCOMPLETIONS" : "BLOCK";
1217 IndentedScope indent(this, block_txt, node->position());
1218 PrintStatements(node->statements());
1219 }
1220
1221
1222 // TODO(svenpanne) Start with IndentedScope.
1223 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
1224 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
1225 node->proxy()->var(),
1226 node->proxy()->name());
1227 }
1228
1229
1230 // TODO(svenpanne) Start with IndentedScope.
1231 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
1232 PrintIndented("FUNCTION ");
1233 PrintLiteral(node->proxy()->name(), true);
1234 Print(" = function ");
1235 PrintLiteral(node->fun()->name(), false);
1236 Print("\n");
1237 }
1238
1239
1240 void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
1241 IndentedScope indent(this, "IMPORT", node->position());
1242 PrintLiteralIndented("NAME", node->proxy()->name(), true);
1243 PrintLiteralIndented("FROM", node->module_specifier()->string(), true);
1244 }
1245
1246
1247 void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
1248 IndentedScope indent(this, "EXPORT", node->position());
1249 PrintLiteral(node->proxy()->name(), true);
1250 }
1251
1252
1253 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
1254 IndentedScope indent(this, "EXPRESSION STATEMENT", node->position());
1255 Visit(node->expression());
1256 }
1257
1258
1259 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
1260 IndentedScope indent(this, "EMPTY", node->position());
1261 }
1262
1263
1264 void AstPrinter::VisitSloppyBlockFunctionStatement(
1265 SloppyBlockFunctionStatement* node) {
1266 Visit(node->statement());
1267 }
1268
1269
1270 void AstPrinter::VisitIfStatement(IfStatement* node) {
1271 IndentedScope indent(this, "IF", node->position());
1272 PrintIndentedVisit("CONDITION", node->condition());
1273 PrintIndentedVisit("THEN", node->then_statement());
1274 if (node->HasElseStatement()) {
1275 PrintIndentedVisit("ELSE", node->else_statement());
1276 }
1277 }
1278
1279
1280 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
1281 IndentedScope indent(this, "CONTINUE", node->position());
1282 PrintLabelsIndented(node->target()->labels());
1283 }
1284
1285
1286 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
1287 IndentedScope indent(this, "BREAK", node->position());
1288 PrintLabelsIndented(node->target()->labels());
1289 }
1290
1291
1292 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
1293 IndentedScope indent(this, "RETURN", node->position());
1294 Visit(node->expression());
1295 }
1296
1297
1298 void AstPrinter::VisitWithStatement(WithStatement* node) {
1299 IndentedScope indent(this, "WITH", node->position());
1300 PrintIndentedVisit("OBJECT", node->expression());
1301 PrintIndentedVisit("BODY", node->statement());
1302 }
1303
1304
1305 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
1306 IndentedScope indent(this, "SWITCH", node->position());
1307 PrintLabelsIndented(node->labels());
1308 PrintIndentedVisit("TAG", node->tag());
1309 for (int i = 0; i < node->cases()->length(); i++) {
1310 Visit(node->cases()->at(i));
1311 }
1312 }
1313
1314
1315 void AstPrinter::VisitCaseClause(CaseClause* clause) {
1316 if (clause->is_default()) {
1317 IndentedScope indent(this, "DEFAULT", clause->position());
1318 PrintStatements(clause->statements());
1319 } else {
1320 IndentedScope indent(this, "CASE", clause->position());
1321 Visit(clause->label());
1322 PrintStatements(clause->statements());
1323 }
1324 }
1325
1326
1327 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
1328 IndentedScope indent(this, "DO", node->position());
1329 PrintLabelsIndented(node->labels());
1330 PrintIndentedVisit("BODY", node->body());
1331 PrintIndentedVisit("COND", node->cond());
1332 }
1333
1334
1335 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
1336 IndentedScope indent(this, "WHILE", node->position());
1337 PrintLabelsIndented(node->labels());
1338 PrintIndentedVisit("COND", node->cond());
1339 PrintIndentedVisit("BODY", node->body());
1340 }
1341
1342
1343 void AstPrinter::VisitForStatement(ForStatement* node) {
1344 IndentedScope indent(this, "FOR", node->position());
1345 PrintLabelsIndented(node->labels());
1346 if (node->init()) PrintIndentedVisit("INIT", node->init());
1347 if (node->cond()) PrintIndentedVisit("COND", node->cond());
1348 PrintIndentedVisit("BODY", node->body());
1349 if (node->next()) PrintIndentedVisit("NEXT", node->next());
1350 }
1351
1352
1353 void AstPrinter::VisitForInStatement(ForInStatement* node) {
1354 IndentedScope indent(this, "FOR IN", node->position());
1355 PrintIndentedVisit("FOR", node->each());
1356 PrintIndentedVisit("IN", node->enumerable());
1357 PrintIndentedVisit("BODY", node->body());
1358 }
1359
1360
1361 void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
1362 IndentedScope indent(this, "FOR OF", node->position());
1363 PrintIndentedVisit("FOR", node->each());
1364 PrintIndentedVisit("OF", node->iterable());
1365 PrintIndentedVisit("BODY", node->body());
1366 }
1367
1368
1369 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
1370 IndentedScope indent(this, "TRY CATCH", node->position());
1371 PrintIndentedVisit("TRY", node->try_block());
1372 PrintLiteralWithModeIndented("CATCHVAR",
1373 node->variable(),
1374 node->variable()->name());
1375 PrintIndentedVisit("CATCH", node->catch_block());
1376 }
1377
1378
1379 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
1380 IndentedScope indent(this, "TRY FINALLY", node->position());
1381 PrintIndentedVisit("TRY", node->try_block());
1382 PrintIndentedVisit("FINALLY", node->finally_block());
1383 }
1384
1385
1386 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
1387 IndentedScope indent(this, "DEBUGGER", node->position());
1388 }
1389
1390
1391 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
1392 IndentedScope indent(this, "FUNC LITERAL", node->position());
1393 PrintLiteralIndented("NAME", node->name(), false);
1394 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
1395 PrintParameters(node->scope());
1396 // We don't want to see the function literal in this case: it
1397 // will be printed via PrintProgram when the code for it is
1398 // generated.
1399 // PrintStatements(node->body());
1400 }
1401
1402
1403 void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
1404 IndentedScope indent(this, "CLASS LITERAL", node->position());
1405 if (node->raw_name() != nullptr) {
1406 PrintLiteralIndented("NAME", node->name(), false);
1407 }
1408 if (node->extends() != nullptr) {
1409 PrintIndentedVisit("EXTENDS", node->extends());
1410 }
1411 PrintProperties(node->properties());
1412 }
1413
1414
1415 void AstPrinter::PrintProperties(
1416 ZoneList<ObjectLiteral::Property*>* properties) {
1417 for (int i = 0; i < properties->length(); i++) {
1418 ObjectLiteral::Property* property = properties->at(i);
1419 const char* prop_kind = nullptr;
1420 switch (property->kind()) {
1421 case ObjectLiteral::Property::CONSTANT:
1422 prop_kind = "CONSTANT";
1423 break;
1424 case ObjectLiteral::Property::COMPUTED:
1425 prop_kind = "COMPUTED";
1426 break;
1427 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1428 prop_kind = "MATERIALIZED_LITERAL";
1429 break;
1430 case ObjectLiteral::Property::PROTOTYPE:
1431 prop_kind = "PROTOTYPE";
1432 break;
1433 case ObjectLiteral::Property::GETTER:
1434 prop_kind = "GETTER";
1435 break;
1436 case ObjectLiteral::Property::SETTER:
1437 prop_kind = "SETTER";
1438 break;
1439 }
1440 EmbeddedVector<char, 128> buf;
1441 SNPrintF(buf, "PROPERTY%s - %s", property->is_static() ? " - STATIC" : "",
1442 prop_kind);
1443 IndentedScope prop(this, buf.start());
1444 PrintIndentedVisit("KEY", properties->at(i)->key());
1445 PrintIndentedVisit("VALUE", properties->at(i)->value());
1446 }
1447 }
1448
1449
1450 void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
1451 IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position());
1452 PrintLiteralIndented("NAME", node->name(), false);
1453 }
1454
1455
1456 void AstPrinter::VisitDoExpression(DoExpression* node) {
1457 IndentedScope indent(this, "DO EXPRESSION", node->position());
1458 PrintStatements(node->block()->statements());
1459 }
1460
1461
1462 void AstPrinter::VisitConditional(Conditional* node) {
1463 IndentedScope indent(this, "CONDITIONAL", node->position());
1464 PrintIndentedVisit("CONDITION", node->condition());
1465 PrintIndentedVisit("THEN", node->then_expression());
1466 PrintIndentedVisit("ELSE", node->else_expression());
1467 }
1468
1469
1470 // TODO(svenpanne) Start with IndentedScope.
1471 void AstPrinter::VisitLiteral(Literal* node) {
1472 PrintLiteralIndented("LITERAL", node->value(), true);
1473 }
1474
1475
1476 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1477 IndentedScope indent(this, "REGEXP LITERAL", node->position());
1478 EmbeddedVector<char, 128> buf;
1479 SNPrintF(buf, "literal_index = %d\n", node->literal_index());
1480 PrintIndented(buf.start());
1481 PrintLiteralIndented("PATTERN", node->pattern(), false);
1482 int i = 0;
1483 if (node->flags() & RegExp::kGlobal) buf[i++] = 'g';
1484 if (node->flags() & RegExp::kIgnoreCase) buf[i++] = 'i';
1485 if (node->flags() & RegExp::kMultiline) buf[i++] = 'm';
1486 if (node->flags() & RegExp::kUnicode) buf[i++] = 'u';
1487 if (node->flags() & RegExp::kSticky) buf[i++] = 'y';
1488 buf[i] = '\0';
1489 PrintIndented("FLAGS ");
1490 Print(buf.start());
1491 Print("\n");
1492 }
1493
1494
1495 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1496 IndentedScope indent(this, "OBJ LITERAL", node->position());
1497 EmbeddedVector<char, 128> buf;
1498 SNPrintF(buf, "literal_index = %d\n", node->literal_index());
1499 PrintIndented(buf.start());
1500 PrintProperties(node->properties());
1501 }
1502
1503
1504 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1505 IndentedScope indent(this, "ARRAY LITERAL", node->position());
1506
1507 EmbeddedVector<char, 128> buf;
1508 SNPrintF(buf, "literal_index = %d\n", node->literal_index());
1509 PrintIndented(buf.start());
1510 if (node->values()->length() > 0) {
1511 IndentedScope indent(this, "VALUES", node->position());
1512 for (int i = 0; i < node->values()->length(); i++) {
1513 Visit(node->values()->at(i));
1514 }
1515 }
1516 }
1517
1518
1519 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1520 Variable* var = node->var();
1521 EmbeddedVector<char, 128> buf;
1522 int pos =
1523 FormatSlotNode(&buf, node, "VAR PROXY", node->VariableFeedbackSlot());
1524
1525 switch (var->location()) {
1526 case VariableLocation::UNALLOCATED:
1527 break;
1528 case VariableLocation::PARAMETER:
1529 SNPrintF(buf + pos, " parameter[%d]", var->index());
1530 break;
1531 case VariableLocation::LOCAL:
1532 SNPrintF(buf + pos, " local[%d]", var->index());
1533 break;
1534 case VariableLocation::CONTEXT:
1535 SNPrintF(buf + pos, " context[%d]", var->index());
1536 break;
1537 case VariableLocation::GLOBAL:
1538 SNPrintF(buf + pos, " global[%d]", var->index());
1539 break;
1540 case VariableLocation::LOOKUP:
1541 SNPrintF(buf + pos, " lookup");
1542 break;
1543 }
1544 PrintLiteralWithModeIndented(buf.start(), var, node->name());
1545 }
1546
1547
1548 void AstPrinter::VisitAssignment(Assignment* node) {
1549 IndentedScope indent(this, Token::Name(node->op()), node->position());
1550 Visit(node->target());
1551 Visit(node->value());
1552 }
1553
1554
1555 void AstPrinter::VisitYield(Yield* node) {
1556 IndentedScope indent(this, "YIELD", node->position());
1557 Visit(node->expression());
1558 }
1559
1560
1561 void AstPrinter::VisitThrow(Throw* node) {
1562 IndentedScope indent(this, "THROW", node->position());
1563 Visit(node->exception());
1564 }
1565
1566
1567 void AstPrinter::VisitProperty(Property* node) {
1568 EmbeddedVector<char, 128> buf;
1569 FormatSlotNode(&buf, node, "PROPERTY", node->PropertyFeedbackSlot());
1570 IndentedScope indent(this, buf.start(), node->position());
1571
1572 Visit(node->obj());
1573 Literal* literal = node->key()->AsLiteral();
1574 if (literal != NULL && literal->value()->IsInternalizedString()) {
1575 PrintLiteralIndented("NAME", literal->value(), false);
1576 } else {
1577 PrintIndentedVisit("KEY", node->key());
1578 }
1579 }
1580
1581
1582 void AstPrinter::VisitCall(Call* node) {
1583 EmbeddedVector<char, 128> buf;
1584 FormatSlotNode(&buf, node, "CALL", node->CallFeedbackICSlot());
1585 IndentedScope indent(this, buf.start());
1586
1587 Visit(node->expression());
1588 PrintArguments(node->arguments());
1589 }
1590
1591
1592 void AstPrinter::VisitCallNew(CallNew* node) {
1593 IndentedScope indent(this, "CALL NEW", node->position());
1594 Visit(node->expression());
1595 PrintArguments(node->arguments());
1596 }
1597
1598
1599 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1600 EmbeddedVector<char, 128> buf;
1601 SNPrintF(buf, "CALL RUNTIME %s", node->debug_name());
1602 IndentedScope indent(this, buf.start(), node->position());
1603 PrintArguments(node->arguments());
1604 }
1605
1606
1607 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1608 IndentedScope indent(this, Token::Name(node->op()), node->position());
1609 Visit(node->expression());
1610 }
1611
1612
1613 void AstPrinter::VisitCountOperation(CountOperation* node) {
1614 EmbeddedVector<char, 128> buf;
1615 SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1616 Token::Name(node->op()));
1617 IndentedScope indent(this, buf.start(), node->position());
1618 Visit(node->expression());
1619 }
1620
1621
1622 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1623 IndentedScope indent(this, Token::Name(node->op()), node->position());
1624 Visit(node->left());
1625 Visit(node->right());
1626 }
1627
1628
1629 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1630 IndentedScope indent(this, Token::Name(node->op()), node->position());
1631 Visit(node->left());
1632 Visit(node->right());
1633 }
1634
1635
1636 void AstPrinter::VisitSpread(Spread* node) {
1637 IndentedScope indent(this, "...", node->position());
1638 Visit(node->expression());
1639 }
1640
1641
1642 void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
1643 IndentedScope indent(this, "()", node->position());
1644 }
1645
1646
1647 void AstPrinter::VisitThisFunction(ThisFunction* node) {
1648 IndentedScope indent(this, "THIS-FUNCTION", node->position());
1649 }
1650
1651
1652 void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
1653 IndentedScope indent(this, "SUPER-PROPERTY-REFERENCE", node->position());
1654 }
1655
1656
1657 void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
1658 IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position());
1659 }
1660
1661
1662 #endif // DEBUG
1663
1664 } // namespace internal
1665 } // namespace v8
OLDNEW
« no previous file with comments | « src/prettyprinter.h ('k') | src/profiler/profile-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698