00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdarg.h>
00029
00030 #include "v8.h"
00031
00032 #include "prettyprinter.h"
00033 #include "scopes.h"
00034 #include "platform.h"
00035
00036 namespace v8 { namespace internal {
00037
00038 #ifdef DEBUG
00039
00040 PrettyPrinter::PrettyPrinter() {
00041 output_ = NULL;
00042 size_ = 0;
00043 pos_ = 0;
00044 }
00045
00046
00047 PrettyPrinter::~PrettyPrinter() {
00048 DeleteArray(output_);
00049 }
00050
00051
00052 void PrettyPrinter::VisitBlock(Block* node) {
00053 if (!node->is_initializer_block()) Print("{ ");
00054 PrintStatements(node->statements());
00055 if (node->statements()->length() > 0) Print(" ");
00056 if (!node->is_initializer_block()) Print("}");
00057 }
00058
00059
00060 void PrettyPrinter::VisitDeclaration(Declaration* node) {
00061 Print("var ");
00062 PrintLiteral(node->proxy()->name(), false);
00063 if (node->fun() != NULL) {
00064 Print(" = ");
00065 PrintFunctionLiteral(node->fun());
00066 }
00067 Print(";");
00068 }
00069
00070
00071 void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
00072 Visit(node->expression());
00073 Print(";");
00074 }
00075
00076
00077 void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
00078 Print(";");
00079 }
00080
00081
00082 void PrettyPrinter::VisitIfStatement(IfStatement* node) {
00083 Print("if (");
00084 Visit(node->condition());
00085 Print(") ");
00086 Visit(node->then_statement());
00087 if (node->HasElseStatement()) {
00088 Print(" else ");
00089 Visit(node->else_statement());
00090 }
00091 }
00092
00093
00094 void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
00095 Print("continue");
00096 ZoneStringList* labels = node->target()->labels();
00097 if (labels != NULL) {
00098 Print(" ");
00099 ASSERT(labels->length() > 0);
00100 PrintLiteral(labels->at(0), false);
00101 }
00102 Print(";");
00103 }
00104
00105
00106 void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
00107 Print("break");
00108 ZoneStringList* labels = node->target()->labels();
00109 if (labels != NULL) {
00110 Print(" ");
00111 ASSERT(labels->length() > 0);
00112 PrintLiteral(labels->at(0), false);
00113 }
00114 Print(";");
00115 }
00116
00117
00118 void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
00119 Print("return ");
00120 Visit(node->expression());
00121 Print(";");
00122 }
00123
00124
00125 void PrettyPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
00126 Print("<enter with> (");
00127 Visit(node->expression());
00128 Print(") ");
00129 }
00130
00131
00132 void PrettyPrinter::VisitWithExitStatement(WithExitStatement* node) {
00133 Print("<exit with>");
00134 }
00135
00136
00137 void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
00138 PrintLabels(node->labels());
00139 Print("switch (");
00140 Visit(node->tag());
00141 Print(") { ");
00142 ZoneList<CaseClause*>* cases = node->cases();
00143 for (int i = 0; i < cases->length(); i++)
00144 PrintCaseClause(cases->at(i));
00145 Print("}");
00146 }
00147
00148
00149 void PrettyPrinter::VisitLoopStatement(LoopStatement* node) {
00150 PrintLabels(node->labels());
00151 switch (node->type()) {
00152 case LoopStatement::DO_LOOP:
00153 ASSERT(node->init() == NULL);
00154 ASSERT(node->next() == NULL);
00155 Print("do ");
00156 Visit(node->body());
00157 Print(" while (");
00158 Visit(node->cond());
00159 Print(");");
00160 break;
00161
00162 case LoopStatement::FOR_LOOP:
00163 Print("for (");
00164 if (node->init() != NULL) {
00165 Visit(node->init());
00166 Print(" ");
00167 } else {
00168 Print("; ");
00169 }
00170 if (node->cond() != NULL)
00171 Visit(node->cond());
00172 Print("; ");
00173 if (node->next() != NULL)
00174 Visit(node->next());
00175
00176 Print(") ");
00177 Visit(node->body());
00178 break;
00179
00180 case LoopStatement::WHILE_LOOP:
00181 ASSERT(node->init() == NULL);
00182 ASSERT(node->next() == NULL);
00183 Print("while (");
00184 Visit(node->cond());
00185 Print(") ");
00186 Visit(node->body());
00187 break;
00188 }
00189 }
00190
00191
00192 void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
00193 PrintLabels(node->labels());
00194 Print("for (");
00195 Visit(node->each());
00196 Print(" in ");
00197 Visit(node->enumerable());
00198 Print(") ");
00199 Visit(node->body());
00200 }
00201
00202
00203 void PrettyPrinter::VisitTryCatch(TryCatch* node) {
00204 Print("try ");
00205 Visit(node->try_block());
00206 Print(" catch (");
00207 Visit(node->catch_var());
00208 Print(") ");
00209 Visit(node->catch_block());
00210 }
00211
00212
00213 void PrettyPrinter::VisitTryFinally(TryFinally* node) {
00214 Print("try ");
00215 Visit(node->try_block());
00216 Print(" finally ");
00217 Visit(node->finally_block());
00218 }
00219
00220
00221 void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
00222 Print("debugger ");
00223 }
00224
00225
00226 void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
00227 Print("(");
00228 PrintFunctionLiteral(node);
00229 Print(")");
00230 }
00231
00232
00233 void PrettyPrinter::VisitFunctionBoilerplateLiteral(
00234 FunctionBoilerplateLiteral* node) {
00235 Print("(");
00236 PrintLiteral(node->boilerplate(), true);
00237 Print(")");
00238 }
00239
00240
00241 void PrettyPrinter::VisitConditional(Conditional* node) {
00242 Visit(node->condition());
00243 Print(" ? ");
00244 Visit(node->then_expression());
00245 Print(" : ");
00246 Visit(node->else_expression());
00247 }
00248
00249
00250 void PrettyPrinter::VisitLiteral(Literal* node) {
00251 PrintLiteral(node->handle(), true);
00252 }
00253
00254
00255 void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
00256 Print(" RegExp(");
00257 PrintLiteral(node->pattern(), false);
00258 Print(",");
00259 PrintLiteral(node->flags(), false);
00260 Print(") ");
00261 }
00262
00263
00264 void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
00265 Print("{ ");
00266 for (int i = 0; i < node->properties()->length(); i++) {
00267 if (i != 0) Print(",");
00268 ObjectLiteral::Property* property = node->properties()->at(i);
00269 Print(" ");
00270 Visit(property->key());
00271 Print(": ");
00272 Visit(property->value());
00273 }
00274 Print(" }");
00275 }
00276
00277
00278 void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
00279 Print("[ ");
00280 for (int i = 0; i < node->values()->length(); i++) {
00281 if (i != 0) Print(",");
00282 Visit(node->values()->at(i));
00283 }
00284 Print(" ]");
00285 }
00286
00287
00288 void PrettyPrinter::VisitSlot(Slot* node) {
00289 switch (node->type()) {
00290 case Slot::PARAMETER:
00291 Print("parameter[%d]", node->index());
00292 break;
00293 case Slot::LOCAL:
00294 Print("frame[%d]", node->index());
00295 break;
00296 case Slot::CONTEXT:
00297 Print(".context[%d]", node->index());
00298 break;
00299 case Slot::LOOKUP:
00300 Print(".context[");
00301 PrintLiteral(node->var()->name(), false);
00302 Print("]");
00303 break;
00304 default:
00305 UNREACHABLE();
00306 }
00307 }
00308
00309
00310 void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
00311 PrintLiteral(node->name(), false);
00312 }
00313
00314
00315 void PrettyPrinter::VisitAssignment(Assignment* node) {
00316 Visit(node->target());
00317 Print(" %s ", Token::String(node->op()));
00318 Visit(node->value());
00319 }
00320
00321
00322 void PrettyPrinter::VisitThrow(Throw* node) {
00323 Print("throw ");
00324 Visit(node->exception());
00325 }
00326
00327
00328 void PrettyPrinter::VisitProperty(Property* node) {
00329 Expression* key = node->key();
00330 Literal* literal = key->AsLiteral();
00331 if (literal != NULL && literal->handle()->IsSymbol()) {
00332 Print("(");
00333 Visit(node->obj());
00334 Print(").");
00335 PrintLiteral(literal->handle(), false);
00336 } else {
00337 Visit(node->obj());
00338 Print("[");
00339 Visit(key);
00340 Print("]");
00341 }
00342 }
00343
00344
00345 void PrettyPrinter::VisitCall(Call* node) {
00346 Visit(node->expression());
00347 PrintArguments(node->arguments());
00348 }
00349
00350
00351 void PrettyPrinter::VisitCallNew(CallNew* node) {
00352 Print("new (");
00353 Visit(node->expression());
00354 Print(")");
00355 PrintArguments(node->arguments());
00356 }
00357
00358
00359 void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
00360 Print("%%");
00361 PrintLiteral(node->name(), false);
00362 PrintArguments(node->arguments());
00363 }
00364
00365
00366 void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
00367 Print("(%s", Token::String(node->op()));
00368 Visit(node->expression());
00369 Print(")");
00370 }
00371
00372
00373 void PrettyPrinter::VisitCountOperation(CountOperation* node) {
00374 Print("(");
00375 if (node->is_prefix()) Print("%s", Token::String(node->op()));
00376 Visit(node->expression());
00377 if (node->is_postfix()) Print("%s", Token::String(node->op()));
00378 Print(")");
00379 }
00380
00381
00382 void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
00383 Print("(");
00384 Visit(node->left());
00385 Print("%s", Token::String(node->op()));
00386 Visit(node->right());
00387 Print(")");
00388 }
00389
00390
00391 void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
00392 Print("(");
00393 Visit(node->left());
00394 Print("%s", Token::String(node->op()));
00395 Visit(node->right());
00396 Print(")");
00397 }
00398
00399
00400 void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
00401 Print("<this-function>");
00402 }
00403
00404
00405 const char* PrettyPrinter::Print(Node* node) {
00406 Init();
00407 Visit(node);
00408 return output_;
00409 }
00410
00411
00412 const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
00413 Init();
00414 ExpressionStatement* statement =
00415 program->body()->at(0)->AsExpressionStatement();
00416 Visit(statement->expression());
00417 return output_;
00418 }
00419
00420
00421 const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
00422 Init();
00423 PrintStatements(program->body());
00424 Print("\n");
00425 return output_;
00426 }
00427
00428
00429 void PrettyPrinter::PrintOut(Node* node) {
00430 PrettyPrinter printer;
00431 PrintF("%s", printer.Print(node));
00432 }
00433
00434
00435 void PrettyPrinter::Init() {
00436 if (size_ == 0) {
00437 ASSERT(output_ == NULL);
00438 const int initial_size = 256;
00439 output_ = NewArray<char>(initial_size);
00440 size_ = initial_size;
00441 }
00442 output_[0] = '\0';
00443 pos_ = 0;
00444 }
00445
00446
00447 void PrettyPrinter::Print(const char* format, ...) {
00448 for (;;) {
00449 va_list arguments;
00450 va_start(arguments, format);
00451 int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
00452 format,
00453 arguments);
00454 va_end(arguments);
00455
00456 if (n >= 0) {
00457
00458 pos_ += n;
00459 return;
00460 } else {
00461
00462 const int slack = 32;
00463 int new_size = size_ + (size_ >> 1) + slack;
00464 char* new_output = NewArray<char>(new_size);
00465 memcpy(new_output, output_, pos_);
00466 DeleteArray(output_);
00467 output_ = new_output;
00468 size_ = new_size;
00469 }
00470 }
00471 }
00472
00473
00474 void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
00475 for (int i = 0; i < statements->length(); i++) {
00476 if (i != 0) Print(" ");
00477 Visit(statements->at(i));
00478 }
00479 }
00480
00481
00482 void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
00483 if (labels != NULL) {
00484 for (int i = 0; i < labels->length(); i++) {
00485 PrintLiteral(labels->at(i), false);
00486 Print(": ");
00487 }
00488 }
00489 }
00490
00491
00492 void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
00493 Print("(");
00494 for (int i = 0; i < arguments->length(); i++) {
00495 if (i != 0) Print(", ");
00496 Visit(arguments->at(i));
00497 }
00498 Print(")");
00499 }
00500
00501
00502 void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
00503 Object* object = *value;
00504 if (object->IsString()) {
00505 String* string = String::cast(object);
00506 if (quote) Print("\"");
00507 for (int i = 0; i < string->length(); i++) {
00508 Print("%c", string->Get(i));
00509 }
00510 if (quote) Print("\"");
00511 } else if (object == Heap::null_value()) {
00512 Print("null");
00513 } else if (object == Heap::true_value()) {
00514 Print("true");
00515 } else if (object == Heap::false_value()) {
00516 Print("false");
00517 } else if (object == Heap::undefined_value()) {
00518 Print("undefined");
00519 } else if (object->IsNumber()) {
00520 Print("%g", object->Number());
00521 } else if (object->IsJSObject()) {
00522
00523 if (object->IsJSFunction()) {
00524 Print("JS-Function");
00525 } else if (object->IsJSArray()) {
00526 Print("JS-array[%u]", JSArray::cast(object)->length());
00527 } else if (object->IsJSObject()) {
00528 Print("JS-Object");
00529 } else {
00530 Print("?UNKNOWN?");
00531 }
00532 } else if (object->IsFixedArray()) {
00533 Print("FixedArray");
00534 } else {
00535 Print("<unknown literal %p>", object);
00536 }
00537 }
00538
00539
00540 void PrettyPrinter::PrintParameters(Scope* scope) {
00541 Print("(");
00542 for (int i = 0; i < scope->num_parameters(); i++) {
00543 if (i > 0) Print(", ");
00544 PrintLiteral(scope->parameter(i)->name(), false);
00545 }
00546 Print(")");
00547 }
00548
00549
00550 void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
00551 for (int i = 0; i < declarations->length(); i++) {
00552 if (i > 0) Print(" ");
00553 Visit(declarations->at(i));
00554 }
00555 }
00556
00557
00558 void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
00559 Print("function ");
00560 PrintLiteral(function->name(), false);
00561 PrintParameters(function->scope());
00562 Print(" { ");
00563 PrintDeclarations(function->scope()->declarations());
00564 PrintStatements(function->body());
00565 Print(" }");
00566 }
00567
00568
00569 void PrettyPrinter::PrintCaseClause(CaseClause* clause) {
00570 if (clause->is_default()) {
00571 Print("default");
00572 } else {
00573 Print("case ");
00574 Visit(clause->label());
00575 }
00576 Print(": ");
00577 PrintStatements(clause->statements());
00578 if (clause->statements()->length() > 0)
00579 Print(" ");
00580 }
00581
00582
00583
00584
00585 class IndentedScope BASE_EMBEDDED {
00586 public:
00587 IndentedScope() {
00588 ast_printer_->inc_indent();
00589 }
00590
00591 explicit IndentedScope(const char* txt, StaticType* type = NULL) {
00592 ast_printer_->PrintIndented(txt);
00593 if ((type != NULL) && (type->IsKnown())) {
00594 ast_printer_->Print(" (type = ");
00595 ast_printer_->Print(StaticType::Type2String(type));
00596 ast_printer_->Print(")");
00597 }
00598 ast_printer_->Print("\n");
00599 ast_printer_->inc_indent();
00600 }
00601
00602 virtual ~IndentedScope() {
00603 ast_printer_->dec_indent();
00604 }
00605
00606 static void SetAstPrinter(AstPrinter* a) { ast_printer_ = a; }
00607
00608 private:
00609 static AstPrinter* ast_printer_;
00610 };
00611
00612
00613 AstPrinter* IndentedScope::ast_printer_ = NULL;
00614
00615
00616
00617
00618 int AstPrinter::indent_ = 0;
00619
00620
00621 AstPrinter::AstPrinter() {
00622 ASSERT(indent_ == 0);
00623 IndentedScope::SetAstPrinter(this);
00624 }
00625
00626
00627 AstPrinter::~AstPrinter() {
00628 ASSERT(indent_ == 0);
00629 IndentedScope::SetAstPrinter(NULL);
00630 }
00631
00632
00633 void AstPrinter::PrintIndented(const char* txt) {
00634 for (int i = 0; i < indent_; i++) {
00635 Print(". ");
00636 }
00637 Print(txt);
00638 }
00639
00640
00641 void AstPrinter::PrintLiteralIndented(const char* info,
00642 Handle<Object> value,
00643 bool quote) {
00644 PrintIndented(info);
00645 Print(" ");
00646 PrintLiteral(value, quote);
00647 Print("\n");
00648 }
00649
00650
00651 void AstPrinter::PrintLiteralWithModeIndented(const char* info,
00652 Variable* var,
00653 Handle<Object> value,
00654 StaticType* type) {
00655 if (var == NULL) {
00656 PrintLiteralIndented(info, value, true);
00657 } else {
00658 EmbeddedVector<char, 256> buf;
00659 if (type->IsKnown()) {
00660 OS::SNPrintF(buf, "%s (mode = %s, type = %s)", info,
00661 Variable::Mode2String(var->mode()),
00662 StaticType::Type2String(type));
00663 } else {
00664 OS::SNPrintF(buf, "%s (mode = %s)", info,
00665 Variable::Mode2String(var->mode()));
00666 }
00667 PrintLiteralIndented(buf.start(), value, true);
00668 }
00669 }
00670
00671
00672 void AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) {
00673 if (labels != NULL && labels->length() > 0) {
00674 if (info == NULL) {
00675 PrintIndented("LABELS ");
00676 } else {
00677 PrintIndented(info);
00678 Print(" ");
00679 }
00680 PrintLabels(labels);
00681 Print("\n");
00682 } else if (info != NULL) {
00683 PrintIndented(info);
00684 }
00685 }
00686
00687
00688 void AstPrinter::PrintIndentedVisit(const char* s, Node* node) {
00689 IndentedScope indent(s);
00690 Visit(node);
00691 }
00692
00693
00694 const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
00695 Init();
00696 { IndentedScope indent("FUNC");
00697 PrintLiteralIndented("NAME", program->name(), true);
00698 PrintParameters(program->scope());
00699 PrintDeclarations(program->scope()->declarations());
00700 PrintStatements(program->body());
00701 }
00702 return Output();
00703 }
00704
00705
00706 void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
00707 if (declarations->length() > 0) {
00708 IndentedScope indent("DECLS");
00709 for (int i = 0; i < declarations->length(); i++) {
00710 Visit(declarations->at(i));
00711 }
00712 }
00713 }
00714
00715
00716 void AstPrinter::PrintParameters(Scope* scope) {
00717 if (scope->num_parameters() > 0) {
00718 IndentedScope indent("PARAMS");
00719 for (int i = 0; i < scope->num_parameters(); i++) {
00720 PrintLiteralWithModeIndented("VAR ", scope->parameter(i),
00721 scope->parameter(i)->name(),
00722 scope->parameter(i)->type());
00723 }
00724 }
00725 }
00726
00727
00728 void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
00729 for (int i = 0; i < statements->length(); i++) {
00730 Visit(statements->at(i));
00731 }
00732 }
00733
00734
00735 void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
00736 for (int i = 0; i < arguments->length(); i++) {
00737 Visit(arguments->at(i));
00738 }
00739 }
00740
00741
00742 void AstPrinter::PrintCaseClause(CaseClause* clause) {
00743 if (clause->is_default()) {
00744 IndentedScope indent("DEFAULT");
00745 PrintStatements(clause->statements());
00746 } else {
00747 IndentedScope indent("CASE");
00748 Visit(clause->label());
00749 PrintStatements(clause->statements());
00750 }
00751 }
00752
00753
00754 void AstPrinter::VisitBlock(Block* node) {
00755 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
00756 IndentedScope indent(block_txt);
00757 PrintStatements(node->statements());
00758 }
00759
00760
00761 void AstPrinter::VisitDeclaration(Declaration* node) {
00762 if (node->fun() == NULL) {
00763
00764 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
00765 node->proxy()->AsVariable(),
00766 node->proxy()->name(),
00767 node->proxy()->AsVariable()->type());
00768 } else {
00769
00770 PrintIndented("FUNCTION ");
00771 PrintLiteral(node->proxy()->name(), true);
00772 Print(" = function ");
00773 PrintLiteral(node->fun()->name(), false);
00774 Print("\n");
00775 }
00776 }
00777
00778
00779 void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
00780 Visit(node->expression());
00781 }
00782
00783
00784 void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
00785 PrintIndented("EMPTY\n");
00786 }
00787
00788
00789 void AstPrinter::VisitIfStatement(IfStatement* node) {
00790 PrintIndentedVisit("IF", node->condition());
00791 PrintIndentedVisit("THEN", node->then_statement());
00792 if (node->HasElseStatement()) {
00793 PrintIndentedVisit("ELSE", node->else_statement());
00794 }
00795 }
00796
00797
00798 void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
00799 PrintLabelsIndented("CONTINUE", node->target()->labels());
00800 }
00801
00802
00803 void AstPrinter::VisitBreakStatement(BreakStatement* node) {
00804 PrintLabelsIndented("BREAK", node->target()->labels());
00805 }
00806
00807
00808 void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
00809 PrintIndentedVisit("RETURN", node->expression());
00810 }
00811
00812
00813 void AstPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
00814 PrintIndentedVisit("WITH ENTER", node->expression());
00815 }
00816
00817
00818 void AstPrinter::VisitWithExitStatement(WithExitStatement* node) {
00819 PrintIndented("WITH EXIT\n");
00820 }
00821
00822
00823 void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
00824 IndentedScope indent("SWITCH");
00825 PrintLabelsIndented(NULL, node->labels());
00826 PrintIndentedVisit("TAG", node->tag());
00827 for (int i = 0; i < node->cases()->length(); i++) {
00828 PrintCaseClause(node->cases()->at(i));
00829 }
00830 }
00831
00832
00833 void AstPrinter::VisitLoopStatement(LoopStatement* node) {
00834 IndentedScope indent(node->OperatorString());
00835 PrintLabelsIndented(NULL, node->labels());
00836 if (node->init()) PrintIndentedVisit("INIT", node->init());
00837 if (node->cond()) PrintIndentedVisit("COND", node->cond());
00838 if (node->body()) PrintIndentedVisit("BODY", node->body());
00839 if (node->next()) PrintIndentedVisit("NEXT", node->next());
00840 }
00841
00842
00843 void AstPrinter::VisitForInStatement(ForInStatement* node) {
00844 IndentedScope indent("FOR IN");
00845 PrintIndentedVisit("FOR", node->each());
00846 PrintIndentedVisit("IN", node->enumerable());
00847 PrintIndentedVisit("BODY", node->body());
00848 }
00849
00850
00851 void AstPrinter::VisitTryCatch(TryCatch* node) {
00852 IndentedScope indent("TRY CATCH");
00853 PrintIndentedVisit("TRY", node->try_block());
00854 PrintIndentedVisit("CATCHVAR", node->catch_var());
00855 PrintIndentedVisit("CATCH", node->catch_block());
00856 }
00857
00858
00859 void AstPrinter::VisitTryFinally(TryFinally* node) {
00860 IndentedScope indent("TRY FINALLY");
00861 PrintIndentedVisit("TRY", node->try_block());
00862 PrintIndentedVisit("FINALLY", node->finally_block());
00863 }
00864
00865
00866 void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
00867 IndentedScope indent("DEBUGGER");
00868 }
00869
00870
00871 void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
00872 IndentedScope indent("FUNC LITERAL");
00873 PrintLiteralIndented("NAME", node->name(), false);
00874 PrintParameters(node->scope());
00875
00876
00877
00878
00879 }
00880
00881
00882 void AstPrinter::VisitFunctionBoilerplateLiteral(
00883 FunctionBoilerplateLiteral* node) {
00884 IndentedScope indent("FUNC LITERAL");
00885 PrintLiteralIndented("BOILERPLATE", node->boilerplate(), true);
00886 }
00887
00888
00889 void AstPrinter::VisitConditional(Conditional* node) {
00890 IndentedScope indent("CONDITIONAL");
00891 PrintIndentedVisit("?", node->condition());
00892 PrintIndentedVisit("THEN", node->then_expression());
00893 PrintIndentedVisit("ELSE", node->else_expression());
00894 }
00895
00896
00897 void AstPrinter::VisitLiteral(Literal* node) {
00898 PrintLiteralIndented("LITERAL", node->handle(), true);
00899 }
00900
00901
00902 void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
00903 IndentedScope indent("REGEXP LITERAL");
00904 PrintLiteral(node->pattern(), false);
00905 Print(",");
00906 PrintLiteral(node->flags(), false);
00907 }
00908
00909
00910 void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
00911 IndentedScope indent("OBJ LITERAL");
00912 for (int i = 0; i < node->properties()->length(); i++) {
00913 const char* prop_kind = NULL;
00914 switch (node->properties()->at(i)->kind()) {
00915 case ObjectLiteral::Property::CONSTANT:
00916 prop_kind = "PROPERTY - CONSTANT";
00917 break;
00918 case ObjectLiteral::Property::COMPUTED:
00919 prop_kind = "PROPERTY - COMPUTED";
00920 break;
00921 case ObjectLiteral::Property::PROTOTYPE:
00922 prop_kind = "PROPERTY - PROTOTYPE";
00923 break;
00924 case ObjectLiteral::Property::GETTER:
00925 prop_kind = "PROPERTY - GETTER";
00926 break;
00927 case ObjectLiteral::Property::SETTER:
00928 prop_kind = "PROPERTY - SETTER";
00929 break;
00930 default:
00931 UNREACHABLE();
00932 break;
00933 }
00934 IndentedScope prop(prop_kind);
00935 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
00936 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
00937 }
00938 }
00939
00940
00941 void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
00942 IndentedScope indent("ARRAY LITERAL");
00943 if (node->values()->length() > 0) {
00944 IndentedScope indent("VALUES");
00945 for (int i = 0; i < node->values()->length(); i++) {
00946 Visit(node->values()->at(i));
00947 }
00948 }
00949 }
00950
00951
00952 void AstPrinter::VisitSlot(Slot* node) {
00953 PrintIndented("SLOT ");
00954 switch (node->type()) {
00955 case Slot::PARAMETER:
00956 Print("parameter[%d]", node->index());
00957 break;
00958 case Slot::LOCAL:
00959 Print("frame[%d]", node->index());
00960 break;
00961 case Slot::CONTEXT:
00962 Print(".context[%d]", node->index());
00963 break;
00964 case Slot::LOOKUP:
00965 Print(".context[");
00966 PrintLiteral(node->var()->name(), false);
00967 Print("]");
00968 break;
00969 default:
00970 UNREACHABLE();
00971 }
00972 Print("\n");
00973 }
00974
00975
00976 void AstPrinter::VisitVariableProxy(VariableProxy* node) {
00977 PrintLiteralWithModeIndented("VAR PROXY", node->AsVariable(), node->name(),
00978 node->type());
00979 Variable* var = node->var();
00980 if (var != NULL && var->rewrite() != NULL) {
00981 IndentedScope indent;
00982 Visit(var->rewrite());
00983 }
00984 }
00985
00986
00987 void AstPrinter::VisitAssignment(Assignment* node) {
00988 IndentedScope indent(Token::Name(node->op()), node->type());
00989 Visit(node->target());
00990 Visit(node->value());
00991 }
00992
00993
00994 void AstPrinter::VisitThrow(Throw* node) {
00995 PrintIndentedVisit("THROW", node->exception());
00996 }
00997
00998
00999 void AstPrinter::VisitProperty(Property* node) {
01000 IndentedScope indent("PROPERTY");
01001 Visit(node->obj());
01002 Literal* literal = node->key()->AsLiteral();
01003 if (literal != NULL && literal->handle()->IsSymbol()) {
01004 PrintLiteralIndented("LITERAL", literal->handle(), false);
01005 } else {
01006 PrintIndentedVisit("KEY", node->key());
01007 }
01008 }
01009
01010
01011 void AstPrinter::VisitCall(Call* node) {
01012 IndentedScope indent("CALL");
01013 Visit(node->expression());
01014 PrintArguments(node->arguments());
01015 }
01016
01017
01018 void AstPrinter::VisitCallNew(CallNew* node) {
01019 IndentedScope indent("CALL NEW");
01020 Visit(node->expression());
01021 PrintArguments(node->arguments());
01022 }
01023
01024
01025 void AstPrinter::VisitCallRuntime(CallRuntime* node) {
01026 PrintLiteralIndented("CALL RUNTIME ", node->name(), false);
01027 IndentedScope indent;
01028 PrintArguments(node->arguments());
01029 }
01030
01031
01032 void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
01033 PrintIndentedVisit(Token::Name(node->op()), node->expression());
01034 }
01035
01036
01037 void AstPrinter::VisitCountOperation(CountOperation* node) {
01038 EmbeddedVector<char, 128> buf;
01039 if (node->type()->IsKnown()) {
01040 OS::SNPrintF(buf, "%s %s (type = %s)",
01041 (node->is_prefix() ? "PRE" : "POST"),
01042 Token::Name(node->op()),
01043 StaticType::Type2String(node->type()));
01044 } else {
01045 OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
01046 Token::Name(node->op()));
01047 }
01048 PrintIndentedVisit(buf.start(), node->expression());
01049 }
01050
01051
01052 void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
01053 IndentedScope indent(Token::Name(node->op()), node->type());
01054 Visit(node->left());
01055 Visit(node->right());
01056 }
01057
01058
01059 void AstPrinter::VisitCompareOperation(CompareOperation* node) {
01060 IndentedScope indent(Token::Name(node->op()), node->type());
01061 Visit(node->left());
01062 Visit(node->right());
01063 }
01064
01065
01066 void AstPrinter::VisitThisFunction(ThisFunction* node) {
01067 IndentedScope indent("THIS-FUNCTION");
01068 }
01069
01070
01071
01072 #endif // DEBUG
01073
01074 } }