v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
prettyprinter.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include <stdarg.h>
29 
30 #include "v8.h"
31 
32 #include "prettyprinter.h"
33 #include "scopes.h"
34 #include "platform.h"
35 
36 namespace v8 {
37 namespace internal {
38 
39 #ifdef DEBUG
40 
41 PrettyPrinter::PrettyPrinter(Zone* zone) {
42  output_ = NULL;
43  size_ = 0;
44  pos_ = 0;
45  InitializeAstVisitor(zone);
46 }
47 
48 
49 PrettyPrinter::~PrettyPrinter() {
50  DeleteArray(output_);
51 }
52 
53 
54 void PrettyPrinter::VisitBlock(Block* node) {
55  if (!node->is_initializer_block()) Print("{ ");
56  PrintStatements(node->statements());
57  if (node->statements()->length() > 0) Print(" ");
58  if (!node->is_initializer_block()) Print("}");
59 }
60 
61 
62 void PrettyPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
63  Print("var ");
64  PrintLiteral(node->proxy()->name(), false);
65  Print(";");
66 }
67 
68 
69 void PrettyPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
70  Print("function ");
71  PrintLiteral(node->proxy()->name(), false);
72  Print(" = ");
73  PrintFunctionLiteral(node->fun());
74  Print(";");
75 }
76 
77 
78 void PrettyPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
79  Print("module ");
80  PrintLiteral(node->proxy()->name(), false);
81  Print(" = ");
82  Visit(node->module());
83  Print(";");
84 }
85 
86 
87 void PrettyPrinter::VisitImportDeclaration(ImportDeclaration* node) {
88  Print("import ");
89  PrintLiteral(node->proxy()->name(), false);
90  Print(" from ");
91  Visit(node->module());
92  Print(";");
93 }
94 
95 
96 void PrettyPrinter::VisitExportDeclaration(ExportDeclaration* node) {
97  Print("export ");
98  PrintLiteral(node->proxy()->name(), false);
99  Print(";");
100 }
101 
102 
103 void PrettyPrinter::VisitModuleLiteral(ModuleLiteral* node) {
104  VisitBlock(node->body());
105 }
106 
107 
108 void PrettyPrinter::VisitModuleVariable(ModuleVariable* node) {
109  Visit(node->proxy());
110 }
111 
112 
113 void PrettyPrinter::VisitModulePath(ModulePath* node) {
114  Visit(node->module());
115  Print(".");
116  PrintLiteral(node->name(), false);
117 }
118 
119 
120 void PrettyPrinter::VisitModuleUrl(ModuleUrl* node) {
121  Print("at ");
122  PrintLiteral(node->url(), true);
123 }
124 
125 
126 void PrettyPrinter::VisitModuleStatement(ModuleStatement* node) {
127  Print("module ");
128  PrintLiteral(node->proxy()->name(), false);
129  Print(" ");
130  Visit(node->body());
131 }
132 
133 
134 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
135  Visit(node->expression());
136  Print(";");
137 }
138 
139 
140 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
141  Print(";");
142 }
143 
144 
145 void PrettyPrinter::VisitIfStatement(IfStatement* node) {
146  Print("if (");
147  Visit(node->condition());
148  Print(") ");
149  Visit(node->then_statement());
150  if (node->HasElseStatement()) {
151  Print(" else ");
152  Visit(node->else_statement());
153  }
154 }
155 
156 
157 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
158  Print("continue");
159  ZoneStringList* labels = node->target()->labels();
160  if (labels != NULL) {
161  Print(" ");
162  ASSERT(labels->length() > 0); // guaranteed to have at least one entry
163  PrintLiteral(labels->at(0), false); // any label from the list is fine
164  }
165  Print(";");
166 }
167 
168 
169 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
170  Print("break");
171  ZoneStringList* labels = node->target()->labels();
172  if (labels != NULL) {
173  Print(" ");
174  ASSERT(labels->length() > 0); // guaranteed to have at least one entry
175  PrintLiteral(labels->at(0), false); // any label from the list is fine
176  }
177  Print(";");
178 }
179 
180 
181 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
182  Print("return ");
183  Visit(node->expression());
184  Print(";");
185 }
186 
187 
188 void PrettyPrinter::VisitWithStatement(WithStatement* node) {
189  Print("with (");
190  Visit(node->expression());
191  Print(") ");
192  Visit(node->statement());
193 }
194 
195 
196 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
197  PrintLabels(node->labels());
198  Print("switch (");
199  Visit(node->tag());
200  Print(") { ");
201  ZoneList<CaseClause*>* cases = node->cases();
202  for (int i = 0; i < cases->length(); i++)
203  Visit(cases->at(i));
204  Print("}");
205 }
206 
207 
208 void PrettyPrinter::VisitCaseClause(CaseClause* clause) {
209  if (clause->is_default()) {
210  Print("default");
211  } else {
212  Print("case ");
213  Visit(clause->label());
214  }
215  Print(": ");
216  PrintStatements(clause->statements());
217  if (clause->statements()->length() > 0)
218  Print(" ");
219 }
220 
221 
222 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
223  PrintLabels(node->labels());
224  Print("do ");
225  Visit(node->body());
226  Print(" while (");
227  Visit(node->cond());
228  Print(");");
229 }
230 
231 
232 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
233  PrintLabels(node->labels());
234  Print("while (");
235  Visit(node->cond());
236  Print(") ");
237  Visit(node->body());
238 }
239 
240 
241 void PrettyPrinter::VisitForStatement(ForStatement* node) {
242  PrintLabels(node->labels());
243  Print("for (");
244  if (node->init() != NULL) {
245  Visit(node->init());
246  Print(" ");
247  } else {
248  Print("; ");
249  }
250  if (node->cond() != NULL) Visit(node->cond());
251  Print("; ");
252  if (node->next() != NULL) {
253  Visit(node->next()); // prints extra ';', unfortunately
254  // to fix: should use Expression for next
255  }
256  Print(") ");
257  Visit(node->body());
258 }
259 
260 
261 void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
262  PrintLabels(node->labels());
263  Print("for (");
264  Visit(node->each());
265  Print(" in ");
266  Visit(node->enumerable());
267  Print(") ");
268  Visit(node->body());
269 }
270 
271 
272 void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) {
273  PrintLabels(node->labels());
274  Print("for (");
275  Visit(node->each());
276  Print(" of ");
277  Visit(node->iterable());
278  Print(") ");
279  Visit(node->body());
280 }
281 
282 
283 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
284  Print("try ");
285  Visit(node->try_block());
286  Print(" catch (");
287  const bool quote = false;
288  PrintLiteral(node->variable()->name(), quote);
289  Print(") ");
290  Visit(node->catch_block());
291 }
292 
293 
294 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
295  Print("try ");
296  Visit(node->try_block());
297  Print(" finally ");
298  Visit(node->finally_block());
299 }
300 
301 
302 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
303  Print("debugger ");
304 }
305 
306 
307 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
308  Print("(");
309  PrintFunctionLiteral(node);
310  Print(")");
311 }
312 
313 
314 void PrettyPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
315  Print("(");
316  PrintLiteral(node->name(), false);
317  Print(")");
318 }
319 
320 
321 void PrettyPrinter::VisitConditional(Conditional* node) {
322  Visit(node->condition());
323  Print(" ? ");
324  Visit(node->then_expression());
325  Print(" : ");
326  Visit(node->else_expression());
327 }
328 
329 
330 void PrettyPrinter::VisitLiteral(Literal* node) {
331  PrintLiteral(node->value(), true);
332 }
333 
334 
335 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
336  Print(" RegExp(");
337  PrintLiteral(node->pattern(), false);
338  Print(",");
339  PrintLiteral(node->flags(), false);
340  Print(") ");
341 }
342 
343 
344 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
345  Print("{ ");
346  for (int i = 0; i < node->properties()->length(); i++) {
347  if (i != 0) Print(",");
348  ObjectLiteral::Property* property = node->properties()->at(i);
349  Print(" ");
350  Visit(property->key());
351  Print(": ");
352  Visit(property->value());
353  }
354  Print(" }");
355 }
356 
357 
358 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
359  Print("[ ");
360  for (int i = 0; i < node->values()->length(); i++) {
361  if (i != 0) Print(",");
362  Visit(node->values()->at(i));
363  }
364  Print(" ]");
365 }
366 
367 
368 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
369  PrintLiteral(node->name(), false);
370 }
371 
372 
373 void PrettyPrinter::VisitAssignment(Assignment* node) {
374  Visit(node->target());
375  Print(" %s ", Token::String(node->op()));
376  Visit(node->value());
377 }
378 
379 
380 void PrettyPrinter::VisitYield(Yield* node) {
381  Print("yield ");
382  Visit(node->expression());
383 }
384 
385 
386 void PrettyPrinter::VisitThrow(Throw* node) {
387  Print("throw ");
388  Visit(node->exception());
389 }
390 
391 
392 void PrettyPrinter::VisitProperty(Property* node) {
393  Expression* key = node->key();
394  Literal* literal = key->AsLiteral();
395  if (literal != NULL && literal->value()->IsInternalizedString()) {
396  Print("(");
397  Visit(node->obj());
398  Print(").");
399  PrintLiteral(literal->value(), false);
400  } else {
401  Visit(node->obj());
402  Print("[");
403  Visit(key);
404  Print("]");
405  }
406 }
407 
408 
409 void PrettyPrinter::VisitCall(Call* node) {
410  Visit(node->expression());
411  PrintArguments(node->arguments());
412 }
413 
414 
415 void PrettyPrinter::VisitCallNew(CallNew* node) {
416  Print("new (");
417  Visit(node->expression());
418  Print(")");
419  PrintArguments(node->arguments());
420 }
421 
422 
423 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
424  Print("%%");
425  PrintLiteral(node->name(), false);
426  PrintArguments(node->arguments());
427 }
428 
429 
430 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
431  Token::Value op = node->op();
432  bool needsSpace =
433  op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
434  Print("(%s%s", Token::String(op), needsSpace ? " " : "");
435  Visit(node->expression());
436  Print(")");
437 }
438 
439 
440 void PrettyPrinter::VisitCountOperation(CountOperation* node) {
441  Print("(");
442  if (node->is_prefix()) Print("%s", Token::String(node->op()));
443  Visit(node->expression());
444  if (node->is_postfix()) Print("%s", Token::String(node->op()));
445  Print(")");
446 }
447 
448 
449 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
450  Print("(");
451  Visit(node->left());
452  Print(" %s ", Token::String(node->op()));
453  Visit(node->right());
454  Print(")");
455 }
456 
457 
458 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
459  Print("(");
460  Visit(node->left());
461  Print(" %s ", Token::String(node->op()));
462  Visit(node->right());
463  Print(")");
464 }
465 
466 
467 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
468  Print("<this-function>");
469 }
470 
471 
472 const char* PrettyPrinter::Print(AstNode* node) {
473  Init();
474  Visit(node);
475  return output_;
476 }
477 
478 
479 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
480  Init();
481  ExpressionStatement* statement =
482  program->body()->at(0)->AsExpressionStatement();
483  Visit(statement->expression());
484  return output_;
485 }
486 
487 
488 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
489  Init();
490  PrintStatements(program->body());
491  Print("\n");
492  return output_;
493 }
494 
495 
496 void PrettyPrinter::PrintOut(Zone* zone, AstNode* node) {
497  PrettyPrinter printer(zone);
498  PrintF("%s", printer.Print(node));
499 }
500 
501 
502 void PrettyPrinter::Init() {
503  if (size_ == 0) {
504  ASSERT(output_ == NULL);
505  const int initial_size = 256;
506  output_ = NewArray<char>(initial_size);
507  size_ = initial_size;
508  }
509  output_[0] = '\0';
510  pos_ = 0;
511 }
512 
513 
514 void PrettyPrinter::Print(const char* format, ...) {
515  for (;;) {
516  va_list arguments;
517  va_start(arguments, format);
518  int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
519  format,
520  arguments);
521  va_end(arguments);
522 
523  if (n >= 0) {
524  // there was enough space - we are done
525  pos_ += n;
526  return;
527  } else {
528  // there was not enough space - allocate more and try again
529  const int slack = 32;
530  int new_size = size_ + (size_ >> 1) + slack;
531  char* new_output = NewArray<char>(new_size);
532  OS::MemCopy(new_output, output_, pos_);
533  DeleteArray(output_);
534  output_ = new_output;
535  size_ = new_size;
536  }
537  }
538 }
539 
540 
541 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
542  if (statements == NULL) return;
543  for (int i = 0; i < statements->length(); i++) {
544  if (i != 0) Print(" ");
545  Visit(statements->at(i));
546  }
547 }
548 
549 
550 void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
551  if (labels != NULL) {
552  for (int i = 0; i < labels->length(); i++) {
553  PrintLiteral(labels->at(i), false);
554  Print(": ");
555  }
556  }
557 }
558 
559 
560 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
561  Print("(");
562  for (int i = 0; i < arguments->length(); i++) {
563  if (i != 0) Print(", ");
564  Visit(arguments->at(i));
565  }
566  Print(")");
567 }
568 
569 
570 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
571  Object* object = *value;
572  if (object->IsString()) {
573  String* string = String::cast(object);
574  if (quote) Print("\"");
575  for (int i = 0; i < string->length(); i++) {
576  Print("%c", string->Get(i));
577  }
578  if (quote) Print("\"");
579  } else if (object->IsNull()) {
580  Print("null");
581  } else if (object->IsTrue()) {
582  Print("true");
583  } else if (object->IsFalse()) {
584  Print("false");
585  } else if (object->IsUndefined()) {
586  Print("undefined");
587  } else if (object->IsNumber()) {
588  Print("%g", object->Number());
589  } else if (object->IsJSObject()) {
590  // regular expression
591  if (object->IsJSFunction()) {
592  Print("JS-Function");
593  } else if (object->IsJSArray()) {
594  Print("JS-array[%u]", JSArray::cast(object)->length());
595  } else if (object->IsJSObject()) {
596  Print("JS-Object");
597  } else {
598  Print("?UNKNOWN?");
599  }
600  } else if (object->IsFixedArray()) {
601  Print("FixedArray");
602  } else {
603  Print("<unknown literal %p>", object);
604  }
605 }
606 
607 
608 void PrettyPrinter::PrintParameters(Scope* scope) {
609  Print("(");
610  for (int i = 0; i < scope->num_parameters(); i++) {
611  if (i > 0) Print(", ");
612  PrintLiteral(scope->parameter(i)->name(), false);
613  }
614  Print(")");
615 }
616 
617 
618 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
619  for (int i = 0; i < declarations->length(); i++) {
620  if (i > 0) Print(" ");
621  Visit(declarations->at(i));
622  }
623 }
624 
625 
626 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
627  Print("function ");
628  PrintLiteral(function->name(), false);
629  PrintParameters(function->scope());
630  Print(" { ");
631  PrintDeclarations(function->scope()->declarations());
632  PrintStatements(function->body());
633  Print(" }");
634 }
635 
636 
637 //-----------------------------------------------------------------------------
638 
639 class IndentedScope BASE_EMBEDDED {
640  public:
641  IndentedScope(AstPrinter* printer, const char* txt)
642  : ast_printer_(printer) {
643  ast_printer_->PrintIndented(txt);
644  ast_printer_->Print("\n");
645  ast_printer_->inc_indent();
646  }
647 
648  virtual ~IndentedScope() {
649  ast_printer_->dec_indent();
650  }
651 
652  private:
653  AstPrinter* ast_printer_;
654 };
655 
656 
657 //-----------------------------------------------------------------------------
658 
659 
660 AstPrinter::AstPrinter(Zone* zone) : PrettyPrinter(zone), indent_(0) {
661 }
662 
663 
664 AstPrinter::~AstPrinter() {
665  ASSERT(indent_ == 0);
666 }
667 
668 
669 void AstPrinter::PrintIndented(const char* txt) {
670  for (int i = 0; i < indent_; i++) {
671  Print(". ");
672  }
673  Print(txt);
674 }
675 
676 
677 void AstPrinter::PrintLiteralIndented(const char* info,
678  Handle<Object> value,
679  bool quote) {
680  PrintIndented(info);
681  Print(" ");
682  PrintLiteral(value, quote);
683  Print("\n");
684 }
685 
686 
687 void AstPrinter::PrintLiteralWithModeIndented(const char* info,
688  Variable* var,
689  Handle<Object> value) {
690  if (var == NULL) {
691  PrintLiteralIndented(info, value, true);
692  } else {
693  EmbeddedVector<char, 256> buf;
694  int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
695  Variable::Mode2String(var->mode()));
696  OS::SNPrintF(buf + pos, ")");
697  PrintLiteralIndented(buf.start(), value, true);
698  }
699 }
700 
701 
702 void AstPrinter::PrintLabelsIndented(ZoneStringList* labels) {
703  if (labels == NULL || labels->length() == 0) return;
704  PrintIndented("LABELS ");
705  PrintLabels(labels);
706  Print("\n");
707 }
708 
709 
710 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
711  IndentedScope indent(this, s);
712  Visit(node);
713 }
714 
715 
716 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
717  Init();
718  { IndentedScope indent(this, "FUNC");
719  PrintLiteralIndented("NAME", program->name(), true);
720  PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
721  PrintParameters(program->scope());
722  PrintDeclarations(program->scope()->declarations());
723  PrintStatements(program->body());
724  }
725  return Output();
726 }
727 
728 
729 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
730  if (declarations->length() > 0) {
731  IndentedScope indent(this, "DECLS");
732  for (int i = 0; i < declarations->length(); i++) {
733  Visit(declarations->at(i));
734  }
735  }
736 }
737 
738 
739 void AstPrinter::PrintParameters(Scope* scope) {
740  if (scope->num_parameters() > 0) {
741  IndentedScope indent(this, "PARAMS");
742  for (int i = 0; i < scope->num_parameters(); i++) {
743  PrintLiteralWithModeIndented("VAR", scope->parameter(i),
744  scope->parameter(i)->name());
745  }
746  }
747 }
748 
749 
750 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
751  for (int i = 0; i < statements->length(); i++) {
752  Visit(statements->at(i));
753  }
754 }
755 
756 
757 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
758  for (int i = 0; i < arguments->length(); i++) {
759  Visit(arguments->at(i));
760  }
761 }
762 
763 
764 void AstPrinter::VisitBlock(Block* node) {
765  const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
766  IndentedScope indent(this, block_txt);
767  PrintStatements(node->statements());
768 }
769 
770 
771 // TODO(svenpanne) Start with IndentedScope.
772 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
773  PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
774  node->proxy()->var(),
775  node->proxy()->name());
776 }
777 
778 
779 // TODO(svenpanne) Start with IndentedScope.
780 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
781  PrintIndented("FUNCTION ");
782  PrintLiteral(node->proxy()->name(), true);
783  Print(" = function ");
784  PrintLiteral(node->fun()->name(), false);
785  Print("\n");
786 }
787 
788 
789 void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
790  IndentedScope indent(this, "MODULE");
791  PrintLiteralIndented("NAME", node->proxy()->name(), true);
792  Visit(node->module());
793 }
794 
795 
796 void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) {
797  IndentedScope indent(this, "IMPORT");
798  PrintLiteralIndented("NAME", node->proxy()->name(), true);
799  Visit(node->module());
800 }
801 
802 
803 void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) {
804  IndentedScope indent(this, "EXPORT ");
805  PrintLiteral(node->proxy()->name(), true);
806 }
807 
808 
809 void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) {
810  IndentedScope indent(this, "MODULE LITERAL");
811  VisitBlock(node->body());
812 }
813 
814 
815 void AstPrinter::VisitModuleVariable(ModuleVariable* node) {
816  IndentedScope indent(this, "MODULE VARIABLE");
817  Visit(node->proxy());
818 }
819 
820 
821 void AstPrinter::VisitModulePath(ModulePath* node) {
822  IndentedScope indent(this, "MODULE PATH");
823  PrintIndentedVisit("MODULE PATH PARENT", node->module());
824  PrintLiteralIndented("NAME", node->name(), true);
825 }
826 
827 
828 void AstPrinter::VisitModuleUrl(ModuleUrl* node) {
829  PrintLiteralIndented("URL", node->url(), true);
830 }
831 
832 
833 void AstPrinter::VisitModuleStatement(ModuleStatement* node) {
834  IndentedScope indent(this, "MODULE STATEMENT");
835  PrintLiteralIndented("NAME", node->proxy()->name(), true);
836  PrintStatements(node->body()->statements());
837 }
838 
839 
840 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
841  IndentedScope indent(this, "EXPRESSION STATEMENT");
842  Visit(node->expression());
843 }
844 
845 
846 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
847  IndentedScope indent(this, "EMPTY");
848 }
849 
850 
851 void AstPrinter::VisitIfStatement(IfStatement* node) {
852  IndentedScope indent(this, "IF");
853  PrintIndentedVisit("CONDITION", node->condition());
854  PrintIndentedVisit("THEN", node->then_statement());
855  if (node->HasElseStatement()) {
856  PrintIndentedVisit("ELSE", node->else_statement());
857  }
858 }
859 
860 
861 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
862  IndentedScope indent(this, "CONTINUE");
863  PrintLabelsIndented(node->target()->labels());
864 }
865 
866 
867 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
868  IndentedScope indent(this, "BREAK");
869  PrintLabelsIndented(node->target()->labels());
870 }
871 
872 
873 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
874  IndentedScope indent(this, "RETURN");
875  Visit(node->expression());
876 }
877 
878 
879 void AstPrinter::VisitWithStatement(WithStatement* node) {
880  IndentedScope indent(this, "WITH");
881  PrintIndentedVisit("OBJECT", node->expression());
882  PrintIndentedVisit("BODY", node->statement());
883 }
884 
885 
886 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
887  IndentedScope indent(this, "SWITCH");
888  PrintLabelsIndented(node->labels());
889  PrintIndentedVisit("TAG", node->tag());
890  for (int i = 0; i < node->cases()->length(); i++) {
891  Visit(node->cases()->at(i));
892  }
893 }
894 
895 
896 void AstPrinter::VisitCaseClause(CaseClause* clause) {
897  if (clause->is_default()) {
898  IndentedScope indent(this, "DEFAULT");
899  PrintStatements(clause->statements());
900  } else {
901  IndentedScope indent(this, "CASE");
902  Visit(clause->label());
903  PrintStatements(clause->statements());
904  }
905 }
906 
907 
908 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
909  IndentedScope indent(this, "DO");
910  PrintLabelsIndented(node->labels());
911  PrintIndentedVisit("BODY", node->body());
912  PrintIndentedVisit("COND", node->cond());
913 }
914 
915 
916 void AstPrinter::VisitWhileStatement(WhileStatement* node) {
917  IndentedScope indent(this, "WHILE");
918  PrintLabelsIndented(node->labels());
919  PrintIndentedVisit("COND", node->cond());
920  PrintIndentedVisit("BODY", node->body());
921 }
922 
923 
924 void AstPrinter::VisitForStatement(ForStatement* node) {
925  IndentedScope indent(this, "FOR");
926  PrintLabelsIndented(node->labels());
927  if (node->init()) PrintIndentedVisit("INIT", node->init());
928  if (node->cond()) PrintIndentedVisit("COND", node->cond());
929  PrintIndentedVisit("BODY", node->body());
930  if (node->next()) PrintIndentedVisit("NEXT", node->next());
931 }
932 
933 
934 void AstPrinter::VisitForInStatement(ForInStatement* node) {
935  IndentedScope indent(this, "FOR IN");
936  PrintIndentedVisit("FOR", node->each());
937  PrintIndentedVisit("IN", node->enumerable());
938  PrintIndentedVisit("BODY", node->body());
939 }
940 
941 
942 void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
943  IndentedScope indent(this, "FOR OF");
944  PrintIndentedVisit("FOR", node->each());
945  PrintIndentedVisit("OF", node->iterable());
946  PrintIndentedVisit("BODY", node->body());
947 }
948 
949 
950 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
951  IndentedScope indent(this, "TRY CATCH");
952  PrintIndentedVisit("TRY", node->try_block());
953  PrintLiteralWithModeIndented("CATCHVAR",
954  node->variable(),
955  node->variable()->name());
956  PrintIndentedVisit("CATCH", node->catch_block());
957 }
958 
959 
960 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
961  IndentedScope indent(this, "TRY FINALLY");
962  PrintIndentedVisit("TRY", node->try_block());
963  PrintIndentedVisit("FINALLY", node->finally_block());
964 }
965 
966 
967 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
968  IndentedScope indent(this, "DEBUGGER");
969 }
970 
971 
972 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
973  IndentedScope indent(this, "FUNC LITERAL");
974  PrintLiteralIndented("NAME", node->name(), false);
975  PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
976  PrintParameters(node->scope());
977  // We don't want to see the function literal in this case: it
978  // will be printed via PrintProgram when the code for it is
979  // generated.
980  // PrintStatements(node->body());
981 }
982 
983 
984 void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
985  IndentedScope indent(this, "NATIVE FUNC LITERAL");
986  PrintLiteralIndented("NAME", node->name(), false);
987 }
988 
989 
990 void AstPrinter::VisitConditional(Conditional* node) {
991  IndentedScope indent(this, "CONDITIONAL");
992  PrintIndentedVisit("CONDITION", node->condition());
993  PrintIndentedVisit("THEN", node->then_expression());
994  PrintIndentedVisit("ELSE", node->else_expression());
995 }
996 
997 
998 // TODO(svenpanne) Start with IndentedScope.
999 void AstPrinter::VisitLiteral(Literal* node) {
1000  PrintLiteralIndented("LITERAL", node->value(), true);
1001 }
1002 
1003 
1004 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1005  IndentedScope indent(this, "REGEXP LITERAL");
1006  PrintLiteralIndented("PATTERN", node->pattern(), false);
1007  PrintLiteralIndented("FLAGS", node->flags(), false);
1008 }
1009 
1010 
1011 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1012  IndentedScope indent(this, "OBJ LITERAL");
1013  for (int i = 0; i < node->properties()->length(); i++) {
1014  const char* prop_kind = NULL;
1015  switch (node->properties()->at(i)->kind()) {
1017  prop_kind = "PROPERTY - CONSTANT";
1018  break;
1019  case ObjectLiteral::Property::COMPUTED:
1020  prop_kind = "PROPERTY - COMPUTED";
1021  break;
1022  case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1023  prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
1024  break;
1025  case ObjectLiteral::Property::PROTOTYPE:
1026  prop_kind = "PROPERTY - PROTOTYPE";
1027  break;
1028  case ObjectLiteral::Property::GETTER:
1029  prop_kind = "PROPERTY - GETTER";
1030  break;
1031  case ObjectLiteral::Property::SETTER:
1032  prop_kind = "PROPERTY - SETTER";
1033  break;
1034  default:
1035  UNREACHABLE();
1036  }
1037  IndentedScope prop(this, prop_kind);
1038  PrintIndentedVisit("KEY", node->properties()->at(i)->key());
1039  PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
1040  }
1041 }
1042 
1043 
1044 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1045  IndentedScope indent(this, "ARRAY LITERAL");
1046  if (node->values()->length() > 0) {
1047  IndentedScope indent(this, "VALUES");
1048  for (int i = 0; i < node->values()->length(); i++) {
1049  Visit(node->values()->at(i));
1050  }
1051  }
1052 }
1053 
1054 
1055 // TODO(svenpanne) Start with IndentedScope.
1056 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1057  Variable* var = node->var();
1058  EmbeddedVector<char, 128> buf;
1059  int pos = OS::SNPrintF(buf, "VAR PROXY");
1060  switch (var->location()) {
1061  case Variable::UNALLOCATED:
1062  break;
1063  case Variable::PARAMETER:
1064  OS::SNPrintF(buf + pos, " parameter[%d]", var->index());
1065  break;
1066  case Variable::LOCAL:
1067  OS::SNPrintF(buf + pos, " local[%d]", var->index());
1068  break;
1069  case Variable::CONTEXT:
1070  OS::SNPrintF(buf + pos, " context[%d]", var->index());
1071  break;
1072  case Variable::LOOKUP:
1073  OS::SNPrintF(buf + pos, " lookup");
1074  break;
1075  }
1076  PrintLiteralWithModeIndented(buf.start(), var, node->name());
1077 }
1078 
1079 
1080 void AstPrinter::VisitAssignment(Assignment* node) {
1081  IndentedScope indent(this, Token::Name(node->op()));
1082  Visit(node->target());
1083  Visit(node->value());
1084 }
1085 
1086 
1087 void AstPrinter::VisitYield(Yield* node) {
1088  IndentedScope indent(this, "YIELD");
1089  Visit(node->expression());
1090 }
1091 
1092 
1093 void AstPrinter::VisitThrow(Throw* node) {
1094  IndentedScope indent(this, "THROW");
1095  Visit(node->exception());
1096 }
1097 
1098 
1099 void AstPrinter::VisitProperty(Property* node) {
1100  IndentedScope indent(this, "PROPERTY");
1101  Visit(node->obj());
1102  Literal* literal = node->key()->AsLiteral();
1103  if (literal != NULL && literal->value()->IsInternalizedString()) {
1104  PrintLiteralIndented("NAME", literal->value(), false);
1105  } else {
1106  PrintIndentedVisit("KEY", node->key());
1107  }
1108 }
1109 
1110 
1111 void AstPrinter::VisitCall(Call* node) {
1112  IndentedScope indent(this, "CALL");
1113  Visit(node->expression());
1114  PrintArguments(node->arguments());
1115 }
1116 
1117 
1118 void AstPrinter::VisitCallNew(CallNew* node) {
1119  IndentedScope indent(this, "CALL NEW");
1120  Visit(node->expression());
1121  PrintArguments(node->arguments());
1122 }
1123 
1124 
1125 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1126  IndentedScope indent(this, "CALL RUNTIME");
1127  PrintLiteralIndented("NAME", node->name(), false);
1128  PrintArguments(node->arguments());
1129 }
1130 
1131 
1132 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1133  IndentedScope indent(this, Token::Name(node->op()));
1134  Visit(node->expression());
1135 }
1136 
1137 
1138 void AstPrinter::VisitCountOperation(CountOperation* node) {
1139  EmbeddedVector<char, 128> buf;
1140  OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1141  Token::Name(node->op()));
1142  IndentedScope indent(this, buf.start());
1143  Visit(node->expression());
1144 }
1145 
1146 
1147 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1148  IndentedScope indent(this, Token::Name(node->op()));
1149  Visit(node->left());
1150  Visit(node->right());
1151 }
1152 
1153 
1154 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1155  IndentedScope indent(this, Token::Name(node->op()));
1156  Visit(node->left());
1157  Visit(node->right());
1158 }
1159 
1160 
1161 void AstPrinter::VisitThisFunction(ThisFunction* node) {
1162  IndentedScope indent(this, "THIS-FUNCTION");
1163 }
1164 
1165 #endif // DEBUG
1166 
1167 } } // namespace v8::internal
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
void PrintF(const char *format,...)
Definition: v8utils.cc:40
static int VSNPrintF(Vector< char > str, const char *format, va_list args)
static String * cast(Object *obj)
static const char * Name(Value tok)
Definition: token.h:198
kSerializedDataOffset Object
Definition: objects-inl.h:5016
#define ASSERT(condition)
Definition: checks.h:329
#define UNREACHABLE()
Definition: checks.h:52
static void MemCopy(void *dest, const void *src, size_t size)
Definition: platform.h:399
static const char * String(Value tok)
Definition: token.h:294
static const char * Mode2String(VariableMode mode)
Definition: variables.cc:40
#define BASE_EMBEDDED
Definition: allocation.h:68
static JSArray * cast(Object *obj)
static int SNPrintF(Vector< char > str, const char *format,...)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
Definition: flags.cc:317
void Print(const v8::FunctionCallbackInfo< v8::Value > &args)
ZoneList< Handle< String > > ZoneStringList
Definition: ast.h:161
void DeleteArray(T *array)
Definition: allocation.h:91
#define VOID