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