v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
prettyprinter.cc
Go to the documentation of this file.
1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <stdarg.h>
8
10#include "src/ast/scopes.h"
11#include "src/base/strings.h"
12#include "src/base/vector.h"
13#include "src/common/globals.h"
17
18namespace v8 {
19namespace internal {
20
21CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js,
22 SpreadErrorInArgsHint error_in_spread_args)
23 : builder_(isolate) {
25 position_ = 0;
26 num_prints_ = 0;
27 found_ = false;
28 done_ = false;
29 is_call_error_ = false;
30 is_iterator_error_ = false;
32 destructuring_prop_ = nullptr;
34 is_user_js_ = is_user_js;
35 error_in_spread_args_ = error_in_spread_args;
36 spread_arg_ = nullptr;
38 InitializeAstVisitor(isolate);
39}
40
42
53
55 int position) {
56 num_prints_ = 0;
58 Find(program);
59 return builder_.Finish().ToHandleChecked();
60}
61
62void CallPrinter::Find(AstNode* node, bool print) {
63 if (found_) {
64 if (print) {
65 int prev_num_prints = num_prints_;
66 Visit(node);
67 if (prev_num_prints != num_prints_) return;
68 }
69 Print("(intermediate value)");
70 } else {
71 Visit(node);
72 }
73}
74
75void CallPrinter::Print(char c) {
76 if (!found_ || done_) return;
79}
80
81void CallPrinter::Print(const char* str) {
82 if (!found_ || done_) return;
85}
86
88 if (!found_ || done_) return;
91}
92
93void CallPrinter::VisitBlock(Block* node) {
94 FindStatements(node->statements());
95}
96
97
98void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
99
100
101void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {}
102
103
104void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
105 Find(node->expression());
106}
107
108
109void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
110
111
112void CallPrinter::VisitSloppyBlockFunctionStatement(
113 SloppyBlockFunctionStatement* node) {
114 Find(node->statement());
115}
116
117
118void CallPrinter::VisitIfStatement(IfStatement* node) {
119 Find(node->condition());
120 Find(node->then_statement());
121 if (node->HasElseStatement()) {
122 Find(node->else_statement());
123 }
124}
125
126
127void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
128
129
130void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
131
132
133void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
134 Find(node->expression());
135}
136
137
138void CallPrinter::VisitWithStatement(WithStatement* node) {
139 Find(node->expression());
140 Find(node->statement());
141}
142
143
144void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
145 Find(node->tag());
146 for (CaseClause* clause : *node->cases()) {
147 if (!clause->is_default()) Find(clause->label());
148 FindStatements(clause->statements());
149 }
150}
151
152
153void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
154 Find(node->body());
155 Find(node->cond());
156}
157
158
159void CallPrinter::VisitWhileStatement(WhileStatement* node) {
160 Find(node->cond());
161 Find(node->body());
162}
163
164
165void CallPrinter::VisitForStatement(ForStatement* node) {
166 if (node->init() != nullptr) {
167 Find(node->init());
168 }
169 if (node->cond() != nullptr) Find(node->cond());
170 if (node->next() != nullptr) Find(node->next());
171 Find(node->body());
172}
173
174
175void CallPrinter::VisitForInStatement(ForInStatement* node) {
176 Find(node->each());
177 Find(node->subject());
178 Find(node->body());
179}
180
181
182void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
183 Find(node->each());
184
185 // Check the subject's position in case there was a GetIterator error.
186 bool was_found = false;
187 if (node->subject()->position() == position_) {
190 was_found = !found_;
191 if (was_found) {
192 found_ = true;
193 }
194 }
195 Find(node->subject(), true);
196 if (was_found) {
197 done_ = true;
198 found_ = false;
199 }
200
201 Find(node->body());
202}
203
204
205void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
206 Find(node->try_block());
207 Find(node->catch_block());
208}
209
210
211void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
212 Find(node->try_block());
213 Find(node->finally_block());
214}
215
216
217void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
218
219
220void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
221 FunctionKind last_function_kind = function_kind_;
222 function_kind_ = node->kind();
223 FindStatements(node->body());
224 function_kind_ = last_function_kind;
225}
226
227
228void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
229 if (node->extends()) Find(node->extends());
230 for (int i = 0; i < node->public_members()->length(); i++) {
231 Find(node->public_members()->at(i)->value());
232 }
233 for (int i = 0; i < node->private_members()->length(); i++) {
234 Find(node->private_members()->at(i)->value());
235 }
236}
237
238void CallPrinter::VisitInitializeClassMembersStatement(
239 InitializeClassMembersStatement* node) {
240 for (int i = 0; i < node->fields()->length(); i++) {
241 Find(node->fields()->at(i)->value());
242 }
243}
244
245void CallPrinter::VisitInitializeClassStaticElementsStatement(
246 InitializeClassStaticElementsStatement* node) {
247 for (int i = 0; i < node->elements()->length(); i++) {
248 ClassLiteral::StaticElement* element = node->elements()->at(i);
249 if (element->kind() == ClassLiteral::StaticElement::PROPERTY) {
250 Find(element->property()->value());
251 } else {
252 Find(element->static_block());
253 }
254 }
255}
256
257void CallPrinter::VisitAutoAccessorGetterBody(AutoAccessorGetterBody* node) {}
258
259void CallPrinter::VisitAutoAccessorSetterBody(AutoAccessorSetterBody* node) {}
260
261void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
262
263void CallPrinter::VisitConditionalChain(ConditionalChain* node) {
264 for (size_t i = 0; i < node->conditional_chain_length(); ++i) {
265 Find(node->condition_at(i));
266 Find(node->then_expression_at(i));
267 }
268 Find(node->else_expression());
269}
270
271void CallPrinter::VisitConditional(Conditional* node) {
272 Find(node->condition());
273 Find(node->then_expression());
274 Find(node->else_expression());
275}
276
277
278void CallPrinter::VisitLiteral(Literal* node) {
279 // TODO(adamk): Teach Literal how to print its values without
280 // allocating on the heap.
281 PrintLiteral(node->BuildValue(isolate_), true);
282}
283
284
285void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
286 Print("/");
287 PrintLiteral(node->pattern(), false);
288 Print("/");
289#define V(Lower, Camel, LowerCamel, Char, Bit) \
290 if (node->flags() & RegExp::k##Camel) Print(Char);
292#undef V
293}
294
295
296void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
297 Print("{");
298 for (int i = 0; i < node->properties()->length(); i++) {
299 Find(node->properties()->at(i)->value());
300 }
301 Print("}");
302}
303
304
305void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
306 Print("[");
307 for (int i = 0; i < node->values()->length(); i++) {
308 if (i != 0) Print(",");
309 Expression* subexpr = node->values()->at(i);
310 Spread* spread = subexpr->AsSpread();
311 if (spread != nullptr && !found_ &&
312 position_ == spread->expression()->position()) {
313 found_ = true;
314 is_iterator_error_ = true;
315 Find(spread->expression(), true);
316 done_ = true;
317 return;
318 }
319 Find(subexpr, true);
320 }
321 Print("]");
322}
323
324
325void CallPrinter::VisitVariableProxy(VariableProxy* node) {
326 if (is_user_js_) {
327 PrintLiteral(node->name(), false);
328 } else {
329 // Variable names of non-user code are meaningless due to minification.
330 Print("(var)");
331 }
332}
333
334
335void CallPrinter::VisitAssignment(Assignment* node) {
336 bool was_found = false;
337 if (node->target()->IsObjectLiteral()) {
338 ObjectLiteral* target = node->target()->AsObjectLiteral();
339 if (target->position() == position_) {
340 was_found = !found_;
341 found_ = true;
343 } else {
344 for (ObjectLiteralProperty* prop : *target->properties()) {
345 if (prop->value()->position() == position_) {
346 was_found = !found_;
347 found_ = true;
348 destructuring_prop_ = prop;
350 break;
351 }
352 }
353 }
354 }
355 if (!was_found) {
356 if (found_) {
357 Find(node->target(), true);
358 return;
359 }
360 Find(node->target());
361 if (node->target()->IsArrayLiteral()) {
362 // Special case the visit for destructuring array assignment.
363 if (node->value()->position() == position_) {
364 is_iterator_error_ = true;
365 was_found = !found_;
366 found_ = true;
367 }
368 Find(node->value(), true);
369 } else {
370 Find(node->value());
371 }
372 } else {
373 Find(node->value(), true);
374 }
375
376 if (was_found) {
377 done_ = true;
378 found_ = false;
379 }
380}
381
382void CallPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
383 VisitAssignment(node);
384}
385
386void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
387
388void CallPrinter::VisitYieldStar(YieldStar* node) {
389 if (!found_ && position_ == node->expression()->position()) {
390 found_ = true;
393 else
394 is_iterator_error_ = true;
395 Print("yield* ");
396 }
397 Find(node->expression());
398}
399
400void CallPrinter::VisitAwait(Await* node) { Find(node->expression()); }
401
402void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
403
404void CallPrinter::VisitOptionalChain(OptionalChain* node) {
405 Find(node->expression());
406}
407
408void CallPrinter::VisitProperty(Property* node) {
409 Expression* key = node->key();
410 Literal* literal = key->AsLiteral();
411 if (literal != nullptr &&
412 IsInternalizedString(*literal->BuildValue(isolate_))) {
413 Find(node->obj(), true);
414 if (node->is_optional_chain_link()) {
415 Print("?");
416 }
417 Print(".");
418 // TODO(adamk): Teach Literal how to print its values without
419 // allocating on the heap.
420 PrintLiteral(literal->BuildValue(isolate_), false);
421 } else {
422 Find(node->obj(), true);
423 if (node->is_optional_chain_link()) {
424 Print("?.");
425 }
426 Print("[");
427 Find(key, true);
428 Print("]");
429 }
430}
431
432void CallPrinter::VisitCall(Call* node) {
433 bool was_found = false;
434 if (node->position() == position_) {
436 !node->arguments()->is_empty()) {
437 if (const Spread* spread = node->arguments()->last()->AsSpread()) {
438 found_ = true;
439 spread_arg_ = spread->expression();
440 Find(spread_arg_, true);
441
442 done_ = true;
443 found_ = false;
444 return;
445 }
446 }
447
448 is_call_error_ = true;
449 was_found = !found_;
450 }
451
452 if (was_found) {
453 // Bail out if the error is caused by a direct call to a variable in
454 // non-user JS code. The variable name is meaningless due to minification.
455 if (!is_user_js_ && node->expression()->IsVariableProxy()) {
456 done_ = true;
457 return;
458 }
459 found_ = true;
460 }
461 Find(node->expression(), true);
462 if (!was_found && !is_iterator_error_) Print("(...)");
463 FindArguments(node->arguments());
464 if (was_found) {
465 done_ = true;
466 found_ = false;
467 }
468}
469
470
471void CallPrinter::VisitCallNew(CallNew* node) {
472 bool was_found = false;
473 if (node->position() == position_) {
475 !node->arguments()->is_empty()) {
476 if (const Spread* spread = node->arguments()->last()->AsSpread()) {
477 found_ = true;
478 spread_arg_ = spread->expression();
479 Find(spread_arg_, true);
480
481 done_ = true;
482 found_ = false;
483 return;
484 }
485 }
486
487 is_call_error_ = true;
488 was_found = !found_;
489 }
490 if (was_found) {
491 // Bail out if the error is caused by a direct call to a variable in
492 // non-user JS code. The variable name is meaningless due to minification.
493 if (!is_user_js_ && node->expression()->IsVariableProxy()) {
494 done_ = true;
495 return;
496 }
497 found_ = true;
498 }
499 Find(node->expression(), was_found || is_iterator_error_);
500 FindArguments(node->arguments());
501 if (was_found) {
502 done_ = true;
503 found_ = false;
504 }
505}
506
507
508void CallPrinter::VisitCallRuntime(CallRuntime* node) {
509 FindArguments(node->arguments());
510}
511
512void CallPrinter::VisitSuperCallForwardArgs(SuperCallForwardArgs* node) {
513 Find(node->expression(), true);
514 Print("(...forwarded args...)");
515}
516
517void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
518 Token::Value op = node->op();
519 bool needsSpace =
520 op == Token::kDelete || op == Token::kTypeOf || op == Token::kVoid;
521 Print("(");
522 Print(Token::String(op));
523 if (needsSpace) Print(" ");
524 Find(node->expression(), true);
525 Print(")");
526}
527
528
529void CallPrinter::VisitCountOperation(CountOperation* node) {
530 Print("(");
531 if (node->is_prefix()) Print(Token::String(node->op()));
532 Find(node->expression(), true);
533 if (node->is_postfix()) Print(Token::String(node->op()));
534 Print(")");
535}
536
537
538void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
539 Print("(");
540 Find(node->left(), true);
541 Print(" ");
542 Print(Token::String(node->op()));
543 Print(" ");
544 Find(node->right(), true);
545 Print(")");
546}
547
548void CallPrinter::VisitNaryOperation(NaryOperation* node) {
549 Print("(");
550 Find(node->first(), true);
551 for (size_t i = 0; i < node->subsequent_length(); ++i) {
552 Print(" ");
553 Print(Token::String(node->op()));
554 Print(" ");
555 Find(node->subsequent(i), true);
556 }
557 Print(")");
558}
559
560void CallPrinter::VisitCompareOperation(CompareOperation* node) {
561 Print("(");
562 Find(node->left(), true);
563 Print(" ");
564 Print(Token::String(node->op()));
565 Print(" ");
566 Find(node->right(), true);
567 Print(")");
568}
569
570
571void CallPrinter::VisitSpread(Spread* node) {
572 Print("(...");
573 Find(node->expression(), true);
574 Print(")");
575}
576
577void CallPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
578 UNREACHABLE();
579}
580
581void CallPrinter::VisitGetTemplateObject(GetTemplateObject* node) {}
582
583void CallPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
584 for (Expression* substitution : *node->substitutions()) {
585 Find(substitution, true);
586 }
587}
588
589void CallPrinter::VisitImportCallExpression(ImportCallExpression* node) {
590 Print("import");
591 if (node->phase() == ModuleImportPhase::kSource) {
592 Print(".source");
593 }
594 Print("(");
595 Find(node->specifier(), true);
596 if (node->import_options()) {
597 Print(", ");
598 Find(node->import_options(), true);
599 }
600 Print(")");
601}
602
603void CallPrinter::VisitThisExpression(ThisExpression* node) { Print("this"); }
604
605void CallPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {}
606
607
608void CallPrinter::VisitSuperCallReference(SuperCallReference* node) {
609 Print("super");
610}
611
612
614 if (statements == nullptr) return;
615 for (int i = 0; i < statements->length(); i++) {
616 Find(statements->at(i));
617 }
618}
619
621 if (found_) return;
622 for (int i = 0; i < arguments->length(); i++) {
623 Find(arguments->at(i));
624 }
625}
626
628 if (IsString(*value)) {
629 if (quote) Print("\"");
630 Print(Cast<String>(value));
631 if (quote) Print("\"");
632 } else if (IsNull(*value, isolate_)) {
633 Print("null");
634 } else if (IsTrue(*value, isolate_)) {
635 Print("true");
636 } else if (IsFalse(*value, isolate_)) {
637 Print("false");
638 } else if (IsUndefined(*value, isolate_)) {
639 Print("undefined");
640 } else if (IsNumber(*value)) {
642 } else if (IsSymbol(*value)) {
643 // Symbols can only occur as literals if they were inserted by the parser.
644 PrintLiteral(direct_handle(Cast<Symbol>(value)->description(), isolate_),
645 false);
646 }
647}
648
649void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
650 PrintLiteral(value->string(), quote);
651}
652
653//-----------------------------------------------------------------------------
654
655
656#ifdef DEBUG
657
658const char* AstPrinter::Print(AstNode* node) {
659 Init();
660 Visit(node);
661 return output_;
662}
663
664void AstPrinter::Init() {
665 if (size_ == 0) {
667 const int initial_size = 256;
668 output_ = NewArray<char>(initial_size);
669 size_ = initial_size;
670 }
671 output_[0] = '\0';
672 pos_ = 0;
673}
674
675void AstPrinter::Print(const char* format, ...) {
676 for (;;) {
677 va_list arguments;
678 va_start(arguments, format);
679 int n = base::VSNPrintF(base::Vector<char>(output_, size_) + pos_, format,
680 arguments);
681 va_end(arguments);
682
683 if (n >= 0) {
684 // there was enough space - we are done
685 pos_ += n;
686 return;
687 } else {
688 // there was not enough space - allocate more and try again
689 const int slack = 32;
690 int new_size = size_ + (size_ >> 1) + slack;
691 char* new_output = NewArray<char>(new_size);
692 MemCopy(new_output, output_, pos_);
694 output_ = new_output;
695 size_ = new_size;
696 }
697 }
698}
699
700void AstPrinter::PrintLiteral(Literal* literal, bool quote) {
701 switch (literal->type()) {
702 case Literal::kString:
703 PrintLiteral(literal->AsRawString(), quote);
704 break;
706 PrintLiteral(literal->AsConsString(), quote);
707 break;
708 case Literal::kSmi:
709 Print("%d", Smi::ToInt(literal->AsSmiLiteral()));
710 break;
712 Print("%g", literal->AsNumber());
713 break;
714 case Literal::kBigInt:
715 Print("%sn", literal->AsBigInt().c_str());
716 break;
717 case Literal::kNull:
718 Print("null");
719 break;
721 Print("undefined");
722 break;
724 Print("the hole");
725 break;
727 if (literal->ToBooleanIsTrue()) {
728 Print("true");
729 } else {
730 Print("false");
731 }
732 break;
733 }
734}
735
736void AstPrinter::PrintLiteral(const AstRawString* value, bool quote) {
737 if (quote) Print("\"");
738 if (value != nullptr) {
739 const char* format = value->is_one_byte() ? "%c" : "%lc";
740 const int increment = value->is_one_byte() ? 1 : 2;
741 const unsigned char* raw_bytes = value->raw_data();
742 for (int i = 0; i < value->length(); i += increment) {
743 Print(format, raw_bytes[i]);
744 }
745 }
746 if (quote) Print("\"");
747}
748
749void AstPrinter::PrintLiteral(const AstConsString* value, bool quote) {
750 if (quote) Print("\"");
751 if (value != nullptr) {
752 std::forward_list<const AstRawString*> strings = value->ToRawStrings();
753 for (const AstRawString* string : strings) {
754 PrintLiteral(string, false);
755 }
756 }
757 if (quote) Print("\"");
758}
759
760//-----------------------------------------------------------------------------
761
762class V8_NODISCARD IndentedScope {
763 public:
764 IndentedScope(AstPrinter* printer, const char* txt)
765 : ast_printer_(printer) {
766 ast_printer_->PrintIndented(txt);
767 ast_printer_->Print("\n");
768 ast_printer_->inc_indent();
769 }
770
771 IndentedScope(AstPrinter* printer, const char* txt, int pos)
772 : ast_printer_(printer) {
773 ast_printer_->PrintIndented(txt);
774 ast_printer_->Print(" at %d\n", pos);
775 ast_printer_->inc_indent();
776 }
777
778 virtual ~IndentedScope() {
779 ast_printer_->dec_indent();
780 }
781
782 private:
783 AstPrinter* ast_printer_;
784};
785
786//-----------------------------------------------------------------------------
787
788AstPrinter::AstPrinter(uintptr_t stack_limit)
789 : output_(nullptr), size_(0), pos_(0), indent_(0) {
790 InitializeAstVisitor(stack_limit);
791}
792
793AstPrinter::~AstPrinter() {
794 DCHECK_EQ(indent_, 0);
796}
797
798
799void AstPrinter::PrintIndented(const char* txt) {
800 for (int i = 0; i < indent_; i++) {
801 Print(". ");
802 }
803 Print("%s", txt);
804}
805
806void AstPrinter::PrintLiteralIndented(const char* info, Literal* literal,
807 bool quote) {
808 PrintIndented(info);
809 Print(" ");
810 PrintLiteral(literal, quote);
811 Print("\n");
812}
813
814void AstPrinter::PrintLiteralIndented(const char* info,
815 const AstRawString* value, bool quote) {
816 PrintIndented(info);
817 Print(" ");
818 PrintLiteral(value, quote);
819 Print("\n");
820}
821
822void AstPrinter::PrintLiteralIndented(const char* info,
823 const AstConsString* value, bool quote) {
824 PrintIndented(info);
825 Print(" ");
826 PrintLiteral(value, quote);
827 Print("\n");
828}
829
830void AstPrinter::PrintLiteralWithModeIndented(const char* info, Variable* var,
831 const AstRawString* value) {
832 if (var == nullptr) {
833 PrintLiteralIndented(info, value, true);
834 } else {
835 base::EmbeddedVector<char, 256> buf;
836 int pos =
837 SNPrintF(buf, "%s (%p) (mode = %s, assigned = %s", info,
838 reinterpret_cast<void*>(var), VariableMode2String(var->mode()),
839 var->maybe_assigned() == kMaybeAssigned ? "true" : "false");
840 SNPrintF(buf + pos, ")");
841 PrintLiteralIndented(buf.begin(), value, true);
842 }
843}
844
845void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
846 if (node != nullptr) {
847 IndentedScope indent(this, s, node->position());
848 Visit(node);
849 }
850}
851
852
853const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
854 Init();
855 { IndentedScope indent(this, "FUNC", program->position());
856 PrintIndented("KIND");
857 Print(" %d\n", static_cast<uint32_t>(program->kind()));
858 PrintIndented("LITERAL ID");
859 Print(" %d\n", program->function_literal_id());
860 PrintIndented("SUSPEND COUNT");
861 Print(" %d\n", program->suspend_count());
862 PrintLiteralIndented("NAME", program->raw_name(), true);
863 if (program->raw_inferred_name()) {
864 PrintLiteralIndented("INFERRED NAME", program->raw_inferred_name(), true);
865 }
866 if (program->requires_instance_members_initializer()) {
867 Print(" REQUIRES INSTANCE FIELDS INITIALIZER\n");
868 }
869 if (program->class_scope_has_private_brand()) {
870 Print(" CLASS SCOPE HAS PRIVATE BRAND\n");
871 }
872 if (program->has_static_private_methods_or_accessors()) {
873 Print(" HAS STATIC PRIVATE METHODS\n");
874 }
875 PrintParameters(program->scope());
876 PrintDeclarations(program->scope()->declarations());
877 PrintStatements(program->body());
878 }
879 return output_;
880}
881
882
883void AstPrinter::PrintOut(Isolate* isolate, AstNode* node) {
884 AstPrinter printer(isolate ? isolate->stack_guard()->real_climit() : 0);
885 printer.Init();
886 printer.Visit(node);
887 PrintF("%s", printer.output_);
888}
889
890void AstPrinter::PrintDeclarations(Declaration::List* declarations) {
891 if (!declarations->is_empty()) {
892 IndentedScope indent(this, "DECLS");
893 for (Declaration* decl : *declarations) Visit(decl);
894 }
895}
896
897void AstPrinter::PrintParameters(DeclarationScope* scope) {
898 if (scope->num_parameters() > 0) {
899 IndentedScope indent(this, "PARAMS");
900 for (int i = 0; i < scope->num_parameters(); i++) {
901 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
902 scope->parameter(i)->raw_name());
903 }
904 }
905}
906
907void AstPrinter::PrintStatements(const ZonePtrList<Statement>* statements) {
908 for (int i = 0; i < statements->length(); i++) {
909 Visit(statements->at(i));
910 }
911}
912
913void AstPrinter::PrintArguments(const ZonePtrList<Expression>* arguments) {
914 for (int i = 0; i < arguments->length(); i++) {
915 Visit(arguments->at(i));
916 }
917}
918
919
920void AstPrinter::VisitBlock(Block* node) {
921 const char* block_txt =
922 node->ignore_completion_value() ? "BLOCK NOCOMPLETIONS" : "BLOCK";
923 IndentedScope indent(this, block_txt, node->position());
924 PrintStatements(node->statements());
925}
926
927
928// TODO(svenpanne) Start with IndentedScope.
929void AstPrinter::VisitVariableDeclaration(VariableDeclaration* node) {
930 PrintLiteralWithModeIndented("VARIABLE", node->var(),
931 node->var()->raw_name());
932}
933
934
935// TODO(svenpanne) Start with IndentedScope.
936void AstPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
937 PrintIndented("FUNCTION ");
938 PrintLiteral(node->var()->raw_name(), true);
939 Print(" = function ");
940 PrintLiteral(node->fun()->raw_name(), false);
941 Print("\n");
942}
943
944
945void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
946 IndentedScope indent(this, "EXPRESSION STATEMENT", node->position());
947 Visit(node->expression());
948}
949
950
951void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
952 IndentedScope indent(this, "EMPTY", node->position());
953}
954
955
956void AstPrinter::VisitSloppyBlockFunctionStatement(
957 SloppyBlockFunctionStatement* node) {
958 Visit(node->statement());
959}
960
961
962void AstPrinter::VisitIfStatement(IfStatement* node) {
963 IndentedScope indent(this, "IF", node->position());
964 PrintIndentedVisit("CONDITION", node->condition());
965 PrintIndentedVisit("THEN", node->then_statement());
966 if (node->HasElseStatement()) {
967 PrintIndentedVisit("ELSE", node->else_statement());
968 }
969}
970
971
972void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
973 IndentedScope indent(this, "CONTINUE", node->position());
974}
975
976
977void AstPrinter::VisitBreakStatement(BreakStatement* node) {
978 IndentedScope indent(this, "BREAK", node->position());
979}
980
981
982void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
983 IndentedScope indent(this, "RETURN", node->position());
984 Visit(node->expression());
985}
986
987
988void AstPrinter::VisitWithStatement(WithStatement* node) {
989 IndentedScope indent(this, "WITH", node->position());
990 PrintIndentedVisit("OBJECT", node->expression());
991 PrintIndentedVisit("BODY", node->statement());
992}
993
994
995void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
996 IndentedScope switch_indent(this, "SWITCH", node->position());
997 PrintIndentedVisit("TAG", node->tag());
998 for (CaseClause* clause : *node->cases()) {
999 if (clause->is_default()) {
1000 IndentedScope indent(this, "DEFAULT");
1001 PrintStatements(clause->statements());
1002 } else {
1003 IndentedScope indent(this, "CASE");
1004 Visit(clause->label());
1005 PrintStatements(clause->statements());
1006 }
1007 }
1008}
1009
1010
1011void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
1012 IndentedScope indent(this, "DO", node->position());
1013 PrintIndentedVisit("BODY", node->body());
1014 PrintIndentedVisit("COND", node->cond());
1015}
1016
1017
1018void AstPrinter::VisitWhileStatement(WhileStatement* node) {
1019 IndentedScope indent(this, "WHILE", node->position());
1020 PrintIndentedVisit("COND", node->cond());
1021 PrintIndentedVisit("BODY", node->body());
1022}
1023
1024
1025void AstPrinter::VisitForStatement(ForStatement* node) {
1026 IndentedScope indent(this, "FOR", node->position());
1027 if (node->init()) PrintIndentedVisit("INIT", node->init());
1028 if (node->cond()) PrintIndentedVisit("COND", node->cond());
1029 PrintIndentedVisit("BODY", node->body());
1030 if (node->next()) PrintIndentedVisit("NEXT", node->next());
1031}
1032
1033
1034void AstPrinter::VisitForInStatement(ForInStatement* node) {
1035 IndentedScope indent(this, "FOR IN", node->position());
1036 PrintIndentedVisit("FOR", node->each());
1037 PrintIndentedVisit("IN", node->subject());
1038 PrintIndentedVisit("BODY", node->body());
1039}
1040
1041
1042void AstPrinter::VisitForOfStatement(ForOfStatement* node) {
1043 IndentedScope indent(this, "FOR OF", node->position());
1044 const char* for_type;
1045 switch (node->type()) {
1047 for_type = "FOR";
1048 break;
1050 for_type = "FOR AWAIT";
1051 break;
1052 }
1053 PrintIndentedVisit(for_type, node->each());
1054 PrintIndentedVisit("OF", node->subject());
1055 PrintIndentedVisit("BODY", node->body());
1056}
1057
1058
1059void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
1060 IndentedScope indent(this, "TRY CATCH", node->position());
1061 PrintIndentedVisit("TRY", node->try_block());
1062 PrintIndented("CATCH PREDICTION");
1063 const char* prediction = "";
1064 switch (node->GetCatchPrediction(HandlerTable::UNCAUGHT)) {
1066 prediction = "UNCAUGHT";
1067 break;
1069 prediction = "CAUGHT";
1070 break;
1072 prediction = "ASYNC_AWAIT";
1073 break;
1075 prediction = "UNCAUGHT_ASYNC_AWAIT";
1076 break;
1078 // Catch prediction resulting in promise rejections aren't
1079 // parsed by the parser.
1080 UNREACHABLE();
1081 }
1082 Print(" %s\n", prediction);
1083 if (node->scope()) {
1084 PrintLiteralWithModeIndented("CATCHVAR", node->scope()->catch_variable(),
1085 node->scope()->catch_variable()->raw_name());
1086 }
1087 PrintIndentedVisit("CATCH", node->catch_block());
1088}
1089
1090void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
1091 IndentedScope indent(this, "TRY FINALLY", node->position());
1092 PrintIndentedVisit("TRY", node->try_block());
1093 PrintIndentedVisit("FINALLY", node->finally_block());
1094}
1095
1096void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
1097 IndentedScope indent(this, "DEBUGGER", node->position());
1098}
1099
1100
1101void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
1102 IndentedScope indent(this, "FUNC LITERAL", node->position());
1103 PrintIndented("LITERAL ID");
1104 Print(" %d\n", node->function_literal_id());
1105 PrintLiteralIndented("NAME", node->raw_name(), false);
1106 PrintLiteralIndented("INFERRED NAME", node->raw_inferred_name(), false);
1107 // We don't want to see the function literal in this case: it
1108 // will be printed via PrintProgram when the code for it is
1109 // generated.
1110 // PrintParameters(node->scope());
1111 // PrintStatements(node->body());
1112}
1113
1114
1115void AstPrinter::VisitClassLiteral(ClassLiteral* node) {
1116 IndentedScope indent(this, "CLASS LITERAL", node->position());
1117 PrintLiteralIndented("NAME", node->constructor()->raw_name(), false);
1118 if (node->extends() != nullptr) {
1119 PrintIndentedVisit("EXTENDS", node->extends());
1120 }
1121 Scope* outer = node->constructor()->scope()->outer_scope();
1122 if (outer->is_class_scope()) {
1123 Variable* brand = outer->AsClassScope()->brand();
1124 if (brand != nullptr) {
1125 PrintLiteralWithModeIndented("BRAND", brand, brand->raw_name());
1126 }
1127 }
1128 if (node->static_initializer() != nullptr) {
1129 PrintIndentedVisit("STATIC INITIALIZER", node->static_initializer());
1130 }
1131 if (node->instance_members_initializer_function() != nullptr) {
1132 PrintIndentedVisit("INSTANCE MEMBERS INITIALIZER",
1133 node->instance_members_initializer_function());
1134 }
1135 PrintClassProperties(node->private_members());
1136 PrintClassProperties(node->public_members());
1137}
1138
1139void AstPrinter::VisitInitializeClassMembersStatement(
1140 InitializeClassMembersStatement* node) {
1141 IndentedScope indent(this, "INITIALIZE CLASS MEMBERS", node->position());
1142 PrintClassProperties(node->fields());
1143}
1144
1145void AstPrinter::VisitInitializeClassStaticElementsStatement(
1146 InitializeClassStaticElementsStatement* node) {
1147 IndentedScope indent(this, "INITIALIZE CLASS STATIC ELEMENTS",
1148 node->position());
1149 PrintClassStaticElements(node->elements());
1150}
1151
1152void AstPrinter::VisitAutoAccessorGetterBody(AutoAccessorGetterBody* node) {
1153 IndentedScope indent(this, "AUTO ACCESSOR GETTER BODY", node->position());
1154 PrintIndentedVisit("AUTO ACCESSOR STORAGE PRIVATE NAME", node->name_proxy());
1155}
1156
1157void AstPrinter::VisitAutoAccessorSetterBody(AutoAccessorSetterBody* node) {
1158 IndentedScope indent(this, "AUTO ACCESSOR SETTER BODY", node->position());
1159 PrintIndentedVisit("AUTO ACCESSOR STORAGE PRIVATE NAME", node->name_proxy());
1160}
1161
1162void AstPrinter::PrintClassProperty(ClassLiteral::Property* property) {
1163 const char* prop_kind = nullptr;
1164 switch (property->kind()) {
1166 prop_kind = "METHOD";
1167 break;
1169 prop_kind = "GETTER";
1170 break;
1172 prop_kind = "SETTER";
1173 break;
1175 prop_kind = "FIELD";
1176 break;
1178 prop_kind = "AUTO ACCESSOR";
1179 break;
1180 }
1181 base::EmbeddedVector<char, 128> buf;
1182 SNPrintF(buf, "PROPERTY%s%s - %s", property->is_static() ? " - STATIC" : "",
1183 property->is_private() ? " - PRIVATE" : " - PUBLIC", prop_kind);
1184 IndentedScope prop(this, buf.begin());
1185 PrintIndentedVisit("KEY", property->key());
1186 PrintIndentedVisit("VALUE", property->value());
1187}
1188
1189void AstPrinter::PrintClassProperties(
1190 const ZonePtrList<ClassLiteral::Property>* properties) {
1191 for (int i = 0; i < properties->length(); i++) {
1192 PrintClassProperty(properties->at(i));
1193 }
1194}
1195
1196void AstPrinter::PrintClassStaticElements(
1197 const ZonePtrList<ClassLiteral::StaticElement>* static_elements) {
1198 for (int i = 0; i < static_elements->length(); i++) {
1199 ClassLiteral::StaticElement* element = static_elements->at(i);
1200 switch (element->kind()) {
1202 PrintClassProperty(element->property());
1203 break;
1205 PrintIndentedVisit("STATIC BLOCK", element->static_block());
1206 break;
1207 }
1208 }
1209}
1210
1211void AstPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {
1212 IndentedScope indent(this, "NATIVE FUNC LITERAL", node->position());
1213 PrintLiteralIndented("NAME", node->raw_name(), false);
1214}
1215
1216void AstPrinter::VisitConditionalChain(ConditionalChain* node) {
1217 IndentedScope indent(this, "CONDITIONAL_CHAIN", node->position());
1218 PrintIndentedVisit("CONDITION", node->condition_at(0));
1219 PrintIndentedVisit("THEN", node->then_expression_at(0));
1220 for (size_t i = 1; i < node->conditional_chain_length(); ++i) {
1221 IndentedScope inner_indent(this, "ELSE IF", node->condition_position_at(i));
1222 PrintIndentedVisit("CONDITION", node->condition_at(i));
1223 PrintIndentedVisit("THEN", node->then_expression_at(i));
1224 }
1225 PrintIndentedVisit("ELSE", node->else_expression());
1226}
1227
1228void AstPrinter::VisitConditional(Conditional* node) {
1229 IndentedScope indent(this, "CONDITIONAL", node->position());
1230 PrintIndentedVisit("CONDITION", node->condition());
1231 PrintIndentedVisit("THEN", node->then_expression());
1232 PrintIndentedVisit("ELSE", node->else_expression());
1233}
1234
1235
1236void AstPrinter::VisitLiteral(Literal* node) {
1237 PrintLiteralIndented("LITERAL", node, true);
1238}
1239
1240
1241void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
1242 IndentedScope indent(this, "REGEXP LITERAL", node->position());
1243 PrintLiteralIndented("PATTERN", node->raw_pattern(), false);
1244 int i = 0;
1245 base::EmbeddedVector<char, 128> buf;
1246#define V(Lower, Camel, LowerCamel, Char, Bit) \
1247 if (node->flags() & RegExp::k##Camel) buf[i++] = Char;
1249#undef V
1250 buf[i] = '\0';
1251 PrintIndented("FLAGS ");
1252 Print("%s", buf.begin());
1253 Print("\n");
1254}
1255
1256
1257void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
1258 IndentedScope indent(this, "OBJ LITERAL", node->position());
1259 PrintObjectProperties(node->properties());
1260}
1261
1262void AstPrinter::PrintObjectProperties(
1263 const ZonePtrList<ObjectLiteral::Property>* properties) {
1264 for (int i = 0; i < properties->length(); i++) {
1265 ObjectLiteral::Property* property = properties->at(i);
1266 const char* prop_kind = nullptr;
1267 switch (property->kind()) {
1269 prop_kind = "CONSTANT";
1270 break;
1272 prop_kind = "COMPUTED";
1273 break;
1275 prop_kind = "MATERIALIZED_LITERAL";
1276 break;
1278 prop_kind = "PROTOTYPE";
1279 break;
1281 prop_kind = "GETTER";
1282 break;
1284 prop_kind = "SETTER";
1285 break;
1287 prop_kind = "SPREAD";
1288 break;
1289 }
1290 base::EmbeddedVector<char, 128> buf;
1291 SNPrintF(buf, "PROPERTY - %s", prop_kind);
1292 IndentedScope prop(this, buf.begin());
1293 PrintIndentedVisit("KEY", properties->at(i)->key());
1294 PrintIndentedVisit("VALUE", properties->at(i)->value());
1295 }
1296}
1297
1298
1299void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
1300 IndentedScope array_indent(this, "ARRAY LITERAL", node->position());
1301 if (node->values()->length() > 0) {
1302 IndentedScope indent(this, "VALUES", node->position());
1303 for (int i = 0; i < node->values()->length(); i++) {
1304 Visit(node->values()->at(i));
1305 }
1306 }
1307}
1308
1309
1310void AstPrinter::VisitVariableProxy(VariableProxy* node) {
1311 base::EmbeddedVector<char, 128> buf;
1312 int pos = SNPrintF(buf, "VAR PROXY");
1313
1314 if (!node->is_resolved()) {
1315 SNPrintF(buf + pos, " unresolved");
1316 PrintLiteralWithModeIndented(buf.begin(), nullptr, node->raw_name());
1317 } else {
1318 Variable* var = node->var();
1319 switch (var->location()) {
1321 SNPrintF(buf + pos, " unallocated");
1322 break;
1324 SNPrintF(buf + pos, " parameter[%d]", var->index());
1325 break;
1327 SNPrintF(buf + pos, " local[%d]", var->index());
1328 break;
1330 SNPrintF(buf + pos, " context[%d]", var->index());
1331 break;
1333 SNPrintF(buf + pos, " lookup");
1334 break;
1336 SNPrintF(buf + pos, " module");
1337 break;
1339 SNPrintF(buf + pos, " repl global[%d]", var->index());
1340 break;
1341 }
1342 PrintLiteralWithModeIndented(buf.begin(), var, node->raw_name());
1343 }
1344}
1345
1346
1347void AstPrinter::VisitAssignment(Assignment* node) {
1348 IndentedScope indent(this, Token::Name(node->op()), node->position());
1349 Visit(node->target());
1350 Visit(node->value());
1351}
1352
1353void AstPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
1354 VisitAssignment(node);
1355}
1356
1357void AstPrinter::VisitYield(Yield* node) {
1358 base::EmbeddedVector<char, 128> buf;
1359 SNPrintF(buf, "YIELD");
1360 IndentedScope indent(this, buf.begin(), node->position());
1361 Visit(node->expression());
1362}
1363
1364void AstPrinter::VisitYieldStar(YieldStar* node) {
1365 base::EmbeddedVector<char, 128> buf;
1366 SNPrintF(buf, "YIELD_STAR");
1367 IndentedScope indent(this, buf.begin(), node->position());
1368 Visit(node->expression());
1369}
1370
1371void AstPrinter::VisitAwait(Await* node) {
1372 base::EmbeddedVector<char, 128> buf;
1373 SNPrintF(buf, "AWAIT");
1374 IndentedScope indent(this, buf.begin(), node->position());
1375 Visit(node->expression());
1376}
1377
1378void AstPrinter::VisitThrow(Throw* node) {
1379 IndentedScope indent(this, "THROW", node->position());
1380 Visit(node->exception());
1381}
1382
1383void AstPrinter::VisitOptionalChain(OptionalChain* node) {
1384 IndentedScope indent(this, "OPTIONAL_CHAIN", node->position());
1385 Visit(node->expression());
1386}
1387
1388void AstPrinter::VisitProperty(Property* node) {
1389 base::EmbeddedVector<char, 128> buf;
1390 SNPrintF(buf, "PROPERTY");
1391 IndentedScope indent(this, buf.begin(), node->position());
1392
1393 Visit(node->obj());
1395 switch (type) {
1396 case NAMED_PROPERTY:
1397 case NAMED_SUPER_PROPERTY: {
1398 PrintLiteralIndented("NAME", node->key()->AsLiteral(), false);
1399 break;
1400 }
1401 case PRIVATE_METHOD: {
1402 PrintIndentedVisit("PRIVATE_METHOD", node->key());
1403 break;
1404 }
1405 case PRIVATE_GETTER_ONLY: {
1406 PrintIndentedVisit("PRIVATE_GETTER_ONLY", node->key());
1407 break;
1408 }
1409 case PRIVATE_SETTER_ONLY: {
1410 PrintIndentedVisit("PRIVATE_SETTER_ONLY", node->key());
1411 break;
1412 }
1414 PrintIndentedVisit("PRIVATE_GETTER_AND_SETTER", node->key());
1415 break;
1416 }
1417 case KEYED_PROPERTY:
1418 case KEYED_SUPER_PROPERTY: {
1419 PrintIndentedVisit("KEY", node->key());
1420 break;
1421 }
1422 case PRIVATE_DEBUG_DYNAMIC: {
1423 PrintIndentedVisit("PRIVATE_DEBUG_DYNAMIC", node->key());
1424 break;
1425 }
1426 case NON_PROPERTY:
1427 UNREACHABLE();
1428 }
1429}
1430
1431void AstPrinter::VisitCall(Call* node) {
1432 base::EmbeddedVector<char, 128> buf;
1433 SNPrintF(buf, "CALL");
1434 IndentedScope indent(this, buf.begin());
1435
1436 Visit(node->expression());
1437 PrintArguments(node->arguments());
1438}
1439
1440
1441void AstPrinter::VisitCallNew(CallNew* node) {
1442 IndentedScope indent(this, "CALL NEW", node->position());
1443 Visit(node->expression());
1444 PrintArguments(node->arguments());
1445}
1446
1447
1448void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1449 base::EmbeddedVector<char, 128> buf;
1450 SNPrintF(buf, "CALL RUNTIME %s", node->function()->name);
1451 IndentedScope indent(this, buf.begin(), node->position());
1452 PrintArguments(node->arguments());
1453}
1454
1455
1456void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1457 IndentedScope indent(this, Token::Name(node->op()), node->position());
1458 Visit(node->expression());
1459}
1460
1461
1462void AstPrinter::VisitCountOperation(CountOperation* node) {
1463 base::EmbeddedVector<char, 128> buf;
1464 SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1465 Token::Name(node->op()));
1466 IndentedScope indent(this, buf.begin(), node->position());
1467 Visit(node->expression());
1468}
1469
1470
1471void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
1472 IndentedScope indent(this, Token::Name(node->op()), node->position());
1473 Visit(node->left());
1474 Visit(node->right());
1475}
1476
1477void AstPrinter::VisitNaryOperation(NaryOperation* node) {
1478 IndentedScope indent(this, Token::Name(node->op()), node->position());
1479 Visit(node->first());
1480 for (size_t i = 0; i < node->subsequent_length(); ++i) {
1481 Visit(node->subsequent(i));
1482 }
1483}
1484
1485void AstPrinter::VisitCompareOperation(CompareOperation* node) {
1486 IndentedScope indent(this, Token::Name(node->op()), node->position());
1487 Visit(node->left());
1488 Visit(node->right());
1489}
1490
1491
1492void AstPrinter::VisitSpread(Spread* node) {
1493 IndentedScope indent(this, "SPREAD", node->position());
1494 Visit(node->expression());
1495}
1496
1497void AstPrinter::VisitEmptyParentheses(EmptyParentheses* node) {
1498 IndentedScope indent(this, "()", node->position());
1499}
1500
1501void AstPrinter::VisitGetTemplateObject(GetTemplateObject* node) {
1502 IndentedScope indent(this, "GET-TEMPLATE-OBJECT", node->position());
1503}
1504
1505void AstPrinter::VisitTemplateLiteral(TemplateLiteral* node) {
1506 IndentedScope indent(this, "TEMPLATE-LITERAL", node->position());
1507 const AstRawString* string = node->string_parts()->first();
1508 if (!string->IsEmpty()) PrintLiteralIndented("SPAN", string, true);
1509 for (int i = 0; i < node->substitutions()->length();) {
1510 PrintIndentedVisit("EXPR", node->substitutions()->at(i++));
1511 if (i < node->string_parts()->length()) {
1512 string = node->string_parts()->at(i);
1513 if (!string->IsEmpty()) PrintLiteralIndented("SPAN", string, true);
1514 }
1515 }
1516}
1517
1518void AstPrinter::VisitImportCallExpression(ImportCallExpression* node) {
1519 IndentedScope indent(this, "IMPORT-CALL", node->position());
1520 PrintIndented("PHASE");
1521 Print(" %d\n", static_cast<uint32_t>(node->phase()));
1522 Visit(node->specifier());
1523 if (node->import_options()) {
1524 Visit(node->import_options());
1525 }
1526}
1527
1528void AstPrinter::VisitThisExpression(ThisExpression* node) {
1529 IndentedScope indent(this, "THIS-EXPRESSION", node->position());
1530}
1531
1532void AstPrinter::VisitSuperPropertyReference(SuperPropertyReference* node) {
1533 IndentedScope indent(this, "SUPER-PROPERTY-REFERENCE", node->position());
1534}
1535
1536void AstPrinter::VisitSuperCallReference(SuperCallReference* node) {
1537 IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position());
1538}
1539
1540void AstPrinter::VisitSuperCallForwardArgs(SuperCallForwardArgs* node) {
1541 IndentedScope indent(this, "SUPER FORWARD-VARARGS", node->position());
1542 Visit(node->expression());
1543}
1544
1545#endif // DEBUG
1546
1547} // namespace internal
1548} // namespace v8
int pos_
SourcePosition pos
Assignment * destructuring_assignment_
SpreadErrorInArgsHint error_in_spread_args_
IncrementalStringBuilder builder_
void FindArguments(const ZonePtrList< Expression > *arguments)
void PrintLiteral(DirectHandle< Object > value, bool quote)
ObjectLiteralProperty * destructuring_prop_
ErrorHint GetErrorHint() const
CallPrinter(Isolate *isolate, bool is_user_js, SpreadErrorInArgsHint error_in_spread_args=SpreadErrorInArgsHint::kNoErrorInArgs)
void Find(AstNode *node, bool print=false)
DirectHandle< String > Print(FunctionLiteral *program, int position)
void FindStatements(const ZonePtrList< Statement > *statements)
ClassLiteralProperty Property
Definition ast.h:2703
ClassLiteralStaticElement StaticElement
Definition ast.h:2704
base::ThreadedList< Declaration > List
Definition ast.h:373
bool ToBooleanIsTrue() const
Definition ast.cc:122
V8_WARN_UNUSED_RESULT Handle< String > NumberToString(DirectHandle< Object > number, NumberCacheMode mode=NumberCacheMode::kBoth)
V8_INLINE void AppendCString(const SrcChar *s)
MaybeDirectHandle< String > Finish()
V8_INLINE void AppendCharacter(uint8_t c)
V8_INLINE void AppendString(std::string_view str)
v8::internal::Factory * factory()
Definition isolate.h:1527
ObjectLiteralProperty Property
Definition ast.h:1393
static AssignType GetAssignType(Property *property)
Definition ast.h:1686
static constexpr int ToInt(const Tagged< Object > object)
Definition smi.h:33
static const char * Name(Value token)
Definition token.h:220
static const char * String(Value token)
Definition token.h:328
V8_INLINE int length() const
Definition zone-list.h:101
T & at(int i) const
Definition zone-list.h:88
const int size_
Definition assembler.cc:132
Isolate * isolate
Node * node
double increment
Comparator::Output * output_
FunctionLiteral * literal
Definition liveedit.cc:294
int position
Definition liveedit.cc:290
int n
Definition mul-fft.cc:296
int SNPrintF(Vector< char > str, const char *format,...)
Definition strings.cc:20
int VSNPrintF(Vector< char > str, const char *format, va_list args)
Definition strings.cc:16
V8_INLINE constexpr bool IsInternalizedString(InstanceType instance_type)
SnapshotTable< OpIndex, VariableData >::Key Variable
Definition operations.h:82
void DeleteArray(T *array)
Definition allocation.h:63
bool IsNumber(Tagged< Object > obj)
void PrintF(const char *format,...)
Definition utils.cc:39
@ PRIVATE_GETTER_ONLY
Definition ast.h:1664
@ NAMED_PROPERTY
Definition ast.h:1659
@ NAMED_SUPER_PROPERTY
Definition ast.h:1661
@ PRIVATE_SETTER_ONLY
Definition ast.h:1665
@ KEYED_SUPER_PROPERTY
Definition ast.h:1662
@ NON_PROPERTY
Definition ast.h:1658
@ PRIVATE_METHOD
Definition ast.h:1663
@ KEYED_PROPERTY
Definition ast.h:1660
@ PRIVATE_DEBUG_DYNAMIC
Definition ast.h:1667
@ PRIVATE_GETTER_AND_SETTER
Definition ast.h:1666
bool IsAsyncFunction(FunctionKind kind)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
void Print(Tagged< Object > obj)
Definition objects.h:774
void MemCopy(void *dest, const void *src, size_t size)
Definition memcopy.h:124
ZoneList< T * > ZonePtrList
kInstanceDescriptorsOffset kTransitionsOrPrototypeInfoOffset IsNull(value)||IsJSProxy(value)||IsWasmObject(value)||(IsJSObject(value) &&(HeapLayout
Definition map-inl.h:70
T * NewArray(size_t size)
Definition allocation.h:43
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
Definition casting.h:150
RegExpBuilder builder_
#define DCHECK_NULL(val)
Definition logging.h:491
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_NODISCARD
Definition v8config.h:693