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() { 42 output_ = NULL; 43 size_ = 0; 44 pos_ = 0; 45 InitializeAstVisitor(); 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 PrintCaseClause(cases->at(i)); 204 Print("}"); 205 } 206 207 208 void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) { 209 PrintLabels(node->labels()); 210 Print("do "); 211 Visit(node->body()); 212 Print(" while ("); 213 Visit(node->cond()); 214 Print(");"); 215 } 216 217 218 void PrettyPrinter::VisitWhileStatement(WhileStatement* node) { 219 PrintLabels(node->labels()); 220 Print("while ("); 221 Visit(node->cond()); 222 Print(") "); 223 Visit(node->body()); 224 } 225 226 227 void PrettyPrinter::VisitForStatement(ForStatement* node) { 228 PrintLabels(node->labels()); 229 Print("for ("); 230 if (node->init() != NULL) { 231 Visit(node->init()); 232 Print(" "); 233 } else { 234 Print("; "); 235 } 236 if (node->cond() != NULL) Visit(node->cond()); 237 Print("; "); 238 if (node->next() != NULL) { 239 Visit(node->next()); // prints extra ';', unfortunately 240 // to fix: should use Expression for next 241 } 242 Print(") "); 243 Visit(node->body()); 244 } 245 246 247 void PrettyPrinter::VisitForInStatement(ForInStatement* node) { 248 PrintLabels(node->labels()); 249 Print("for ("); 250 Visit(node->each()); 251 Print(" in "); 252 Visit(node->enumerable()); 253 Print(") "); 254 Visit(node->body()); 255 } 256 257 258 void PrettyPrinter::VisitForOfStatement(ForOfStatement* node) { 259 PrintLabels(node->labels()); 260 Print("for ("); 261 Visit(node->each()); 262 Print(" of "); 263 Visit(node->iterable()); 264 Print(") "); 265 Visit(node->body()); 266 } 267 268 269 void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) { 270 Print("try "); 271 Visit(node->try_block()); 272 Print(" catch ("); 273 const bool quote = false; 274 PrintLiteral(node->variable()->name(), quote); 275 Print(") "); 276 Visit(node->catch_block()); 277 } 278 279 280 void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) { 281 Print("try "); 282 Visit(node->try_block()); 283 Print(" finally "); 284 Visit(node->finally_block()); 285 } 286 287 288 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) { 289 Print("debugger "); 290 } 291 292 293 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) { 294 Print("("); 295 PrintFunctionLiteral(node); 296 Print(")"); 297 } 298 299 300 void PrettyPrinter::VisitSharedFunctionInfoLiteral( 301 SharedFunctionInfoLiteral* node) { 302 Print("("); 303 PrintLiteral(node->shared_function_info(), true); 304 Print(")"); 305 } 306 307 308 void PrettyPrinter::VisitConditional(Conditional* node) { 309 Visit(node->condition()); 310 Print(" ? "); 311 Visit(node->then_expression()); 312 Print(" : "); 313 Visit(node->else_expression()); 314 } 315 316 317 void PrettyPrinter::VisitLiteral(Literal* node) { 318 PrintLiteral(node->value(), true); 319 } 320 321 322 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) { 323 Print(" RegExp("); 324 PrintLiteral(node->pattern(), false); 325 Print(","); 326 PrintLiteral(node->flags(), false); 327 Print(") "); 328 } 329 330 331 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) { 332 Print("{ "); 333 for (int i = 0; i < node->properties()->length(); i++) { 334 if (i != 0) Print(","); 335 ObjectLiteral::Property* property = node->properties()->at(i); 336 Print(" "); 337 Visit(property->key()); 338 Print(": "); 339 Visit(property->value()); 340 } 341 Print(" }"); 342 } 343 344 345 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) { 346 Print("[ "); 347 for (int i = 0; i < node->values()->length(); i++) { 348 if (i != 0) Print(","); 349 Visit(node->values()->at(i)); 350 } 351 Print(" ]"); 352 } 353 354 355 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) { 356 PrintLiteral(node->name(), false); 357 } 358 359 360 void PrettyPrinter::VisitAssignment(Assignment* node) { 361 Visit(node->target()); 362 Print(" %s ", Token::String(node->op())); 363 Visit(node->value()); 364 } 365 366 367 void PrettyPrinter::VisitYield(Yield* node) { 368 Print("yield "); 369 Visit(node->expression()); 370 } 371 372 373 void PrettyPrinter::VisitThrow(Throw* node) { 374 Print("throw "); 375 Visit(node->exception()); 376 } 377 378 379 void PrettyPrinter::VisitProperty(Property* node) { 380 Expression* key = node->key(); 381 Literal* literal = key->AsLiteral(); 382 if (literal != NULL && literal->value()->IsInternalizedString()) { 383 Print("("); 384 Visit(node->obj()); 385 Print(")."); 386 PrintLiteral(literal->value(), false); 387 } else { 388 Visit(node->obj()); 389 Print("["); 390 Visit(key); 391 Print("]"); 392 } 393 } 394 395 396 void PrettyPrinter::VisitCall(Call* node) { 397 Visit(node->expression()); 398 PrintArguments(node->arguments()); 399 } 400 401 402 void PrettyPrinter::VisitCallNew(CallNew* node) { 403 Print("new ("); 404 Visit(node->expression()); 405 Print(")"); 406 PrintArguments(node->arguments()); 407 } 408 409 410 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) { 411 Print("%%"); 412 PrintLiteral(node->name(), false); 413 PrintArguments(node->arguments()); 414 } 415 416 417 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) { 418 Token::Value op = node->op(); 419 bool needsSpace = 420 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID; 421 Print("(%s%s", Token::String(op), needsSpace ? " " : ""); 422 Visit(node->expression()); 423 Print(")"); 424 } 425 426 427 void PrettyPrinter::VisitCountOperation(CountOperation* node) { 428 Print("("); 429 if (node->is_prefix()) Print("%s", Token::String(node->op())); 430 Visit(node->expression()); 431 if (node->is_postfix()) Print("%s", Token::String(node->op())); 432 Print(")"); 433 } 434 435 436 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) { 437 Print("("); 438 Visit(node->left()); 439 Print(" %s ", Token::String(node->op())); 440 Visit(node->right()); 441 Print(")"); 442 } 443 444 445 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) { 446 Print("("); 447 Visit(node->left()); 448 Print(" %s ", Token::String(node->op())); 449 Visit(node->right()); 450 Print(")"); 451 } 452 453 454 void PrettyPrinter::VisitThisFunction(ThisFunction* node) { 455 Print("<this-function>"); 456 } 457 458 459 const char* PrettyPrinter::Print(AstNode* node) { 460 Init(); 461 Visit(node); 462 return output_; 463 } 464 465 466 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) { 467 Init(); 468 ExpressionStatement* statement = 469 program->body()->at(0)->AsExpressionStatement(); 470 Visit(statement->expression()); 471 return output_; 472 } 473 474 475 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) { 476 Init(); 477 PrintStatements(program->body()); 478 Print("\n"); 479 return output_; 480 } 481 482 483 void PrettyPrinter::PrintOut(AstNode* node) { 484 PrettyPrinter printer; 485 PrintF("%s", printer.Print(node)); 486 } 487 488 489 void PrettyPrinter::Init() { 490 if (size_ == 0) { 491 ASSERT(output_ == NULL); 492 const int initial_size = 256; 493 output_ = NewArray<char>(initial_size); 494 size_ = initial_size; 495 } 496 output_[0] = '\0'; 497 pos_ = 0; 498 } 499 500 501 void PrettyPrinter::Print(const char* format, ...) { 502 for (;;) { 503 va_list arguments; 504 va_start(arguments, format); 505 int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_, 506 format, 507 arguments); 508 va_end(arguments); 509 510 if (n >= 0) { 511 // there was enough space - we are done 512 pos_ += n; 513 return; 514 } else { 515 // there was not enough space - allocate more and try again 516 const int slack = 32; 517 int new_size = size_ + (size_ >> 1) + slack; 518 char* new_output = NewArray<char>(new_size); 519 OS::MemCopy(new_output, output_, pos_); 520 DeleteArray(output_); 521 output_ = new_output; 522 size_ = new_size; 523 } 524 } 525 } 526 527 528 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) { 529 if (statements == NULL) return; 530 for (int i = 0; i < statements->length(); i++) { 531 if (i != 0) Print(" "); 532 Visit(statements->at(i)); 533 } 534 } 535 536 537 void PrettyPrinter::PrintLabels(ZoneStringList* labels) { 538 if (labels != NULL) { 539 for (int i = 0; i < labels->length(); i++) { 540 PrintLiteral(labels->at(i), false); 541 Print(": "); 542 } 543 } 544 } 545 546 547 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) { 548 Print("("); 549 for (int i = 0; i < arguments->length(); i++) { 550 if (i != 0) Print(", "); 551 Visit(arguments->at(i)); 552 } 553 Print(")"); 554 } 555 556 557 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) { 558 Object* object = *value; 559 if (object->IsString()) { 560 String* string = String::cast(object); 561 if (quote) Print("\""); 562 for (int i = 0; i < string->length(); i++) { 563 Print("%c", string->Get(i)); 564 } 565 if (quote) Print("\""); 566 } else if (object->IsNull()) { 567 Print("null"); 568 } else if (object->IsTrue()) { 569 Print("true"); 570 } else if (object->IsFalse()) { 571 Print("false"); 572 } else if (object->IsUndefined()) { 573 Print("undefined"); 574 } else if (object->IsNumber()) { 575 Print("%g", object->Number()); 576 } else if (object->IsJSObject()) { 577 // regular expression 578 if (object->IsJSFunction()) { 579 Print("JS-Function"); 580 } else if (object->IsJSArray()) { 581 Print("JS-array[%u]", JSArray::cast(object)->length()); 582 } else if (object->IsJSObject()) { 583 Print("JS-Object"); 584 } else { 585 Print("?UNKNOWN?"); 586 } 587 } else if (object->IsFixedArray()) { 588 Print("FixedArray"); 589 } else { 590 Print("<unknown literal %p>", object); 591 } 592 } 593 594 595 void PrettyPrinter::PrintParameters(Scope* scope) { 596 Print("("); 597 for (int i = 0; i < scope->num_parameters(); i++) { 598 if (i > 0) Print(", "); 599 PrintLiteral(scope->parameter(i)->name(), false); 600 } 601 Print(")"); 602 } 603 604 605 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) { 606 for (int i = 0; i < declarations->length(); i++) { 607 if (i > 0) Print(" "); 608 Visit(declarations->at(i)); 609 } 610 } 611 612 613 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) { 614 Print("function "); 615 PrintLiteral(function->name(), false); 616 PrintParameters(function->scope()); 617 Print(" { "); 618 PrintDeclarations(function->scope()->declarations()); 619 PrintStatements(function->body()); 620 Print(" }"); 621 } 622 623 624 void PrettyPrinter::PrintCaseClause(CaseClause* clause) { 625 if (clause->is_default()) { 626 Print("default"); 627 } else { 628 Print("case "); 629 Visit(clause->label()); 630 } 631 Print(": "); 632 PrintStatements(clause->statements()); 633 if (clause->statements()->length() > 0) 634 Print(" "); 635 } 636 637 638 //----------------------------------------------------------------------------- 639 640 class IndentedScope BASE_EMBEDDED { 641 public: 642 IndentedScope(AstPrinter* printer, const char* txt) 643 : ast_printer_(printer) { 644 ast_printer_->PrintIndented(txt); 645 ast_printer_->Print("\n"); 646 ast_printer_->inc_indent(); 647 } 648 649 virtual ~IndentedScope() { 650 ast_printer_->dec_indent(); 651 } 652 653 private: 654 AstPrinter* ast_printer_; 655 }; 656 657 658 //----------------------------------------------------------------------------- 659 660 661 AstPrinter::AstPrinter() : indent_(0) { 662 } 663 664 665 AstPrinter::~AstPrinter() { 666 ASSERT(indent_ == 0); 667 } 668 669 670 void AstPrinter::PrintIndented(const char* txt) { 671 for (int i = 0; i < indent_; i++) { 672 Print(". "); 673 } 674 Print(txt); 675 } 676 677 678 void AstPrinter::PrintLiteralIndented(const char* info, 679 Handle<Object> value, 680 bool quote) { 681 PrintIndented(info); 682 Print(" "); 683 PrintLiteral(value, quote); 684 Print("\n"); 685 } 686 687 688 void AstPrinter::PrintLiteralWithModeIndented(const char* info, 689 Variable* var, 690 Handle<Object> value) { 691 if (var == NULL) { 692 PrintLiteralIndented(info, value, true); 693 } else { 694 EmbeddedVector<char, 256> buf; 695 int pos = OS::SNPrintF(buf, "%s (mode = %s", info, 696 Variable::Mode2String(var->mode())); 697 OS::SNPrintF(buf + pos, ")"); 698 PrintLiteralIndented(buf.start(), value, true); 699 } 700 } 701 702 703 void AstPrinter::PrintLabelsIndented(ZoneStringList* labels) { 704 if (labels == NULL || labels->length() == 0) return; 705 PrintIndented("LABELS "); 706 PrintLabels(labels); 707 Print("\n"); 708 } 709 710 711 void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) { 712 IndentedScope indent(this, s); 713 Visit(node); 714 } 715 716 717 const char* AstPrinter::PrintProgram(FunctionLiteral* program) { 718 Init(); 719 { IndentedScope indent(this, "FUNC"); 720 PrintLiteralIndented("NAME", program->name(), true); 721 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true); 722 PrintParameters(program->scope()); 723 PrintDeclarations(program->scope()->declarations()); 724 PrintStatements(program->body()); 725 } 726 return Output(); 727 } 728 729 730 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) { 731 if (declarations->length() > 0) { 732 IndentedScope indent(this, "DECLS"); 733 for (int i = 0; i < declarations->length(); i++) { 734 Visit(declarations->at(i)); 735 } 736 } 737 } 738 739 740 void AstPrinter::PrintParameters(Scope* scope) { 741 if (scope->num_parameters() > 0) { 742 IndentedScope indent(this, "PARAMS"); 743 for (int i = 0; i < scope->num_parameters(); i++) { 744 PrintLiteralWithModeIndented("VAR", scope->parameter(i), 745 scope->parameter(i)->name()); 746 } 747 } 748 } 749 750 751 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) { 752 for (int i = 0; i < statements->length(); i++) { 753 Visit(statements->at(i)); 754 } 755 } 756 757 758 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) { 759 for (int i = 0; i < arguments->length(); i++) { 760 Visit(arguments->at(i)); 761 } 762 } 763 764 765 void AstPrinter::PrintCaseClause(CaseClause* clause) { 766 if (clause->is_default()) { 767 IndentedScope indent(this, "DEFAULT"); 768 PrintStatements(clause->statements()); 769 } else { 770 IndentedScope indent(this, "CASE"); 771 Visit(clause->label()); 772 PrintStatements(clause->statements()); 773 } 774 } 775 776 777 void AstPrinter::VisitBlock(Block* node) { 778 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK"; 779 IndentedScope indent(this, block_txt); 780 PrintStatements(node->statements()); 781 } 782 783 784 // TODO(svenpanne) Start with IndentedScope. 785 void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) { 786 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()), 787 node->proxy()->var(), 788 node->proxy()->name()); 789 } 790 791 792 // TODO(svenpanne) Start with IndentedScope. 793 void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) { 794 PrintIndented("FUNCTION "); 795 PrintLiteral(node->proxy()->name(), true); 796 Print(" = function "); 797 PrintLiteral(node->fun()->name(), false); 798 Print("\n"); 799 } 800 801 802 void AstPrinter::VisitModuleDeclaration(ModuleDeclaration* node) { 803 IndentedScope indent(this, "MODULE"); 804 PrintLiteralIndented("NAME", node->proxy()->name(), true); 805 Visit(node->module()); 806 } 807 808 809 void AstPrinter::VisitImportDeclaration(ImportDeclaration* node) { 810 IndentedScope indent(this, "IMPORT"); 811 PrintLiteralIndented("NAME", node->proxy()->name(), true); 812 Visit(node->module()); 813 } 814 815 816 void AstPrinter::VisitExportDeclaration(ExportDeclaration* node) { 817 IndentedScope indent(this, "EXPORT "); 818 PrintLiteral(node->proxy()->name(), true); 819 } 820 821 822 void AstPrinter::VisitModuleLiteral(ModuleLiteral* node) { 823 IndentedScope indent(this, "MODULE LITERAL"); 824 VisitBlock(node->body()); 825 } 826 827 828 void AstPrinter::VisitModuleVariable(ModuleVariable* node) { 829 IndentedScope indent(this, "MODULE VARIABLE"); 830 Visit(node->proxy()); 831 } 832 833 834 void AstPrinter::VisitModulePath(ModulePath* node) { 835 IndentedScope indent(this, "MODULE PATH"); 836 PrintIndentedVisit("MODULE PATH PARENT", node->module()); 837 PrintLiteralIndented("NAME", node->name(), true); 838 } 839 840 841 void AstPrinter::VisitModuleUrl(ModuleUrl* node) { 842 PrintLiteralIndented("URL", node->url(), true); 843 } 844 845 846 void AstPrinter::VisitModuleStatement(ModuleStatement* node) { 847 IndentedScope indent(this, "MODULE STATEMENT"); 848 PrintLiteralIndented("NAME", node->proxy()->name(), true); 849 PrintStatements(node->body()->statements()); 850 } 851 852 853 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) { 854 IndentedScope indent(this, "EXPRESSION STATEMENT"); 855 Visit(node->expression()); 856 } 857 858 859 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) { 860 IndentedScope indent(this, "EMPTY"); 861 } 862 863 864 void AstPrinter::VisitIfStatement(IfStatement* node) { 865 IndentedScope indent(this, "IF"); 866 PrintIndentedVisit("CONDITION", node->condition()); 867 PrintIndentedVisit("THEN", node->then_statement()); 868 if (node->HasElseStatement()) { 869 PrintIndentedVisit("ELSE", node->else_statement()); 870 } 871 } 872 873 874 void AstPrinter::VisitContinueStatement(ContinueStatement* node) { 875 IndentedScope indent(this, "CONTINUE"); 876 PrintLabelsIndented(node->target()->labels()); 877 } 878 879 880 void AstPrinter::VisitBreakStatement(BreakStatement* node) { 881 IndentedScope indent(this, "BREAK"); 882 PrintLabelsIndented(node->target()->labels()); 883 } 884 885 886 void AstPrinter::VisitReturnStatement(ReturnStatement* node) { 887 IndentedScope indent(this, "RETURN"); 888 Visit(node->expression()); 889 } 890 891 892 void AstPrinter::VisitWithStatement(WithStatement* node) { 893 IndentedScope indent(this, "WITH"); 894 PrintIndentedVisit("OBJECT", node->expression()); 895 PrintIndentedVisit("BODY", node->statement()); 896 } 897 898 899 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) { 900 IndentedScope indent(this, "SWITCH"); 901 PrintLabelsIndented(node->labels()); 902 PrintIndentedVisit("TAG", node->tag()); 903 for (int i = 0; i < node->cases()->length(); i++) { 904 PrintCaseClause(node->cases()->at(i)); 905 } 906 } 907 908 909 void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) { 910 IndentedScope indent(this, "DO"); 911 PrintLabelsIndented(node->labels()); 912 PrintIndentedVisit("BODY", node->body()); 913 PrintIndentedVisit("COND", node->cond()); 914 } 915 916 917 void AstPrinter::VisitWhileStatement(WhileStatement* node) { 918 IndentedScope indent(this, "WHILE"); 919 PrintLabelsIndented(node->labels()); 920 PrintIndentedVisit("COND", node->cond()); 921 PrintIndentedVisit("BODY", node->body()); 922 } 923 924 925 void AstPrinter::VisitForStatement(ForStatement* node) { 926 IndentedScope indent(this, "FOR"); 927 PrintLabelsIndented(node->labels()); 928 if (node->init()) PrintIndentedVisit("INIT", node->init()); 929 if (node->cond()) PrintIndentedVisit("COND", node->cond()); 930 PrintIndentedVisit("BODY", node->body()); 931 if (node->next()) PrintIndentedVisit("NEXT", node->next()); 932 } 933 934 935 void AstPrinter::VisitForInStatement(ForInStatement* node) { 936 IndentedScope indent(this, "FOR IN"); 937 PrintIndentedVisit("FOR", node->each()); 938 PrintIndentedVisit("IN", node->enumerable()); 939 PrintIndentedVisit("BODY", node->body()); 940 } 941 942 943 void AstPrinter::VisitForOfStatement(ForOfStatement* node) { 944 IndentedScope indent(this, "FOR OF"); 945 PrintIndentedVisit("FOR", node->each()); 946 PrintIndentedVisit("OF", node->iterable()); 947 PrintIndentedVisit("BODY", node->body()); 948 } 949 950 951 void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) { 952 IndentedScope indent(this, "TRY CATCH"); 953 PrintIndentedVisit("TRY", node->try_block()); 954 PrintLiteralWithModeIndented("CATCHVAR", 955 node->variable(), 956 node->variable()->name()); 957 PrintIndentedVisit("CATCH", node->catch_block()); 958 } 959 960 961 void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) { 962 IndentedScope indent(this, "TRY FINALLY"); 963 PrintIndentedVisit("TRY", node->try_block()); 964 PrintIndentedVisit("FINALLY", node->finally_block()); 965 } 966 967 968 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) { 969 IndentedScope indent(this, "DEBUGGER"); 970 } 971 972 973 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) { 974 IndentedScope indent(this, "FUNC LITERAL"); 975 PrintLiteralIndented("NAME", node->name(), false); 976 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false); 977 PrintParameters(node->scope()); 978 // We don't want to see the function literal in this case: it 979 // will be printed via PrintProgram when the code for it is 980 // generated. 981 // PrintStatements(node->body()); 982 } 983 984 985 void AstPrinter::VisitSharedFunctionInfoLiteral( 986 SharedFunctionInfoLiteral* node) { 987 IndentedScope indent(this, "FUNC LITERAL"); 988 PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true); 989 } 990 991 992 void AstPrinter::VisitConditional(Conditional* node) { 993 IndentedScope indent(this, "CONDITIONAL"); 994 PrintIndentedVisit("CONDITION", node->condition()); 995 PrintIndentedVisit("THEN", node->then_expression()); 996 PrintIndentedVisit("ELSE", node->else_expression()); 997 } 998 999 1000 // TODO(svenpanne) Start with IndentedScope. 1001 void AstPrinter::VisitLiteral(Literal* node) { 1002 PrintLiteralIndented("LITERAL", node->value(), true); 1003 } 1004 1005 1006 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) { 1007 IndentedScope indent(this, "REGEXP LITERAL"); 1008 PrintLiteralIndented("PATTERN", node->pattern(), false); 1009 PrintLiteralIndented("FLAGS", node->flags(), false); 1010 } 1011 1012 1013 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) { 1014 IndentedScope indent(this, "OBJ LITERAL"); 1015 for (int i = 0; i < node->properties()->length(); i++) { 1016 const char* prop_kind = NULL; 1017 switch (node->properties()->at(i)->kind()) { 1018 case ObjectLiteral::Property::CONSTANT: 1019 prop_kind = "PROPERTY - CONSTANT"; 1020 break; 1021 case ObjectLiteral::Property::COMPUTED: 1022 prop_kind = "PROPERTY - COMPUTED"; 1023 break; 1024 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1025 prop_kind = "PROPERTY - MATERIALIZED_LITERAL"; 1026 break; 1027 case ObjectLiteral::Property::PROTOTYPE: 1028 prop_kind = "PROPERTY - PROTOTYPE"; 1029 break; 1030 case ObjectLiteral::Property::GETTER: 1031 prop_kind = "PROPERTY - GETTER"; 1032 break; 1033 case ObjectLiteral::Property::SETTER: 1034 prop_kind = "PROPERTY - SETTER"; 1035 break; 1036 default: 1037 UNREACHABLE(); 1038 } 1039 IndentedScope prop(this, prop_kind); 1040 PrintIndentedVisit("KEY", node->properties()->at(i)->key()); 1041 PrintIndentedVisit("VALUE", node->properties()->at(i)->value()); 1042 } 1043 } 1044 1045 1046 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) { 1047 IndentedScope indent(this, "ARRAY LITERAL"); 1048 if (node->values()->length() > 0) { 1049 IndentedScope indent(this, "VALUES"); 1050 for (int i = 0; i < node->values()->length(); i++) { 1051 Visit(node->values()->at(i)); 1052 } 1053 } 1054 } 1055 1056 1057 // TODO(svenpanne) Start with IndentedScope. 1058 void AstPrinter::VisitVariableProxy(VariableProxy* node) { 1059 Variable* var = node->var(); 1060 EmbeddedVector<char, 128> buf; 1061 int pos = OS::SNPrintF(buf, "VAR PROXY"); 1062 switch (var->location()) { 1063 case Variable::UNALLOCATED: 1064 break; 1065 case Variable::PARAMETER: 1066 OS::SNPrintF(buf + pos, " parameter[%d]", var->index()); 1067 break; 1068 case Variable::LOCAL: 1069 OS::SNPrintF(buf + pos, " local[%d]", var->index()); 1070 break; 1071 case Variable::CONTEXT: 1072 OS::SNPrintF(buf + pos, " context[%d]", var->index()); 1073 break; 1074 case Variable::LOOKUP: 1075 OS::SNPrintF(buf + pos, " lookup"); 1076 break; 1077 } 1078 PrintLiteralWithModeIndented(buf.start(), var, node->name()); 1079 } 1080 1081 1082 void AstPrinter::VisitAssignment(Assignment* node) { 1083 IndentedScope indent(this, Token::Name(node->op())); 1084 Visit(node->target()); 1085 Visit(node->value()); 1086 } 1087 1088 1089 void AstPrinter::VisitYield(Yield* node) { 1090 IndentedScope indent(this, "YIELD"); 1091 Visit(node->expression()); 1092 } 1093 1094 1095 void AstPrinter::VisitThrow(Throw* node) { 1096 IndentedScope indent(this, "THROW"); 1097 Visit(node->exception()); 1098 } 1099 1100 1101 void AstPrinter::VisitProperty(Property* node) { 1102 IndentedScope indent(this, "PROPERTY"); 1103 Visit(node->obj()); 1104 Literal* literal = node->key()->AsLiteral(); 1105 if (literal != NULL && literal->value()->IsInternalizedString()) { 1106 PrintLiteralIndented("NAME", literal->value(), false); 1107 } else { 1108 PrintIndentedVisit("KEY", node->key()); 1109 } 1110 } 1111 1112 1113 void AstPrinter::VisitCall(Call* node) { 1114 IndentedScope indent(this, "CALL"); 1115 Visit(node->expression()); 1116 PrintArguments(node->arguments()); 1117 } 1118 1119 1120 void AstPrinter::VisitCallNew(CallNew* node) { 1121 IndentedScope indent(this, "CALL NEW"); 1122 Visit(node->expression()); 1123 PrintArguments(node->arguments()); 1124 } 1125 1126 1127 void AstPrinter::VisitCallRuntime(CallRuntime* node) { 1128 IndentedScope indent(this, "CALL RUNTIME"); 1129 PrintLiteralIndented("NAME", node->name(), false); 1130 PrintArguments(node->arguments()); 1131 } 1132 1133 1134 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) { 1135 IndentedScope indent(this, Token::Name(node->op())); 1136 Visit(node->expression()); 1137 } 1138 1139 1140 void AstPrinter::VisitCountOperation(CountOperation* node) { 1141 EmbeddedVector<char, 128> buf; 1142 OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"), 1143 Token::Name(node->op())); 1144 IndentedScope indent(this, buf.start()); 1145 Visit(node->expression()); 1146 } 1147 1148 1149 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) { 1150 IndentedScope indent(this, Token::Name(node->op())); 1151 Visit(node->left()); 1152 Visit(node->right()); 1153 } 1154 1155 1156 void AstPrinter::VisitCompareOperation(CompareOperation* node) { 1157 IndentedScope indent(this, Token::Name(node->op())); 1158 Visit(node->left()); 1159 Visit(node->right()); 1160 } 1161 1162 1163 void AstPrinter::VisitThisFunction(ThisFunction* node) { 1164 IndentedScope indent(this, "THIS-FUNCTION"); 1165 } 1166 1167 #endif // DEBUG 1168 1169 } } // namespace v8::internal 1170