LCOV - code coverage report
Current view: top level - src/ast - prettyprinter.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 232 279 83.2 %
Date: 2017-04-26 Functions: 40 59 67.8 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/ast/prettyprinter.h"
       6             : 
       7             : #include <stdarg.h>
       8             : 
       9             : #include "src/ast/ast-value-factory.h"
      10             : #include "src/ast/scopes.h"
      11             : #include "src/base/platform/platform.h"
      12             : #include "src/globals.h"
      13             : #include "src/objects-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18        8810 : CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js)
      19        8810 :     : builder_(isolate) {
      20        8810 :   isolate_ = isolate;
      21        8810 :   position_ = 0;
      22        8810 :   num_prints_ = 0;
      23        8810 :   found_ = false;
      24        8810 :   done_ = false;
      25        8810 :   is_user_js_ = is_user_js;
      26             :   InitializeAstVisitor(isolate);
      27        8810 : }
      28             : 
      29        8810 : Handle<String> CallPrinter::Print(FunctionLiteral* program, int position) {
      30        8810 :   num_prints_ = 0;
      31        8810 :   position_ = position;
      32        8810 :   Find(program);
      33       17620 :   return builder_.Finish().ToHandleChecked();
      34             : }
      35             : 
      36             : 
      37      323781 : void CallPrinter::Find(AstNode* node, bool print) {
      38      323781 :   if (done_) return;
      39      311334 :   if (found_) {
      40       17279 :     if (print) {
      41       14425 :       int prev_num_prints = num_prints_;
      42       14425 :       Visit(node);
      43       14425 :       if (prev_num_prints != num_prints_) return;
      44             :     }
      45        2911 :     Print("(intermediate value)");
      46             :   } else {
      47      294055 :     Visit(node);
      48             :   }
      49             : }
      50             : 
      51      181176 : void CallPrinter::Print(const char* str) {
      52      362352 :   if (!found_ || done_) return;
      53       11504 :   num_prints_++;
      54       11504 :   builder_.AppendCString(str);
      55             : }
      56             : 
      57      108184 : void CallPrinter::Print(Handle<String> str) {
      58      216368 :   if (!found_ || done_) return;
      59       10708 :   num_prints_++;
      60       10708 :   builder_.AppendString(str);
      61             : }
      62             : 
      63           0 : void CallPrinter::VisitBlock(Block* node) {
      64       24993 :   FindStatements(node->statements());
      65           0 : }
      66             : 
      67             : 
      68           0 : void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
      69             : 
      70             : 
      71           0 : void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
      72             : 
      73             : 
      74       37150 : void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
      75       37150 :   Find(node->expression());
      76       37150 : }
      77             : 
      78             : 
      79           0 : void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
      80             : 
      81             : 
      82          56 : void CallPrinter::VisitSloppyBlockFunctionStatement(
      83          56 :     SloppyBlockFunctionStatement* node) {
      84          56 :   Find(node->statement());
      85          56 : }
      86             : 
      87             : 
      88       21371 : void CallPrinter::VisitIfStatement(IfStatement* node) {
      89        8446 :   Find(node->condition());
      90        8446 :   Find(node->then_statement());
      91        8446 :   if (node->HasElseStatement()) {
      92        4479 :     Find(node->else_statement());
      93             :   }
      94        8446 : }
      95             : 
      96             : 
      97           0 : void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
      98             : 
      99             : 
     100           0 : void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
     101             : 
     102             : 
     103        2895 : void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
     104        2895 :   Find(node->expression());
     105        2895 : }
     106             : 
     107             : 
     108           0 : void CallPrinter::VisitWithStatement(WithStatement* node) {
     109           0 :   Find(node->expression());
     110           0 :   Find(node->statement());
     111           0 : }
     112             : 
     113             : 
     114         168 : void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
     115          84 :   Find(node->tag());
     116             :   ZoneList<CaseClause*>* cases = node->cases();
     117         322 :   for (int i = 0; i < cases->length(); i++) Find(cases->at(i));
     118          84 : }
     119             : 
     120             : 
     121         476 : void CallPrinter::VisitCaseClause(CaseClause* clause) {
     122         238 :   if (!clause->is_default()) {
     123         238 :     Find(clause->label());
     124             :   }
     125         238 :   FindStatements(clause->statements());
     126         238 : }
     127             : 
     128             : 
     129           0 : void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
     130           0 :   Find(node->body());
     131           0 :   Find(node->cond());
     132           0 : }
     133             : 
     134             : 
     135         154 : void CallPrinter::VisitWhileStatement(WhileStatement* node) {
     136         154 :   Find(node->cond());
     137         154 :   Find(node->body());
     138         154 : }
     139             : 
     140             : 
     141        1515 : void CallPrinter::VisitForStatement(ForStatement* node) {
     142         505 :   if (node->init() != NULL) {
     143         505 :     Find(node->init());
     144             :   }
     145         505 :   if (node->cond() != NULL) Find(node->cond());
     146         505 :   if (node->next() != NULL) Find(node->next());
     147         505 :   Find(node->body());
     148         505 : }
     149             : 
     150             : 
     151          45 : void CallPrinter::VisitForInStatement(ForInStatement* node) {
     152          45 :   Find(node->each());
     153          45 :   Find(node->enumerable());
     154          45 :   Find(node->body());
     155          45 : }
     156             : 
     157             : 
     158        2020 : void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
     159         505 :   Find(node->assign_iterator());
     160         505 :   Find(node->next_result());
     161         505 :   Find(node->result_done());
     162         505 :   Find(node->assign_each());
     163         505 :   Find(node->body());
     164         505 : }
     165             : 
     166             : 
     167        6542 : void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
     168        3271 :   Find(node->try_block());
     169        3271 :   Find(node->catch_block());
     170        3271 : }
     171             : 
     172             : 
     173        2160 : void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
     174        1080 :   Find(node->try_block());
     175        1080 :   Find(node->finally_block());
     176        1080 : }
     177             : 
     178             : 
     179           0 : void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
     180             : 
     181             : 
     182        9036 : void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
     183        9036 :   FindStatements(node->body());
     184           0 : }
     185             : 
     186             : 
     187           0 : void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
     188           0 :   if (node->extends()) Find(node->extends());
     189           0 :   for (int i = 0; i < node->properties()->length(); i++) {
     190           0 :     Find(node->properties()->at(i)->value());
     191             :   }
     192           0 : }
     193             : 
     194             : 
     195           0 : void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
     196             : 
     197             : 
     198        2815 : void CallPrinter::VisitDoExpression(DoExpression* node) { Find(node->block()); }
     199             : 
     200             : 
     201         519 : void CallPrinter::VisitConditional(Conditional* node) {
     202         173 :   Find(node->condition());
     203         173 :   Find(node->then_expression());
     204         173 :   Find(node->else_expression());
     205         173 : }
     206             : 
     207             : 
     208       27685 : void CallPrinter::VisitLiteral(Literal* node) {
     209       27685 :   PrintLiteral(node->value(), true);
     210       27685 : }
     211             : 
     212             : 
     213        1239 : void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
     214         177 :   Print("/");
     215         177 :   PrintLiteral(node->pattern(), false);
     216         177 :   Print("/");
     217         177 :   if (node->flags() & RegExp::kGlobal) Print("g");
     218         177 :   if (node->flags() & RegExp::kIgnoreCase) Print("i");
     219         177 :   if (node->flags() & RegExp::kMultiline) Print("m");
     220         177 :   if (node->flags() & RegExp::kUnicode) Print("u");
     221         177 :   if (node->flags() & RegExp::kSticky) Print("y");
     222         177 : }
     223             : 
     224             : 
     225        3074 : void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
     226        3994 :   for (int i = 0; i < node->properties()->length(); i++) {
     227         920 :     Find(node->properties()->at(i)->value());
     228             :   }
     229        1077 : }
     230             : 
     231             : 
     232       15104 : void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
     233         766 :   Print("[");
     234       15104 :   for (int i = 0; i < node->values()->length(); i++) {
     235        6786 :     if (i != 0) Print(",");
     236        6786 :     Find(node->values()->at(i), true);
     237             :   }
     238         766 :   Print("]");
     239         766 : }
     240             : 
     241             : 
     242       81934 : void CallPrinter::VisitVariableProxy(VariableProxy* node) {
     243       81934 :   if (is_user_js_) {
     244       54295 :     PrintLiteral(node->name(), false);
     245             :   } else {
     246             :     // Variable names of non-user code are meaningless due to minification.
     247       27639 :     Print("(var)");
     248             :   }
     249       81934 : }
     250             : 
     251             : 
     252       33350 : void CallPrinter::VisitAssignment(Assignment* node) {
     253       16675 :   Find(node->target());
     254       16675 :   Find(node->value());
     255       16675 : }
     256             : 
     257         196 : void CallPrinter::VisitSuspend(Suspend* node) { Find(node->expression()); }
     258             : 
     259        2355 : void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
     260             : 
     261             : 
     262       65062 : void CallPrinter::VisitProperty(Property* node) {
     263             :   Expression* key = node->key();
     264       94897 :   Literal* literal = key->AsLiteral();
     265       63820 :   if (literal != NULL && literal->value()->IsInternalizedString()) {
     266       31077 :     Find(node->obj(), true);
     267       31077 :     Print(".");
     268       31077 :     PrintLiteral(literal->value(), false);
     269             :   } else {
     270        1454 :     Find(node->obj(), true);
     271        1454 :     Print("[");
     272        1454 :     Find(key, true);
     273        1454 :     Print("]");
     274             :   }
     275       32531 : }
     276             : 
     277             : 
     278       50886 : void CallPrinter::VisitCall(Call* node) {
     279       16962 :   bool was_found = !found_ && node->position() == position_;
     280       16962 :   if (was_found) {
     281             :     // Bail out if the error is caused by a direct call to a variable in
     282             :     // non-user JS code. The variable name is meaningless due to minification.
     283        5619 :     if (!is_user_js_ && node->expression()->IsVariableProxy()) {
     284           0 :       done_ = true;
     285       16962 :       return;
     286             :     }
     287        5619 :     found_ = true;
     288             :   }
     289       16962 :   Find(node->expression(), true);
     290       16962 :   if (!was_found) Print("(...)");
     291       16962 :   FindArguments(node->arguments());
     292       16962 :   if (was_found) done_ = true;
     293             : }
     294             : 
     295             : 
     296       11124 : void CallPrinter::VisitCallNew(CallNew* node) {
     297        3708 :   bool was_found = !found_ && node->position() == position_;
     298        3708 :   if (was_found) {
     299             :     // Bail out if the error is caused by a direct call to a variable in
     300             :     // non-user JS code. The variable name is meaningless due to minification.
     301        1476 :     if (!is_user_js_ && node->expression()->IsVariableProxy()) {
     302           0 :       done_ = true;
     303        3708 :       return;
     304             :     }
     305        1476 :     found_ = true;
     306             :   }
     307        7416 :   Find(node->expression(), was_found);
     308        3708 :   FindArguments(node->arguments());
     309        3708 :   if (was_found) done_ = true;
     310             : }
     311             : 
     312             : 
     313       11908 : void CallPrinter::VisitCallRuntime(CallRuntime* node) {
     314       11908 :   FindArguments(node->arguments());
     315       11908 : }
     316             : 
     317             : 
     318       11988 : void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
     319             :   Token::Value op = node->op();
     320             :   bool needsSpace =
     321        5994 :       op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
     322        5994 :   Print("(");
     323        5994 :   Print(Token::String(op));
     324        5994 :   if (needsSpace) Print(" ");
     325        5994 :   Find(node->expression(), true);
     326        5994 :   Print(")");
     327        5994 : }
     328             : 
     329             : 
     330        1980 : void CallPrinter::VisitCountOperation(CountOperation* node) {
     331         660 :   Print("(");
     332         800 :   if (node->is_prefix()) Print(Token::String(node->op()));
     333         660 :   Find(node->expression(), true);
     334        1180 :   if (node->is_postfix()) Print(Token::String(node->op()));
     335         660 :   Print(")");
     336         660 : }
     337             : 
     338             : 
     339        8972 : void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
     340        2243 :   Print("(");
     341        2243 :   Find(node->left(), true);
     342        2243 :   Print(" ");
     343        2243 :   Print(Token::String(node->op()));
     344        2243 :   Print(" ");
     345        2243 :   Find(node->right(), true);
     346        2243 :   Print(")");
     347        2243 : }
     348             : 
     349             : 
     350       31860 : void CallPrinter::VisitCompareOperation(CompareOperation* node) {
     351        7965 :   Print("(");
     352        7965 :   Find(node->left(), true);
     353        7965 :   Print(" ");
     354        7965 :   Print(Token::String(node->op()));
     355        7965 :   Print(" ");
     356        7965 :   Find(node->right(), true);
     357        7965 :   Print(")");
     358        7965 : }
     359             : 
     360             : 
     361           0 : void CallPrinter::VisitSpread(Spread* node) {
     362           0 :   Print("(...");
     363           0 :   Find(node->expression(), true);
     364           0 :   Print(")");
     365           0 : }
     366             : 
     367             : 
     368           0 : void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
     369           0 :   UNREACHABLE();
     370             : }
     371             : 
     372        2649 : void CallPrinter::VisitGetIterator(GetIterator* node) {
     373             :   // Because CallPrinter is used by RenderCallSite() in runtime-internal.cc,
     374             :   // and the GetIterator node results in a Call, either to a [@@iterator] or
     375             :   // [@@asyncIterator]. It's unknown which call this error refers to, so we
     376             :   // assume it's the first call.
     377         883 :   bool was_found = !found_ && node->position() == position_;
     378         883 :   if (was_found) {
     379          84 :     found_ = true;
     380             :   }
     381         883 :   Find(node->iterable(), true);
     382             :   Print(node->hint() == IteratorType::kNormal ? "[Symbol.iterator]"
     383         883 :                                               : "[Symbol.asyncIterator]");
     384         883 :   if (was_found) done_ = true;
     385         883 : }
     386             : 
     387           0 : void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
     388           0 :   Print("ImportCall(");
     389           0 :   Find(node->argument(), true);
     390           0 :   Print(")");
     391           0 : }
     392             : 
     393           0 : void CallPrinter::VisitThisFunction(ThisFunction* node) {}
     394             : 
     395             : 
     396           0 : void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
     397             : 
     398             : 
     399           0 : void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
     400           0 :   Print("super");
     401           0 : }
     402             : 
     403             : 
     404          98 : void CallPrinter::VisitRewritableExpression(RewritableExpression* node) {
     405          98 :   Find(node->expression());
     406          98 : }
     407             : 
     408             : 
     409       34267 : void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
     410       68534 :   if (statements == NULL) return;
     411      173457 :   for (int i = 0; i < statements->length(); i++) {
     412      173457 :     Find(statements->at(i));
     413             :   }
     414             : }
     415             : 
     416             : 
     417       32578 : void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) {
     418       65156 :   if (found_) return;
     419      104964 :   for (int i = 0; i < arguments->length(); i++) {
     420      104964 :     Find(arguments->at(i));
     421             :   }
     422             : }
     423             : 
     424      113234 : void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
     425      113234 :   if (value->IsString()) {
     426       93961 :     if (quote) Print("\"");
     427       93961 :     Print(Handle<String>::cast(value));
     428       93961 :     if (quote) Print("\"");
     429       38546 :   } else if (value->IsNull(isolate_)) {
     430        1634 :     Print("null");
     431       35278 :   } else if (value->IsTrue(isolate_)) {
     432        1263 :     Print("true");
     433       32752 :   } else if (value->IsFalse(isolate_)) {
     434        1578 :     Print("false");
     435       29596 :   } else if (value->IsUndefined(isolate_)) {
     436         575 :     Print("undefined");
     437       14223 :   } else if (value->IsNumber()) {
     438       14223 :     Print(isolate_->factory()->NumberToString(value));
     439           0 :   } else if (value->IsSymbol()) {
     440             :     // Symbols can only occur as literals if they were inserted by the parser.
     441           0 :     PrintLiteral(handle(Handle<Symbol>::cast(value)->name(), isolate_), false);
     442             :   }
     443      113234 : }
     444             : 
     445             : 
     446           0 : void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
     447           0 :   PrintLiteral(value->string(), quote);
     448           0 : }
     449             : 
     450             : 
     451             : //-----------------------------------------------------------------------------
     452             : 
     453             : 
     454             : #ifdef DEBUG
     455             : 
     456             : // A helper for ast nodes that use FeedbackSlots.
     457             : static int FormatSlotNode(Vector<char>* buf, Expression* node,
     458             :                           const char* node_name, FeedbackSlot slot) {
     459             :   int pos = SNPrintF(*buf, "%s", node_name);
     460             :   if (!slot.IsInvalid()) {
     461             :     pos += SNPrintF(*buf + pos, " Slot(%d)", slot.ToInt());
     462             :   }
     463             :   return pos;
     464             : }
     465             : 
     466             : const char* AstPrinter::Print(AstNode* node) {
     467             :   Init();
     468             :   Visit(node);
     469             :   return output_;
     470             : }
     471             : 
     472             : void AstPrinter::Init() {
     473             :   if (size_ == 0) {
     474             :     DCHECK(output_ == NULL);
     475             :     const int initial_size = 256;
     476             :     output_ = NewArray<char>(initial_size);
     477             :     size_ = initial_size;
     478             :   }
     479             :   output_[0] = '\0';
     480             :   pos_ = 0;
     481             : }
     482             : 
     483             : void AstPrinter::Print(const char* format, ...) {
     484             :   for (;;) {
     485             :     va_list arguments;
     486             :     va_start(arguments, format);
     487             :     int n = VSNPrintF(Vector<char>(output_, size_) + pos_,
     488             :                       format,
     489             :                       arguments);
     490             :     va_end(arguments);
     491             : 
     492             :     if (n >= 0) {
     493             :       // there was enough space - we are done
     494             :       pos_ += n;
     495             :       return;
     496             :     } else {
     497             :       // there was not enough space - allocate more and try again
     498             :       const int slack = 32;
     499             :       int new_size = size_ + (size_ >> 1) + slack;
     500             :       char* new_output = NewArray<char>(new_size);
     501             :       MemCopy(new_output, output_, pos_);
     502             :       DeleteArray(output_);
     503             :       output_ = new_output;
     504             :       size_ = new_size;
     505             :     }
     506             :   }
     507             : }
     508             : 
     509             : void AstPrinter::PrintLabels(ZoneList<const AstRawString*>* labels) {
     510             :   if (labels != NULL) {
     511             :     for (int i = 0; i < labels->length(); i++) {
     512             :       PrintLiteral(labels->at(i), false);
     513             :       Print(": ");
     514             :     }
     515             :   }
     516             : }
     517             : 
     518             : void AstPrinter::PrintLiteral(Handle<Object> value, bool quote) {
     519             :   Object* object = *value;
     520             :   if (object->IsString()) {
     521             :     String* string = String::cast(object);
     522             :     if (quote) Print("\"");
     523             :     for (int i = 0; i < string->length(); i++) {
     524             :       Print("%c", string->Get(i));
     525             :     }
     526             :     if (quote) Print("\"");
     527             :   } else if (object->IsNull(isolate_)) {
     528             :     Print("null");
     529             :   } else if (object->IsTrue(isolate_)) {
     530             :     Print("true");
     531             :   } else if (object->IsFalse(isolate_)) {
     532             :     Print("false");
     533             :   } else if (object->IsUndefined(isolate_)) {
     534             :     Print("undefined");
     535             :   } else if (object->IsNumber()) {
     536             :     Print("%g", object->Number());
     537             :   } else if (object->IsJSObject()) {
     538             :     // regular expression
     539             :     if (object->IsJSFunction()) {
     540             :       Print("JS-Function");
     541             :     } else if (object->IsJSArray()) {
     542             :       Print("JS-array[%u]",
     543             :             Smi::cast(JSArray::cast(object)->length())->value());
     544             :     } else if (object->IsJSObject()) {
     545             :       Print("JS-Object");
     546             :     } else {
     547             :       Print("?UNKNOWN?");
     548             :     }
     549             :   } else if (object->IsFixedArray()) {
     550             :     Print("FixedArray");
     551             :   } else if (object->IsSymbol()) {
     552             :     // Symbols can only occur as literals if they were inserted by the parser.
     553             :     Symbol* symbol = Symbol::cast(object);
     554             :     if (symbol->name()->IsString()) {
     555             :       int length = 0;
     556             :       String* string = String::cast(symbol->name());
     557             :       std::unique_ptr<char[]> desc = string->ToCString(
     558             :           ALLOW_NULLS, FAST_STRING_TRAVERSAL, 0, string->length(), &length);
     559             :       Print("Symbol(%*s)", length, desc.get());
     560             :     } else {
     561             :       Print("Symbol()");
     562             :     }
     563             :   } else {
     564             :     Print("<unknown literal %p>", static_cast<void*>(object));
     565             :   }
     566             : }
     567             : 
     568             : void AstPrinter::PrintLiteral(const AstRawString* value, bool quote) {
     569             :   PrintLiteral(value->string(), quote);
     570             : }
     571             : 
     572             : 
     573             : //-----------------------------------------------------------------------------
     574             : 
     575             : class IndentedScope BASE_EMBEDDED {
     576             :  public:
     577             :   IndentedScope(AstPrinter* printer, const char* txt)
     578             :       : ast_printer_(printer) {
     579             :     ast_printer_->PrintIndented(txt);
     580             :     ast_printer_->Print("\n");
     581             :     ast_printer_->inc_indent();
     582             :   }
     583             : 
     584             :   IndentedScope(AstPrinter* printer, const char* txt, int pos)
     585             :       : ast_printer_(printer) {
     586             :     ast_printer_->PrintIndented(txt);
     587             :     ast_printer_->Print(" at %d\n", pos);
     588             :     ast_printer_->inc_indent();
     589             :   }
     590             : 
     591             :   virtual ~IndentedScope() {
     592             :     ast_printer_->dec_indent();
     593             :   }
     594             : 
     595             :  private:
     596             :   AstPrinter* ast_printer_;
     597             : };
     598             : 
     599             : 
     600             : //-----------------------------------------------------------------------------
     601             : 
     602             : AstPrinter::AstPrinter(Isolate* isolate)
     603             :     : isolate_(isolate), output_(nullptr), size_(0), pos_(0), indent_(0) {
     604             :   InitializeAstVisitor(isolate);
     605             : }
     606             : 
     607             : AstPrinter::~AstPrinter() {
     608             :   DCHECK(indent_ == 0);
     609             :   DeleteArray(output_);
     610             : }
     611             : 
     612             : 
     613             : void AstPrinter::PrintIndented(const char* txt) {
     614             :   for (int i = 0; i < indent_; i++) {
     615             :     Print(". ");
     616             :   }
     617             :   Print("%s", txt);
     618             : }
     619             : 
     620             : 
     621             : void AstPrinter::PrintLiteralIndented(const char* info,
     622             :                                       Handle<Object> value,
     623             :                                       bool quote) {
     624             :   PrintIndented(info);
     625             :   Print(" ");
     626             :   PrintLiteral(value, quote);
     627             :   Print("\n");
     628             : }
     629             : 
     630             : 
     631             : void AstPrinter::PrintLiteralWithModeIndented(const char* info,
     632             :                                               Variable* var,
     633             :                                               Handle<Object> value) {
     634             :   if (var == NULL) {
     635             :     PrintLiteralIndented(info, value, true);
     636             :   } else {
     637             :     EmbeddedVector<char, 256> buf;
     638             :     int pos =
     639             :         SNPrintF(buf, "%s (%p) (mode = %s", info, reinterpret_cast<void*>(var),
     640             :                  VariableMode2String(var->mode()));
     641             :     SNPrintF(buf + pos, ")");
     642             :     PrintLiteralIndented(buf.start(), value, true);
     643             :   }
     644             : }
     645             : 
     646             : 
     647             : void AstPrinter::PrintLabelsIndented(ZoneList<const AstRawString*>* labels) {
     648             :   if (labels == NULL || labels->length() == 0) return;
     649             :   PrintIndented("LABELS ");
     650             :   PrintLabels(labels);
     651             :   Print("\n");
     652             : }
     653             : 
     654             : 
     655             : void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
     656             :   IndentedScope indent(this, s, node->position());
     657             :   Visit(node);
     658             : }
     659             : 
     660             : 
     661             : const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
     662             :   Init();
     663             :   { IndentedScope indent(this, "FUNC", program->position());
     664             :     PrintIndented("KIND");
     665             :     Print(" %d\n", program->kind());
     666             :     PrintIndented("SUSPEND COUNT");
     667             :     Print(" %d\n", program->suspend_count());
     668             :     PrintLiteralIndented("NAME", program->name(), true);
     669             :     PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
     670             :     PrintParameters(program->scope());
     671             :     PrintDeclarations(program->scope()->declarations());
     672             :     PrintStatements(program->body());
     673             :   }
     674             :   return output_;
     675             : }
     676             : 
     677             : 
     678             : void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) {
     679             :   AstPrinter printer(isolate);
     680             :   printer.Init();
     681             :   printer.Visit(node);
     682             :   PrintF("%s", printer.output_);
     683             : }
     684             : 
     685             : void AstPrinter::PrintDeclarations(Declaration::List* declarations) {
     686             :   if (!declarations->is_empty()) {
     687             :     IndentedScope indent(this, "DECLS");
     688             :     for (Declaration* decl : *declarations) Visit(decl);
     689             :   }
     690             : }
     691             : 
     692             : void AstPrinter::PrintParameters(DeclarationScope* scope) {
     693             :   if (scope->num_parameters() > 0) {
     694             :     IndentedScope indent(this, "PARAMS");
     695             :     for (int i = 0; i < scope->num_parameters(); i++) {
     696             :       PrintLiteralWithModeIndented("VAR", scope->parameter(i),
     697             :                                    scope->parameter(i)->name());
     698             :     }
     699             :   }
     700             : }
     701             : 
     702             : 
     703             : void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
     704             :   for (int i = 0; i < statements->length(); i++) {
     705             :     Visit(statements->at(i));
     706             :   }
     707             : }
     708             : 
     709             : 
     710             : void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
     711             :   for (int i = 0; i < arguments->length(); i++) {
     712             :     Visit(arguments->at(i));
     713             :   }
     714             : }
     715             : 
     716             : 
     717             : void AstPrinter::VisitBlock(Block* node) {
     718             :   const char* block_txt =
     719             :       node->ignore_completion_value() ? "BLOCK NOCOMPLETIONS" : "BLOCK";
     720             :   IndentedScope indent(this, block_txt, node->position());
     721             :   PrintStatements(node->statements());
     722             : }
     723             : 
     724             : 
     725             : // TODO(svenpanne) Start with IndentedScope.
     726             : void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
     727             :   PrintLiteralWithModeIndented("VARIABLE", node->proxy()->var(),
     728             :                                node->proxy()->name());
     729             : }
     730             : 
     731             : 
     732             : // TODO(svenpanne) Start with IndentedScope.
     733             : void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
     734             :   PrintIndented("FUNCTION ");
     735             :   PrintLiteral(node->proxy()->name(), true);
     736             :   Print(" = function ");
     737             :   PrintLiteral(node->fun()->name(), false);
     738             :   Print("\n");
     739             : }
     740             : 
     741             : 
     742             : void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
     743             :   IndentedScope indent(this, "EXPRESSION STATEMENT", node->position());
     744             :   Visit(node->expression());
     745             : }
     746             : 
     747             : 
     748             : void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
     749             :   IndentedScope indent(this, "EMPTY", node->position());
     750             : }
     751             : 
     752             : 
     753             : void AstPrinter::VisitSloppyBlockFunctionStatement(
     754             :     SloppyBlockFunctionStatement* node) {
     755             :   Visit(node->statement());
     756             : }
     757             : 
     758             : 
     759             : void AstPrinter::VisitIfStatement(IfStatement* node) {
     760             :   IndentedScope indent(this, "IF", node->position());
     761             :   PrintIndentedVisit("CONDITION", node->condition());
     762             :   PrintIndentedVisit("THEN", node->then_statement());
     763             :   if (node->HasElseStatement()) {
     764             :     PrintIndentedVisit("ELSE", node->else_statement());
     765             :   }
     766             : }
     767             : 
     768             : 
     769             : void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
     770             :   IndentedScope indent(this, "CONTINUE", node->position());
     771             :   PrintLabelsIndented(node->target()->labels());
     772             : }
     773             : 
     774             : 
     775             : void AstPrinter::VisitBreakStatement(BreakStatement* node) {
     776             :   IndentedScope indent(this, "BREAK", node->position());
     777             :   PrintLabelsIndented(node->target()->labels());
     778             : }
     779             : 
     780             : 
     781             : void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
     782             :   IndentedScope indent(this, "RETURN", node->position());
     783             :   Visit(node->expression());
     784             : }
     785             : 
     786             : 
     787             : void AstPrinter::VisitWithStatement(WithStatement* node) {
     788             :   IndentedScope indent(this, "WITH", node->position());
     789             :   PrintIndentedVisit("OBJECT", node->expression());
     790             :   PrintIndentedVisit("BODY", node->statement());
     791             : }
     792             : 
     793             : 
     794             : void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
     795             :   IndentedScope indent(this, "SWITCH", node->position());
     796             :   PrintLabelsIndented(node->labels());
     797             :   PrintIndentedVisit("TAG", node->tag());
     798             :   for (int i = 0; i < node->cases()->length(); i++) {
     799             :     Visit(node->cases()->at(i));
     800             :   }
     801             : }
     802             : 
     803             : 
     804             : void AstPrinter::VisitCaseClause(CaseClause* clause) {
     805             :   if (clause->is_default()) {
     806             :     IndentedScope indent(this, "DEFAULT", clause->position());
     807             :     PrintStatements(clause->statements());
     808             :   } else {
     809             :     IndentedScope indent(this, "CASE", clause->position());
     810             :     Visit(clause->label());
     811             :     PrintStatements(clause->statements());
     812             :   }
     813             : }
     814             : 
     815             : 
     816             : void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
     817             :   IndentedScope indent(this, "DO", node->position());
     818             :   PrintIndented("SUSPEND COUNT");
     819             :   Print(" %d\n", node->suspend_count());
     820             :   PrintLabelsIndented(node->labels());
     821             :   PrintIndentedVisit("BODY", node->body());
     822             :   PrintIndentedVisit("COND", node->cond());
     823             : }
     824             : 
     825             : 
     826             : void AstPrinter::VisitWhileStatement(WhileStatement* node) {
     827             :   IndentedScope indent(this, "WHILE", node->position());
     828             :   PrintIndented("SUSPEND COUNT");
     829             :   Print(" %d\n", node->suspend_count());
     830             :   PrintLabelsIndented(node->labels());
     831             :   PrintIndentedVisit("COND", node->cond());
     832             :   PrintIndentedVisit("BODY", node->body());
     833             : }
     834             : 
     835             : 
     836             : void AstPrinter::VisitForStatement(ForStatement* node) {
     837             :   IndentedScope indent(this, "FOR", node->position());
     838             :   PrintIndented("SUSPEND COUNT");
     839             :   Print(" %d\n", node->suspend_count());
     840             :   PrintLabelsIndented(node->labels());
     841             :   if (node->init()) PrintIndentedVisit("INIT", node->init());
     842             :   if (node->cond()) PrintIndentedVisit("COND", node->cond());
     843             :   PrintIndentedVisit("BODY", node->body());
     844             :   if (node->next()) PrintIndentedVisit("NEXT", node->next());
     845             : }
     846             : 
     847             : 
     848             : void AstPrinter::VisitForInStatement(ForInStatement* node) {
     849             :   IndentedScope indent(this, "FOR IN", node->position());
     850             :   PrintIndented("SUSPEND COUNT");
     851             :   Print(" %d\n", node->suspend_count());
     852             :   PrintIndentedVisit("FOR", node->each());
     853             :   PrintIndentedVisit("IN", node->enumerable());
     854             :   PrintIndentedVisit("BODY", node->body());
     855             : }
     856             : 
     857             : 
     858             : void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
     859             :   IndentedScope indent(this, "FOR OF", node->position());
     860             :   PrintIndented("SUSPEND COUNT");
     861             :   Print(" %d\n", node->suspend_count());
     862             :   PrintIndentedVisit("INIT", node->assign_iterator());
     863             :   PrintIndentedVisit("NEXT", node->next_result());
     864             :   PrintIndentedVisit("DONE", node->result_done());
     865             :   PrintIndentedVisit("EACH", node->assign_each());
     866             :   PrintIndentedVisit("BODY", node->body());
     867             : }
     868             : 
     869             : 
     870             : void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
     871             :   IndentedScope indent(this, "TRY CATCH", node->position());
     872             :   PrintTryStatement(node);
     873             :   PrintLiteralWithModeIndented("CATCHVAR", node->scope()->catch_variable(),
     874             :                                node->scope()->catch_variable()->name());
     875             :   PrintIndentedVisit("CATCH", node->catch_block());
     876             : }
     877             : 
     878             : 
     879             : void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
     880             :   IndentedScope indent(this, "TRY FINALLY", node->position());
     881             :   PrintTryStatement(node);
     882             :   PrintIndentedVisit("FINALLY", node->finally_block());
     883             : }
     884             : 
     885             : void AstPrinter::PrintTryStatement(TryStatement* node) {
     886             :   PrintIndentedVisit("TRY", node->try_block());
     887             :   PrintIndented("CATCH PREDICTION");
     888             :   const char* prediction = "";
     889             :   switch (node->catch_prediction()) {
     890             :     case HandlerTable::UNCAUGHT:
     891             :       prediction = "UNCAUGHT";
     892             :       break;
     893             :     case HandlerTable::CAUGHT:
     894             :       prediction = "CAUGHT";
     895             :       break;
     896             :     case HandlerTable::DESUGARING:
     897             :       prediction = "DESUGARING";
     898             :       break;
     899             :     case HandlerTable::ASYNC_AWAIT:
     900             :       prediction = "ASYNC_AWAIT";
     901             :       break;
     902             :     case HandlerTable::PROMISE:
     903             :       // Catch prediction resulting in promise rejections aren't
     904             :       // parsed by the parser.
     905             :       UNREACHABLE();
     906             :   }
     907             :   Print(" %s\n", prediction);
     908             : }
     909             : 
     910             : void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
     911             :   IndentedScope indent(this, "DEBUGGER", node->position());
     912             : }
     913             : 
     914             : 
     915             : void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
     916             :   IndentedScope indent(this, "FUNC LITERAL", node->position());
     917             :   PrintLiteralIndented("NAME", node->name(), false);
     918             :   PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
     919             :   PrintParameters(node->scope());
     920             :   // We don't want to see the function literal in this case: it
     921             :   // will be printed via PrintProgram when the code for it is
     922             :   // generated.
     923             :   // PrintStatements(node->body());
     924             : }
     925             : 
     926             : 
     927             : void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
     928             :   IndentedScope indent(this, "CLASS LITERAL", node->position());
     929             :   PrintLiteralIndented("NAME", node->constructor()->name(), false);
     930             :   if (node->extends() != nullptr) {
     931             :     PrintIndentedVisit("EXTENDS", node->extends());
     932             :   }
     933             :   PrintClassProperties(node->properties());
     934             : }
     935             : 
     936             : void AstPrinter::PrintClassProperties(
     937             :     ZoneList<ClassLiteral::Property*>* properties) {
     938             :   for (int i = 0; i < properties->length(); i++) {
     939             :     ClassLiteral::Property* property = properties->at(i);
     940             :     const char* prop_kind = nullptr;
     941             :     switch (property->kind()) {
     942             :       case ClassLiteral::Property::METHOD:
     943             :         prop_kind = "METHOD";
     944             :         break;
     945             :       case ClassLiteral::Property::GETTER:
     946             :         prop_kind = "GETTER";
     947             :         break;
     948             :       case ClassLiteral::Property::SETTER:
     949             :         prop_kind = "SETTER";
     950             :         break;
     951             :       case ClassLiteral::Property::FIELD:
     952             :         prop_kind = "FIELD";
     953             :         break;
     954             :     }
     955             :     EmbeddedVector<char, 128> buf;
     956             :     SNPrintF(buf, "PROPERTY%s - %s", property->is_static() ? " - STATIC" : "",
     957             :              prop_kind);
     958             :     IndentedScope prop(this, buf.start());
     959             :     PrintIndentedVisit("KEY", properties->at(i)->key());
     960             :     PrintIndentedVisit("VALUE", properties->at(i)->value());
     961             :   }
     962             : }
     963             : 
     964             : 
     965             : void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
     966             :   IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position());
     967             :   PrintLiteralIndented("NAME", node->name(), false);
     968             : }
     969             : 
     970             : 
     971             : void AstPrinter::VisitDoExpression(DoExpression* node) {
     972             :   IndentedScope indent(this, "DO EXPRESSION", node->position());
     973             :   PrintStatements(node->block()->statements());
     974             : }
     975             : 
     976             : 
     977             : void AstPrinter::VisitConditional(Conditional* node) {
     978             :   IndentedScope indent(this, "CONDITIONAL", node->position());
     979             :   PrintIndentedVisit("CONDITION", node->condition());
     980             :   PrintIndentedVisit("THEN", node->then_expression());
     981             :   PrintIndentedVisit("ELSE", node->else_expression());
     982             : }
     983             : 
     984             : 
     985             : // TODO(svenpanne) Start with IndentedScope.
     986             : void AstPrinter::VisitLiteral(Literal* node) {
     987             :   PrintLiteralIndented("LITERAL", node->value(), true);
     988             : }
     989             : 
     990             : 
     991             : void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
     992             :   IndentedScope indent(this, "REGEXP LITERAL", node->position());
     993             :   EmbeddedVector<char, 128> buf;
     994             :   SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt());
     995             :   PrintIndented(buf.start());
     996             :   PrintLiteralIndented("PATTERN", node->pattern(), false);
     997             :   int i = 0;
     998             :   if (node->flags() & RegExp::kGlobal) buf[i++] = 'g';
     999             :   if (node->flags() & RegExp::kIgnoreCase) buf[i++] = 'i';
    1000             :   if (node->flags() & RegExp::kMultiline) buf[i++] = 'm';
    1001             :   if (node->flags() & RegExp::kUnicode) buf[i++] = 'u';
    1002             :   if (node->flags() & RegExp::kSticky) buf[i++] = 'y';
    1003             :   buf[i] = '\0';
    1004             :   PrintIndented("FLAGS ");
    1005             :   Print("%s", buf.start());
    1006             :   Print("\n");
    1007             : }
    1008             : 
    1009             : 
    1010             : void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
    1011             :   IndentedScope indent(this, "OBJ LITERAL", node->position());
    1012             :   EmbeddedVector<char, 128> buf;
    1013             :   SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt());
    1014             :   PrintIndented(buf.start());
    1015             :   PrintObjectProperties(node->properties());
    1016             : }
    1017             : 
    1018             : void AstPrinter::PrintObjectProperties(
    1019             :     ZoneList<ObjectLiteral::Property*>* properties) {
    1020             :   for (int i = 0; i < properties->length(); i++) {
    1021             :     ObjectLiteral::Property* property = properties->at(i);
    1022             :     const char* prop_kind = nullptr;
    1023             :     switch (property->kind()) {
    1024             :       case ObjectLiteral::Property::CONSTANT:
    1025             :         prop_kind = "CONSTANT";
    1026             :         break;
    1027             :       case ObjectLiteral::Property::COMPUTED:
    1028             :         prop_kind = "COMPUTED";
    1029             :         break;
    1030             :       case ObjectLiteral::Property::MATERIALIZED_LITERAL:
    1031             :         prop_kind = "MATERIALIZED_LITERAL";
    1032             :         break;
    1033             :       case ObjectLiteral::Property::PROTOTYPE:
    1034             :         prop_kind = "PROTOTYPE";
    1035             :         break;
    1036             :       case ObjectLiteral::Property::GETTER:
    1037             :         prop_kind = "GETTER";
    1038             :         break;
    1039             :       case ObjectLiteral::Property::SETTER:
    1040             :         prop_kind = "SETTER";
    1041             :         break;
    1042             :       case ObjectLiteral::Property::SPREAD:
    1043             :         prop_kind = "SPREAD";
    1044             :         break;
    1045             :     }
    1046             :     EmbeddedVector<char, 128> buf;
    1047             :     SNPrintF(buf, "PROPERTY - %s", prop_kind);
    1048             :     IndentedScope prop(this, buf.start());
    1049             :     PrintIndentedVisit("KEY", properties->at(i)->key());
    1050             :     PrintIndentedVisit("VALUE", properties->at(i)->value());
    1051             :   }
    1052             : }
    1053             : 
    1054             : 
    1055             : void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
    1056             :   IndentedScope indent(this, "ARRAY LITERAL", node->position());
    1057             : 
    1058             :   EmbeddedVector<char, 128> buf;
    1059             :   SNPrintF(buf, "literal_slot = %d\n", node->literal_slot().ToInt());
    1060             :   PrintIndented(buf.start());
    1061             :   if (node->values()->length() > 0) {
    1062             :     IndentedScope indent(this, "VALUES", node->position());
    1063             :     for (int i = 0; i < node->values()->length(); i++) {
    1064             :       Visit(node->values()->at(i));
    1065             :     }
    1066             :   }
    1067             : }
    1068             : 
    1069             : 
    1070             : void AstPrinter::VisitVariableProxy(VariableProxy* node) {
    1071             :   EmbeddedVector<char, 128> buf;
    1072             :   int pos =
    1073             :       FormatSlotNode(&buf, node, "VAR PROXY", node->VariableFeedbackSlot());
    1074             : 
    1075             :   if (!node->is_resolved()) {
    1076             :     SNPrintF(buf + pos, " unresolved");
    1077             :     PrintLiteralWithModeIndented(buf.start(), nullptr, node->name());
    1078             :   } else {
    1079             :     Variable* var = node->var();
    1080             :     switch (var->location()) {
    1081             :       case VariableLocation::UNALLOCATED:
    1082             :         SNPrintF(buf + pos, " unallocated");
    1083             :         break;
    1084             :       case VariableLocation::PARAMETER:
    1085             :         SNPrintF(buf + pos, " parameter[%d]", var->index());
    1086             :         break;
    1087             :       case VariableLocation::LOCAL:
    1088             :         SNPrintF(buf + pos, " local[%d]", var->index());
    1089             :         break;
    1090             :       case VariableLocation::CONTEXT:
    1091             :         SNPrintF(buf + pos, " context[%d]", var->index());
    1092             :         break;
    1093             :       case VariableLocation::LOOKUP:
    1094             :         SNPrintF(buf + pos, " lookup");
    1095             :         break;
    1096             :       case VariableLocation::MODULE:
    1097             :         SNPrintF(buf + pos, " module");
    1098             :         break;
    1099             :     }
    1100             :     PrintLiteralWithModeIndented(buf.start(), var, node->name());
    1101             :   }
    1102             : }
    1103             : 
    1104             : 
    1105             : void AstPrinter::VisitAssignment(Assignment* node) {
    1106             :   IndentedScope indent(this, Token::Name(node->op()), node->position());
    1107             :   Visit(node->target());
    1108             :   Visit(node->value());
    1109             : }
    1110             : 
    1111             : void AstPrinter::VisitSuspend(Suspend* node) {
    1112             :   EmbeddedVector<char, 128> buf;
    1113             :   SNPrintF(buf, "SUSPEND id %d", node->suspend_id());
    1114             :   IndentedScope indent(this, buf.start(), node->position());
    1115             :   Visit(node->expression());
    1116             : }
    1117             : 
    1118             : 
    1119             : void AstPrinter::VisitThrow(Throw* node) {
    1120             :   IndentedScope indent(this, "THROW", node->position());
    1121             :   Visit(node->exception());
    1122             : }
    1123             : 
    1124             : 
    1125             : void AstPrinter::VisitProperty(Property* node) {
    1126             :   EmbeddedVector<char, 128> buf;
    1127             :   FormatSlotNode(&buf, node, "PROPERTY", node->PropertyFeedbackSlot());
    1128             :   IndentedScope indent(this, buf.start(), node->position());
    1129             : 
    1130             :   Visit(node->obj());
    1131             :   Literal* literal = node->key()->AsLiteral();
    1132             :   if (literal != NULL && literal->value()->IsInternalizedString()) {
    1133             :     PrintLiteralIndented("NAME", literal->value(), false);
    1134             :   } else {
    1135             :     PrintIndentedVisit("KEY", node->key());
    1136             :   }
    1137             : }
    1138             : 
    1139             : 
    1140             : void AstPrinter::VisitCall(Call* node) {
    1141             :   EmbeddedVector<char, 128> buf;
    1142             :   const char* name =
    1143             :       node->tail_call_mode() == TailCallMode::kAllow ? "TAIL CALL" : "CALL";
    1144             :   FormatSlotNode(&buf, node, name, node->CallFeedbackICSlot());
    1145             :   IndentedScope indent(this, buf.start());
    1146             : 
    1147             :   Visit(node->expression());
    1148             :   PrintArguments(node->arguments());
    1149             : }
    1150             : 
    1151             : 
    1152             : void AstPrinter::VisitCallNew(CallNew* node) {
    1153             :   IndentedScope indent(this, "CALL NEW", node->position());
    1154             :   Visit(node->expression());
    1155             :   PrintArguments(node->arguments());
    1156             : }
    1157             : 
    1158             : 
    1159             : void AstPrinter::VisitCallRuntime(CallRuntime* node) {
    1160             :   EmbeddedVector<char, 128> buf;
    1161             :   SNPrintF(buf, "CALL RUNTIME %s%s", node->debug_name(),
    1162             :            node->is_jsruntime() ? " (JS function)" : "");
    1163             :   IndentedScope indent(this, buf.start(), node->position());
    1164             :   PrintArguments(node->arguments());
    1165             : }
    1166             : 
    1167             : 
    1168             : void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
    1169             :   IndentedScope indent(this, Token::Name(node->op()), node->position());
    1170             :   Visit(node->expression());
    1171             : }
    1172             : 
    1173             : 
    1174             : void AstPrinter::VisitCountOperation(CountOperation* node) {
    1175             :   EmbeddedVector<char, 128> buf;
    1176             :   SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
    1177             :            Token::Name(node->op()));
    1178             :   IndentedScope indent(this, buf.start(), node->position());
    1179             :   Visit(node->expression());
    1180             : }
    1181             : 
    1182             : 
    1183             : void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
    1184             :   IndentedScope indent(this, Token::Name(node->op()), node->position());
    1185             :   Visit(node->left());
    1186             :   Visit(node->right());
    1187             : }
    1188             : 
    1189             : 
    1190             : void AstPrinter::VisitCompareOperation(CompareOperation* node) {
    1191             :   IndentedScope indent(this, Token::Name(node->op()), node->position());
    1192             :   Visit(node->left());
    1193             :   Visit(node->right());
    1194             : }
    1195             : 
    1196             : 
    1197             : void AstPrinter::VisitSpread(Spread* node) {
    1198             :   IndentedScope indent(this, "...", node->position());
    1199             :   Visit(node->expression());
    1200             : }
    1201             : 
    1202             : 
    1203             : void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
    1204             :   IndentedScope indent(this, "()", node->position());
    1205             : }
    1206             : 
    1207             : void AstPrinter::VisitGetIterator(GetIterator* node) {
    1208             :   IndentedScope indent(this, "GET-ITERATOR", node->position());
    1209             :   Visit(node->iterable());
    1210             : }
    1211             : 
    1212             : void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
    1213             :   IndentedScope indent(this, "IMPORT-CALL", node->position());
    1214             :   Visit(node->argument());
    1215             : }
    1216             : 
    1217             : void AstPrinter::VisitThisFunction(ThisFunction* node) {
    1218             :   IndentedScope indent(this, "THIS-FUNCTION", node->position());
    1219             : }
    1220             : 
    1221             : 
    1222             : void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
    1223             :   IndentedScope indent(this, "SUPER-PROPERTY-REFERENCE", node->position());
    1224             : }
    1225             : 
    1226             : 
    1227             : void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
    1228             :   IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position());
    1229             : }
    1230             : 
    1231             : 
    1232             : void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
    1233             :   Visit(node->expression());
    1234             : }
    1235             : 
    1236             : 
    1237             : #endif  // DEBUG
    1238             : 
    1239             : }  // namespace internal
    1240             : }  // namespace v8

Generated by: LCOV version 1.10