blob: 211f3f63602fa8ed46d590e46815a9ab2d4fb998 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include <stdarg.h>
29
30#include "v8.h"
31
32#include "prettyprinter.h"
33#include "scopes.h"
34#include "platform.h"
35
kasperl@chromium.org71affb52009-05-26 05:44:31 +000036namespace v8 {
37namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000038
39#ifdef DEBUG
40
41PrettyPrinter::PrettyPrinter() {
42 output_ = NULL;
43 size_ = 0;
44 pos_ = 0;
45}
46
47
48PrettyPrinter::~PrettyPrinter() {
49 DeleteArray(output_);
50}
51
52
53void PrettyPrinter::VisitBlock(Block* node) {
54 if (!node->is_initializer_block()) Print("{ ");
55 PrintStatements(node->statements());
56 if (node->statements()->length() > 0) Print(" ");
57 if (!node->is_initializer_block()) Print("}");
58}
59
60
61void PrettyPrinter::VisitDeclaration(Declaration* node) {
62 Print("var ");
63 PrintLiteral(node->proxy()->name(), false);
64 if (node->fun() != NULL) {
65 Print(" = ");
66 PrintFunctionLiteral(node->fun());
67 }
68 Print(";");
69}
70
71
72void PrettyPrinter::VisitExpressionStatement(ExpressionStatement* node) {
73 Visit(node->expression());
74 Print(";");
75}
76
77
78void PrettyPrinter::VisitEmptyStatement(EmptyStatement* node) {
79 Print(";");
80}
81
82
83void PrettyPrinter::VisitIfStatement(IfStatement* node) {
84 Print("if (");
85 Visit(node->condition());
86 Print(") ");
87 Visit(node->then_statement());
88 if (node->HasElseStatement()) {
89 Print(" else ");
90 Visit(node->else_statement());
91 }
92}
93
94
95void PrettyPrinter::VisitContinueStatement(ContinueStatement* node) {
96 Print("continue");
97 ZoneStringList* labels = node->target()->labels();
98 if (labels != NULL) {
99 Print(" ");
100 ASSERT(labels->length() > 0); // guaranteed to have at least one entry
101 PrintLiteral(labels->at(0), false); // any label from the list is fine
102 }
103 Print(";");
104}
105
106
107void PrettyPrinter::VisitBreakStatement(BreakStatement* node) {
108 Print("break");
109 ZoneStringList* labels = node->target()->labels();
110 if (labels != NULL) {
111 Print(" ");
112 ASSERT(labels->length() > 0); // guaranteed to have at least one entry
113 PrintLiteral(labels->at(0), false); // any label from the list is fine
114 }
115 Print(";");
116}
117
118
119void PrettyPrinter::VisitReturnStatement(ReturnStatement* node) {
120 Print("return ");
121 Visit(node->expression());
122 Print(";");
123}
124
125
126void PrettyPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
127 Print("<enter with> (");
128 Visit(node->expression());
129 Print(") ");
130}
131
132
133void PrettyPrinter::VisitWithExitStatement(WithExitStatement* node) {
134 Print("<exit with>");
135}
136
137
138void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
139 PrintLabels(node->labels());
140 Print("switch (");
141 Visit(node->tag());
142 Print(") { ");
143 ZoneList<CaseClause*>* cases = node->cases();
144 for (int i = 0; i < cases->length(); i++)
145 PrintCaseClause(cases->at(i));
146 Print("}");
147}
148
149
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000150void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000151 PrintLabels(node->labels());
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000152 Print("do ");
153 Visit(node->body());
154 Print(" while (");
155 Visit(node->cond());
156 Print(");");
157}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000160void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
161 PrintLabels(node->labels());
162 Print("while (");
163 Visit(node->cond());
164 Print(") ");
165 Visit(node->body());
166}
167
168
169void PrettyPrinter::VisitForStatement(ForStatement* node) {
170 PrintLabels(node->labels());
171 Print("for (");
172 if (node->init() != NULL) {
173 Visit(node->init());
174 Print(" ");
175 } else {
176 Print("; ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000177 }
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000178 if (node->cond() != NULL) Visit(node->cond());
179 Print("; ");
180 if (node->next() != NULL) {
181 Visit(node->next()); // prints extra ';', unfortunately
182 // to fix: should use Expression for next
183 }
184 Print(") ");
185 Visit(node->body());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000186}
187
188
189void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
190 PrintLabels(node->labels());
191 Print("for (");
192 Visit(node->each());
193 Print(" in ");
194 Visit(node->enumerable());
195 Print(") ");
196 Visit(node->body());
197}
198
199
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000200void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201 Print("try ");
202 Visit(node->try_block());
203 Print(" catch (");
204 Visit(node->catch_var());
205 Print(") ");
206 Visit(node->catch_block());
207}
208
209
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000210void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211 Print("try ");
212 Visit(node->try_block());
213 Print(" finally ");
214 Visit(node->finally_block());
215}
216
217
218void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
219 Print("debugger ");
220}
221
222
223void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
224 Print("(");
225 PrintFunctionLiteral(node);
226 Print(")");
227}
228
229
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000230void PrettyPrinter::VisitSharedFunctionInfoLiteral(
231 SharedFunctionInfoLiteral* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232 Print("(");
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000233 PrintLiteral(node->shared_function_info(), true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000234 Print(")");
235}
236
237
238void PrettyPrinter::VisitConditional(Conditional* node) {
239 Visit(node->condition());
240 Print(" ? ");
241 Visit(node->then_expression());
242 Print(" : ");
243 Visit(node->else_expression());
244}
245
246
247void PrettyPrinter::VisitLiteral(Literal* node) {
248 PrintLiteral(node->handle(), true);
249}
250
251
252void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
253 Print(" RegExp(");
254 PrintLiteral(node->pattern(), false);
255 Print(",");
256 PrintLiteral(node->flags(), false);
257 Print(") ");
258}
259
260
261void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
262 Print("{ ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263 for (int i = 0; i < node->properties()->length(); i++) {
264 if (i != 0) Print(",");
265 ObjectLiteral::Property* property = node->properties()->at(i);
266 Print(" ");
267 Visit(property->key());
268 Print(": ");
269 Visit(property->value());
270 }
271 Print(" }");
272}
273
274
275void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
276 Print("[ ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000277 for (int i = 0; i < node->values()->length(); i++) {
278 if (i != 0) Print(",");
279 Visit(node->values()->at(i));
280 }
281 Print(" ]");
282}
283
284
ager@chromium.org32912102009-01-16 10:38:43 +0000285void PrettyPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
286 Print("{ ");
287 Visit(node->key());
288 Print(": ");
289 Visit(node->value());
290 Print(" }");
291}
292
293
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000294void PrettyPrinter::VisitSlot(Slot* node) {
295 switch (node->type()) {
296 case Slot::PARAMETER:
297 Print("parameter[%d]", node->index());
298 break;
299 case Slot::LOCAL:
300 Print("frame[%d]", node->index());
301 break;
302 case Slot::CONTEXT:
303 Print(".context[%d]", node->index());
304 break;
305 case Slot::LOOKUP:
306 Print(".context[");
307 PrintLiteral(node->var()->name(), false);
308 Print("]");
309 break;
310 default:
311 UNREACHABLE();
312 }
313}
314
315
316void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
317 PrintLiteral(node->name(), false);
318}
319
320
321void PrettyPrinter::VisitAssignment(Assignment* node) {
322 Visit(node->target());
323 Print(" %s ", Token::String(node->op()));
324 Visit(node->value());
325}
326
327
328void PrettyPrinter::VisitThrow(Throw* node) {
329 Print("throw ");
330 Visit(node->exception());
331}
332
333
334void PrettyPrinter::VisitProperty(Property* node) {
335 Expression* key = node->key();
336 Literal* literal = key->AsLiteral();
337 if (literal != NULL && literal->handle()->IsSymbol()) {
338 Print("(");
339 Visit(node->obj());
340 Print(").");
341 PrintLiteral(literal->handle(), false);
342 } else {
343 Visit(node->obj());
344 Print("[");
345 Visit(key);
346 Print("]");
347 }
348}
349
350
351void PrettyPrinter::VisitCall(Call* node) {
352 Visit(node->expression());
353 PrintArguments(node->arguments());
354}
355
356
357void PrettyPrinter::VisitCallNew(CallNew* node) {
358 Print("new (");
359 Visit(node->expression());
360 Print(")");
361 PrintArguments(node->arguments());
362}
363
364
365void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
366 Print("%%");
367 PrintLiteral(node->name(), false);
368 PrintArguments(node->arguments());
369}
370
371
372void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
373 Print("(%s", Token::String(node->op()));
374 Visit(node->expression());
375 Print(")");
376}
377
378
ricow@chromium.org65fae842010-08-25 15:26:24 +0000379void PrettyPrinter::VisitIncrementOperation(IncrementOperation* node) {
380 UNREACHABLE();
381}
382
383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000384void PrettyPrinter::VisitCountOperation(CountOperation* node) {
385 Print("(");
386 if (node->is_prefix()) Print("%s", Token::String(node->op()));
387 Visit(node->expression());
388 if (node->is_postfix()) Print("%s", Token::String(node->op()));
389 Print(")");
390}
391
392
393void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
394 Print("(");
395 Visit(node->left());
396 Print("%s", Token::String(node->op()));
397 Visit(node->right());
398 Print(")");
399}
400
401
402void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
403 Print("(");
404 Visit(node->left());
405 Print("%s", Token::String(node->op()));
406 Visit(node->right());
407 Print(")");
408}
409
410
ricow@chromium.org65fae842010-08-25 15:26:24 +0000411void PrettyPrinter::VisitCompareToNull(CompareToNull* node) {
412 Print("(");
413 Visit(node->expression());
414 Print("%s null)", Token::String(node->op()));
415}
416
417
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000418void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
419 Print("<this-function>");
420}
421
422
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000423const char* PrettyPrinter::Print(AstNode* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000424 Init();
425 Visit(node);
426 return output_;
427}
428
429
430const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
431 Init();
432 ExpressionStatement* statement =
433 program->body()->at(0)->AsExpressionStatement();
434 Visit(statement->expression());
435 return output_;
436}
437
438
439const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
440 Init();
441 PrintStatements(program->body());
442 Print("\n");
443 return output_;
444}
445
446
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000447void PrettyPrinter::PrintOut(AstNode* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000448 PrettyPrinter printer;
449 PrintF("%s", printer.Print(node));
450}
451
452
453void PrettyPrinter::Init() {
454 if (size_ == 0) {
455 ASSERT(output_ == NULL);
456 const int initial_size = 256;
457 output_ = NewArray<char>(initial_size);
458 size_ = initial_size;
459 }
460 output_[0] = '\0';
461 pos_ = 0;
462}
463
464
465void PrettyPrinter::Print(const char* format, ...) {
466 for (;;) {
467 va_list arguments;
468 va_start(arguments, format);
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000469 int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
470 format,
471 arguments);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000472 va_end(arguments);
473
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000474 if (n >= 0) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475 // there was enough space - we are done
476 pos_ += n;
477 return;
478 } else {
479 // there was not enough space - allocate more and try again
480 const int slack = 32;
481 int new_size = size_ + (size_ >> 1) + slack;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000482 char* new_output = NewArray<char>(new_size);
483 memcpy(new_output, output_, pos_);
484 DeleteArray(output_);
485 output_ = new_output;
486 size_ = new_size;
487 }
488 }
489}
490
491
492void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
493 for (int i = 0; i < statements->length(); i++) {
494 if (i != 0) Print(" ");
495 Visit(statements->at(i));
496 }
497}
498
499
500void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
501 if (labels != NULL) {
502 for (int i = 0; i < labels->length(); i++) {
503 PrintLiteral(labels->at(i), false);
504 Print(": ");
505 }
506 }
507}
508
509
510void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
511 Print("(");
512 for (int i = 0; i < arguments->length(); i++) {
513 if (i != 0) Print(", ");
514 Visit(arguments->at(i));
515 }
516 Print(")");
517}
518
519
520void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
521 Object* object = *value;
522 if (object->IsString()) {
523 String* string = String::cast(object);
524 if (quote) Print("\"");
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000525 for (int i = 0; i < string->length(); i++) {
526 Print("%c", string->Get(i));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000527 }
528 if (quote) Print("\"");
529 } else if (object == Heap::null_value()) {
530 Print("null");
531 } else if (object == Heap::true_value()) {
532 Print("true");
533 } else if (object == Heap::false_value()) {
534 Print("false");
535 } else if (object == Heap::undefined_value()) {
536 Print("undefined");
537 } else if (object->IsNumber()) {
538 Print("%g", object->Number());
539 } else if (object->IsJSObject()) {
540 // regular expression
541 if (object->IsJSFunction()) {
542 Print("JS-Function");
543 } else if (object->IsJSArray()) {
544 Print("JS-array[%u]", JSArray::cast(object)->length());
545 } else if (object->IsJSObject()) {
546 Print("JS-Object");
547 } else {
548 Print("?UNKNOWN?");
549 }
550 } else if (object->IsFixedArray()) {
551 Print("FixedArray");
552 } else {
553 Print("<unknown literal %p>", object);
554 }
555}
556
557
558void PrettyPrinter::PrintParameters(Scope* scope) {
559 Print("(");
560 for (int i = 0; i < scope->num_parameters(); i++) {
561 if (i > 0) Print(", ");
562 PrintLiteral(scope->parameter(i)->name(), false);
563 }
564 Print(")");
565}
566
567
568void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
569 for (int i = 0; i < declarations->length(); i++) {
570 if (i > 0) Print(" ");
571 Visit(declarations->at(i));
572 }
573}
574
575
576void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
577 Print("function ");
578 PrintLiteral(function->name(), false);
579 PrintParameters(function->scope());
580 Print(" { ");
581 PrintDeclarations(function->scope()->declarations());
582 PrintStatements(function->body());
583 Print(" }");
584}
585
586
587void PrettyPrinter::PrintCaseClause(CaseClause* clause) {
588 if (clause->is_default()) {
589 Print("default");
590 } else {
591 Print("case ");
592 Visit(clause->label());
593 }
594 Print(": ");
595 PrintStatements(clause->statements());
596 if (clause->statements()->length() > 0)
597 Print(" ");
598}
599
600
601//-----------------------------------------------------------------------------
602
603class IndentedScope BASE_EMBEDDED {
604 public:
605 IndentedScope() {
606 ast_printer_->inc_indent();
607 }
608
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000609 explicit IndentedScope(const char* txt, AstNode* node = NULL) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610 ast_printer_->PrintIndented(txt);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000611 if (node != NULL && node->AsExpression() != NULL) {
612 Expression* expr = node->AsExpression();
613 bool printed_first = false;
614 if ((expr->type() != NULL) && (expr->type()->IsKnown())) {
615 ast_printer_->Print(" (type = ");
616 ast_printer_->Print(StaticType::Type2String(expr->type()));
617 printed_first = true;
618 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000619 if (printed_first) ast_printer_->Print(")");
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000620 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000621 ast_printer_->Print("\n");
622 ast_printer_->inc_indent();
623 }
624
625 virtual ~IndentedScope() {
626 ast_printer_->dec_indent();
627 }
628
629 static void SetAstPrinter(AstPrinter* a) { ast_printer_ = a; }
630
631 private:
632 static AstPrinter* ast_printer_;
633};
634
635
636AstPrinter* IndentedScope::ast_printer_ = NULL;
637
638
639//-----------------------------------------------------------------------------
640
641int AstPrinter::indent_ = 0;
642
643
644AstPrinter::AstPrinter() {
645 ASSERT(indent_ == 0);
646 IndentedScope::SetAstPrinter(this);
647}
648
649
650AstPrinter::~AstPrinter() {
651 ASSERT(indent_ == 0);
652 IndentedScope::SetAstPrinter(NULL);
653}
654
655
656void AstPrinter::PrintIndented(const char* txt) {
657 for (int i = 0; i < indent_; i++) {
kasperl@chromium.org2d18d102009-04-15 13:27:32 +0000658 Print(". ");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000659 }
660 Print(txt);
661}
662
663
664void AstPrinter::PrintLiteralIndented(const char* info,
665 Handle<Object> value,
666 bool quote) {
667 PrintIndented(info);
668 Print(" ");
669 PrintLiteral(value, quote);
670 Print("\n");
671}
672
673
674void AstPrinter::PrintLiteralWithModeIndented(const char* info,
675 Variable* var,
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000676 Handle<Object> value,
ricow@chromium.org65fae842010-08-25 15:26:24 +0000677 StaticType* type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678 if (var == NULL) {
679 PrintLiteralIndented(info, value, true);
680 } else {
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000681 EmbeddedVector<char, 256> buf;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000682 int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
683 Variable::Mode2String(var->mode()));
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000684 if (type->IsKnown()) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000685 pos += OS::SNPrintF(buf + pos, ", type = %s",
686 StaticType::Type2String(type));
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000687 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000688 OS::SNPrintF(buf + pos, ")");
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000689 PrintLiteralIndented(buf.start(), value, true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000690 }
691}
692
693
694void AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) {
695 if (labels != NULL && labels->length() > 0) {
696 if (info == NULL) {
697 PrintIndented("LABELS ");
698 } else {
699 PrintIndented(info);
700 Print(" ");
701 }
702 PrintLabels(labels);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703 } else if (info != NULL) {
704 PrintIndented(info);
705 }
ager@chromium.orge2902be2009-06-08 12:21:35 +0000706 Print("\n");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000707}
708
709
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000710void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000711 IndentedScope indent(s, node);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000712 Visit(node);
713}
714
715
716const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
717 Init();
718 { IndentedScope indent("FUNC");
719 PrintLiteralIndented("NAME", program->name(), true);
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000720 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721 PrintParameters(program->scope());
722 PrintDeclarations(program->scope()->declarations());
723 PrintStatements(program->body());
724 }
725 return Output();
726}
727
728
729void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
730 if (declarations->length() > 0) {
731 IndentedScope indent("DECLS");
732 for (int i = 0; i < declarations->length(); i++) {
733 Visit(declarations->at(i));
734 }
735 }
736}
737
738
739void AstPrinter::PrintParameters(Scope* scope) {
740 if (scope->num_parameters() > 0) {
741 IndentedScope indent("PARAMS");
742 for (int i = 0; i < scope->num_parameters(); i++) {
kasperl@chromium.org2d18d102009-04-15 13:27:32 +0000743 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000744 scope->parameter(i)->name(),
ricow@chromium.org65fae842010-08-25 15:26:24 +0000745 scope->parameter(i)->type());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000746 }
747 }
748}
749
750
751void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
752 for (int i = 0; i < statements->length(); i++) {
753 Visit(statements->at(i));
754 }
755}
756
757
758void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
759 for (int i = 0; i < arguments->length(); i++) {
760 Visit(arguments->at(i));
761 }
762}
763
764
765void AstPrinter::PrintCaseClause(CaseClause* clause) {
766 if (clause->is_default()) {
767 IndentedScope indent("DEFAULT");
768 PrintStatements(clause->statements());
769 } else {
770 IndentedScope indent("CASE");
771 Visit(clause->label());
772 PrintStatements(clause->statements());
773 }
774}
775
776
777void AstPrinter::VisitBlock(Block* node) {
778 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
779 IndentedScope indent(block_txt);
780 PrintStatements(node->statements());
781}
782
783
784void AstPrinter::VisitDeclaration(Declaration* node) {
785 if (node->fun() == NULL) {
786 // var or const declarations
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000787 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
788 node->proxy()->AsVariable(),
789 node->proxy()->name(),
ricow@chromium.org65fae842010-08-25 15:26:24 +0000790 node->proxy()->AsVariable()->type());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000791 } else {
792 // function declarations
793 PrintIndented("FUNCTION ");
794 PrintLiteral(node->proxy()->name(), true);
795 Print(" = function ");
796 PrintLiteral(node->fun()->name(), false);
797 Print("\n");
798 }
799}
800
801
802void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
803 Visit(node->expression());
804}
805
806
807void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
808 PrintIndented("EMPTY\n");
809}
810
811
812void AstPrinter::VisitIfStatement(IfStatement* node) {
813 PrintIndentedVisit("IF", node->condition());
814 PrintIndentedVisit("THEN", node->then_statement());
815 if (node->HasElseStatement()) {
816 PrintIndentedVisit("ELSE", node->else_statement());
817 }
818}
819
820
821void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
822 PrintLabelsIndented("CONTINUE", node->target()->labels());
823}
824
825
826void AstPrinter::VisitBreakStatement(BreakStatement* node) {
827 PrintLabelsIndented("BREAK", node->target()->labels());
828}
829
830
831void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
832 PrintIndentedVisit("RETURN", node->expression());
833}
834
835
836void AstPrinter::VisitWithEnterStatement(WithEnterStatement* node) {
837 PrintIndentedVisit("WITH ENTER", node->expression());
838}
839
840
841void AstPrinter::VisitWithExitStatement(WithExitStatement* node) {
842 PrintIndented("WITH EXIT\n");
843}
844
845
846void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
847 IndentedScope indent("SWITCH");
848 PrintLabelsIndented(NULL, node->labels());
849 PrintIndentedVisit("TAG", node->tag());
850 for (int i = 0; i < node->cases()->length(); i++) {
851 PrintCaseClause(node->cases()->at(i));
852 }
853}
854
855
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000856void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
857 IndentedScope indent("DO");
858 PrintLabelsIndented(NULL, node->labels());
859 PrintIndentedVisit("BODY", node->body());
860 PrintIndentedVisit("COND", node->cond());
861}
862
863
864void AstPrinter::VisitWhileStatement(WhileStatement* node) {
865 IndentedScope indent("WHILE");
866 PrintLabelsIndented(NULL, node->labels());
867 PrintIndentedVisit("COND", node->cond());
868 PrintIndentedVisit("BODY", node->body());
869}
870
871
872void AstPrinter::VisitForStatement(ForStatement* node) {
873 IndentedScope indent("FOR");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000874 PrintLabelsIndented(NULL, node->labels());
875 if (node->init()) PrintIndentedVisit("INIT", node->init());
876 if (node->cond()) PrintIndentedVisit("COND", node->cond());
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000877 PrintIndentedVisit("BODY", node->body());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000878 if (node->next()) PrintIndentedVisit("NEXT", node->next());
879}
880
881
882void AstPrinter::VisitForInStatement(ForInStatement* node) {
883 IndentedScope indent("FOR IN");
884 PrintIndentedVisit("FOR", node->each());
885 PrintIndentedVisit("IN", node->enumerable());
886 PrintIndentedVisit("BODY", node->body());
887}
888
889
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000890void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891 IndentedScope indent("TRY CATCH");
892 PrintIndentedVisit("TRY", node->try_block());
893 PrintIndentedVisit("CATCHVAR", node->catch_var());
894 PrintIndentedVisit("CATCH", node->catch_block());
895}
896
897
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000899 IndentedScope indent("TRY FINALLY");
900 PrintIndentedVisit("TRY", node->try_block());
901 PrintIndentedVisit("FINALLY", node->finally_block());
902}
903
904
905void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
906 IndentedScope indent("DEBUGGER");
907}
908
909
910void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
911 IndentedScope indent("FUNC LITERAL");
912 PrintLiteralIndented("NAME", node->name(), false);
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000913 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000914 PrintParameters(node->scope());
915 // We don't want to see the function literal in this case: it
916 // will be printed via PrintProgram when the code for it is
917 // generated.
918 // PrintStatements(node->body());
919}
920
921
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000922void AstPrinter::VisitSharedFunctionInfoLiteral(
923 SharedFunctionInfoLiteral* node) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000924 IndentedScope indent("FUNC LITERAL");
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +0000925 PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000926}
927
928
929void AstPrinter::VisitConditional(Conditional* node) {
930 IndentedScope indent("CONDITIONAL");
931 PrintIndentedVisit("?", node->condition());
932 PrintIndentedVisit("THEN", node->then_expression());
933 PrintIndentedVisit("ELSE", node->else_expression());
934}
935
936
937void AstPrinter::VisitLiteral(Literal* node) {
938 PrintLiteralIndented("LITERAL", node->handle(), true);
939}
940
941
942void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
943 IndentedScope indent("REGEXP LITERAL");
ager@chromium.orge2902be2009-06-08 12:21:35 +0000944 PrintLiteralIndented("PATTERN", node->pattern(), false);
945 PrintLiteralIndented("FLAGS", node->flags(), false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000946}
947
948
949void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
950 IndentedScope indent("OBJ LITERAL");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000951 for (int i = 0; i < node->properties()->length(); i++) {
952 const char* prop_kind = NULL;
953 switch (node->properties()->at(i)->kind()) {
954 case ObjectLiteral::Property::CONSTANT:
955 prop_kind = "PROPERTY - CONSTANT";
956 break;
957 case ObjectLiteral::Property::COMPUTED:
958 prop_kind = "PROPERTY - COMPUTED";
959 break;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000960 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
961 prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
962 break;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963 case ObjectLiteral::Property::PROTOTYPE:
964 prop_kind = "PROPERTY - PROTOTYPE";
965 break;
966 case ObjectLiteral::Property::GETTER:
967 prop_kind = "PROPERTY - GETTER";
968 break;
969 case ObjectLiteral::Property::SETTER:
970 prop_kind = "PROPERTY - SETTER";
971 break;
972 default:
973 UNREACHABLE();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000974 }
975 IndentedScope prop(prop_kind);
976 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
977 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
978 }
979}
980
981
982void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
983 IndentedScope indent("ARRAY LITERAL");
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000984 if (node->values()->length() > 0) {
985 IndentedScope indent("VALUES");
986 for (int i = 0; i < node->values()->length(); i++) {
987 Visit(node->values()->at(i));
988 }
989 }
990}
991
992
ager@chromium.org32912102009-01-16 10:38:43 +0000993void AstPrinter::VisitCatchExtensionObject(CatchExtensionObject* node) {
994 IndentedScope indent("CatchExtensionObject");
995 PrintIndentedVisit("KEY", node->key());
996 PrintIndentedVisit("VALUE", node->value());
997}
998
999
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001000void AstPrinter::VisitSlot(Slot* node) {
1001 PrintIndented("SLOT ");
1002 switch (node->type()) {
1003 case Slot::PARAMETER:
1004 Print("parameter[%d]", node->index());
1005 break;
1006 case Slot::LOCAL:
1007 Print("frame[%d]", node->index());
1008 break;
1009 case Slot::CONTEXT:
1010 Print(".context[%d]", node->index());
1011 break;
1012 case Slot::LOOKUP:
1013 Print(".context[");
1014 PrintLiteral(node->var()->name(), false);
1015 Print("]");
1016 break;
1017 default:
1018 UNREACHABLE();
1019 }
1020 Print("\n");
1021}
1022
1023
1024void AstPrinter::VisitVariableProxy(VariableProxy* node) {
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001025 PrintLiteralWithModeIndented("VAR PROXY", node->AsVariable(), node->name(),
ricow@chromium.org65fae842010-08-25 15:26:24 +00001026 node->type());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027 Variable* var = node->var();
1028 if (var != NULL && var->rewrite() != NULL) {
1029 IndentedScope indent;
1030 Visit(var->rewrite());
1031 }
1032}
1033
1034
1035void AstPrinter::VisitAssignment(Assignment* node) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001036 IndentedScope indent(Token::Name(node->op()), node);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037 Visit(node->target());
1038 Visit(node->value());
1039}
1040
1041
1042void AstPrinter::VisitThrow(Throw* node) {
1043 PrintIndentedVisit("THROW", node->exception());
1044}
1045
1046
1047void AstPrinter::VisitProperty(Property* node) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001048 IndentedScope indent("PROPERTY", node);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049 Visit(node->obj());
1050 Literal* literal = node->key()->AsLiteral();
1051 if (literal != NULL && literal->handle()->IsSymbol()) {
kasperl@chromium.org2d18d102009-04-15 13:27:32 +00001052 PrintLiteralIndented("NAME", literal->handle(), false);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053 } else {
1054 PrintIndentedVisit("KEY", node->key());
1055 }
1056}
1057
1058
1059void AstPrinter::VisitCall(Call* node) {
1060 IndentedScope indent("CALL");
1061 Visit(node->expression());
1062 PrintArguments(node->arguments());
1063}
1064
1065
1066void AstPrinter::VisitCallNew(CallNew* node) {
1067 IndentedScope indent("CALL NEW");
1068 Visit(node->expression());
1069 PrintArguments(node->arguments());
1070}
1071
1072
1073void AstPrinter::VisitCallRuntime(CallRuntime* node) {
1074 PrintLiteralIndented("CALL RUNTIME ", node->name(), false);
1075 IndentedScope indent;
1076 PrintArguments(node->arguments());
1077}
1078
1079
1080void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
1081 PrintIndentedVisit(Token::Name(node->op()), node->expression());
1082}
1083
1084
ricow@chromium.org65fae842010-08-25 15:26:24 +00001085void AstPrinter::VisitIncrementOperation(IncrementOperation* node) {
1086 UNREACHABLE();
1087}
1088
1089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001090void AstPrinter::VisitCountOperation(CountOperation* node) {
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001091 EmbeddedVector<char, 128> buf;
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001092 if (node->type()->IsKnown()) {
1093 OS::SNPrintF(buf, "%s %s (type = %s)",
1094 (node->is_prefix() ? "PRE" : "POST"),
1095 Token::Name(node->op()),
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001096 StaticType::Type2String(node->type()));
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001097 } else {
1098 OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1099 Token::Name(node->op()));
1100 }
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001101 PrintIndentedVisit(buf.start(), node->expression());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102}
1103
1104
1105void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001106 IndentedScope indent(Token::Name(node->op()), node);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001107 Visit(node->left());
1108 Visit(node->right());
1109}
1110
1111
1112void AstPrinter::VisitCompareOperation(CompareOperation* node) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001113 IndentedScope indent(Token::Name(node->op()), node);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001114 Visit(node->left());
1115 Visit(node->right());
1116}
1117
1118
ricow@chromium.org65fae842010-08-25 15:26:24 +00001119void AstPrinter::VisitCompareToNull(CompareToNull* node) {
1120 const char* name = node->is_strict()
1121 ? "COMPARE-TO-NULL-STRICT"
1122 : "COMPARE-TO-NULL";
1123 IndentedScope indent(name, node);
1124 Visit(node->expression());
1125}
1126
1127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001128void AstPrinter::VisitThisFunction(ThisFunction* node) {
1129 IndentedScope indent("THIS-FUNCTION");
1130}
1131
1132
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001133TagScope::TagScope(JsonAstBuilder* builder, const char* name)
1134 : builder_(builder), next_(builder->tag()), has_body_(false) {
1135 if (next_ != NULL) {
1136 next_->use();
1137 builder->Print(",\n");
1138 }
1139 builder->set_tag(this);
1140 builder->PrintIndented("[");
1141 builder->Print("\"%s\"", name);
1142 builder->increase_indent(JsonAstBuilder::kTagIndentSize);
1143}
1144
1145
1146TagScope::~TagScope() {
1147 builder_->decrease_indent(JsonAstBuilder::kTagIndentSize);
1148 if (has_body_) {
1149 builder_->Print("\n");
1150 builder_->PrintIndented("]");
1151 } else {
1152 builder_->Print("]");
1153 }
1154 builder_->set_tag(next_);
1155}
1156
1157
1158AttributesScope::AttributesScope(JsonAstBuilder* builder)
1159 : builder_(builder), attribute_count_(0) {
1160 builder->set_attributes(this);
1161 builder->tag()->use();
1162 builder->Print(",\n");
1163 builder->PrintIndented("{");
1164 builder->increase_indent(JsonAstBuilder::kAttributesIndentSize);
1165}
1166
1167
1168AttributesScope::~AttributesScope() {
1169 builder_->decrease_indent(JsonAstBuilder::kAttributesIndentSize);
1170 if (attribute_count_ > 1) {
1171 builder_->Print("\n");
1172 builder_->PrintIndented("}");
1173 } else {
1174 builder_->Print("}");
1175 }
1176 builder_->set_attributes(NULL);
1177}
1178
1179
1180const char* JsonAstBuilder::BuildProgram(FunctionLiteral* program) {
1181 Init();
1182 Visit(program);
1183 Print("\n");
1184 return Output();
1185}
1186
1187
1188void JsonAstBuilder::AddAttributePrefix(const char* name) {
1189 if (attributes()->is_used()) {
1190 Print(",\n");
1191 PrintIndented("\"");
1192 } else {
1193 Print("\"");
1194 }
1195 Print("%s\":", name);
1196 attributes()->use();
1197}
1198
1199
1200void JsonAstBuilder::AddAttribute(const char* name, Handle<String> value) {
1201 SmartPointer<char> value_string = value->ToCString();
1202 AddAttributePrefix(name);
1203 Print("\"%s\"", *value_string);
1204}
1205
1206
1207void JsonAstBuilder::AddAttribute(const char* name, const char* value) {
1208 AddAttributePrefix(name);
1209 Print("\"%s\"", value);
1210}
1211
1212
1213void JsonAstBuilder::AddAttribute(const char* name, int value) {
1214 AddAttributePrefix(name);
1215 Print("%d", value);
1216}
1217
1218
1219void JsonAstBuilder::AddAttribute(const char* name, bool value) {
1220 AddAttributePrefix(name);
1221 Print(value ? "true" : "false");
1222}
1223
1224
1225void JsonAstBuilder::VisitBlock(Block* stmt) {
1226 TagScope tag(this, "Block");
1227 VisitStatements(stmt->statements());
1228}
1229
1230
1231void JsonAstBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
1232 TagScope tag(this, "ExpressionStatement");
1233 Visit(stmt->expression());
1234}
1235
1236
1237void JsonAstBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
1238 TagScope tag(this, "EmptyStatement");
1239}
1240
1241
1242void JsonAstBuilder::VisitIfStatement(IfStatement* stmt) {
1243 TagScope tag(this, "IfStatement");
1244 Visit(stmt->condition());
1245 Visit(stmt->then_statement());
1246 Visit(stmt->else_statement());
1247}
1248
1249
1250void JsonAstBuilder::VisitContinueStatement(ContinueStatement* stmt) {
1251 TagScope tag(this, "ContinueStatement");
1252}
1253
1254
1255void JsonAstBuilder::VisitBreakStatement(BreakStatement* stmt) {
1256 TagScope tag(this, "BreakStatement");
1257}
1258
1259
1260void JsonAstBuilder::VisitReturnStatement(ReturnStatement* stmt) {
1261 TagScope tag(this, "ReturnStatement");
1262 Visit(stmt->expression());
1263}
1264
1265
1266void JsonAstBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
1267 TagScope tag(this, "WithEnterStatement");
1268 Visit(stmt->expression());
1269}
1270
1271
1272void JsonAstBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
1273 TagScope tag(this, "WithExitStatement");
1274}
1275
1276
1277void JsonAstBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
1278 TagScope tag(this, "SwitchStatement");
1279}
1280
1281
1282void JsonAstBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
1283 TagScope tag(this, "DoWhileStatement");
1284 Visit(stmt->body());
1285 Visit(stmt->cond());
1286}
1287
1288
1289void JsonAstBuilder::VisitWhileStatement(WhileStatement* stmt) {
1290 TagScope tag(this, "WhileStatement");
1291 Visit(stmt->cond());
1292 Visit(stmt->body());
1293}
1294
1295
1296void JsonAstBuilder::VisitForStatement(ForStatement* stmt) {
1297 TagScope tag(this, "ForStatement");
1298 if (stmt->init() != NULL) Visit(stmt->init());
1299 if (stmt->cond() != NULL) Visit(stmt->cond());
1300 Visit(stmt->body());
1301 if (stmt->next() != NULL) Visit(stmt->next());
1302}
1303
1304
1305void JsonAstBuilder::VisitForInStatement(ForInStatement* stmt) {
1306 TagScope tag(this, "ForInStatement");
1307 Visit(stmt->each());
1308 Visit(stmt->enumerable());
1309 Visit(stmt->body());
1310}
1311
1312
1313void JsonAstBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
1314 TagScope tag(this, "TryCatchStatement");
1315 Visit(stmt->try_block());
1316 Visit(stmt->catch_var());
1317 Visit(stmt->catch_block());
1318}
1319
1320
1321void JsonAstBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1322 TagScope tag(this, "TryFinallyStatement");
1323 Visit(stmt->try_block());
1324 Visit(stmt->finally_block());
1325}
1326
1327
1328void JsonAstBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
1329 TagScope tag(this, "DebuggerStatement");
1330}
1331
1332
1333void JsonAstBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
1334 TagScope tag(this, "FunctionLiteral");
1335 {
1336 AttributesScope attributes(this);
1337 AddAttribute("name", expr->name());
1338 }
1339 VisitDeclarations(expr->scope()->declarations());
1340 VisitStatements(expr->body());
1341}
1342
1343
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00001344void JsonAstBuilder::VisitSharedFunctionInfoLiteral(
1345 SharedFunctionInfoLiteral* expr) {
1346 TagScope tag(this, "SharedFunctionInfoLiteral");
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001347}
1348
1349
1350void JsonAstBuilder::VisitConditional(Conditional* expr) {
1351 TagScope tag(this, "Conditional");
1352}
1353
1354
1355void JsonAstBuilder::VisitSlot(Slot* expr) {
1356 TagScope tag(this, "Slot");
1357 {
1358 AttributesScope attributes(this);
1359 switch (expr->type()) {
1360 case Slot::PARAMETER:
1361 AddAttribute("type", "PARAMETER");
1362 break;
1363 case Slot::LOCAL:
1364 AddAttribute("type", "LOCAL");
1365 break;
1366 case Slot::CONTEXT:
1367 AddAttribute("type", "CONTEXT");
1368 break;
1369 case Slot::LOOKUP:
1370 AddAttribute("type", "LOOKUP");
1371 break;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001372 }
1373 AddAttribute("index", expr->index());
1374 }
1375}
1376
1377
1378void JsonAstBuilder::VisitVariableProxy(VariableProxy* expr) {
1379 if (expr->var()->rewrite() == NULL) {
1380 TagScope tag(this, "VariableProxy");
1381 {
1382 AttributesScope attributes(this);
1383 AddAttribute("name", expr->name());
1384 AddAttribute("mode", Variable::Mode2String(expr->var()->mode()));
1385 }
1386 } else {
1387 Visit(expr->var()->rewrite());
1388 }
1389}
1390
1391
1392void JsonAstBuilder::VisitLiteral(Literal* expr) {
1393 TagScope tag(this, "Literal");
1394 {
1395 AttributesScope attributes(this);
1396 Handle<Object> handle = expr->handle();
1397 if (handle->IsString()) {
1398 AddAttribute("handle", Handle<String>(String::cast(*handle)));
1399 } else if (handle->IsSmi()) {
1400 AddAttribute("handle", Smi::cast(*handle)->value());
1401 }
1402 }
1403}
1404
1405
1406void JsonAstBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
1407 TagScope tag(this, "RegExpLiteral");
1408}
1409
1410
1411void JsonAstBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
1412 TagScope tag(this, "ObjectLiteral");
1413}
1414
1415
1416void JsonAstBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
1417 TagScope tag(this, "ArrayLiteral");
1418}
1419
1420
1421void JsonAstBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
1422 TagScope tag(this, "CatchExtensionObject");
1423 Visit(expr->key());
1424 Visit(expr->value());
1425}
1426
1427
1428void JsonAstBuilder::VisitAssignment(Assignment* expr) {
1429 TagScope tag(this, "Assignment");
1430 {
1431 AttributesScope attributes(this);
1432 AddAttribute("op", Token::Name(expr->op()));
1433 }
1434 Visit(expr->target());
1435 Visit(expr->value());
1436}
1437
1438
1439void JsonAstBuilder::VisitThrow(Throw* expr) {
1440 TagScope tag(this, "Throw");
1441 Visit(expr->exception());
1442}
1443
1444
1445void JsonAstBuilder::VisitProperty(Property* expr) {
1446 TagScope tag(this, "Property");
1447 {
1448 AttributesScope attributes(this);
1449 AddAttribute("type", expr->is_synthetic() ? "SYNTHETIC" : "NORMAL");
1450 }
1451 Visit(expr->obj());
1452 Visit(expr->key());
1453}
1454
1455
1456void JsonAstBuilder::VisitCall(Call* expr) {
1457 TagScope tag(this, "Call");
1458 Visit(expr->expression());
1459 VisitExpressions(expr->arguments());
1460}
1461
1462
1463void JsonAstBuilder::VisitCallNew(CallNew* expr) {
1464 TagScope tag(this, "CallNew");
1465 Visit(expr->expression());
1466 VisitExpressions(expr->arguments());
1467}
1468
1469
1470void JsonAstBuilder::VisitCallRuntime(CallRuntime* expr) {
1471 TagScope tag(this, "CallRuntime");
1472 {
1473 AttributesScope attributes(this);
1474 AddAttribute("name", expr->name());
1475 }
1476 VisitExpressions(expr->arguments());
1477}
1478
1479
1480void JsonAstBuilder::VisitUnaryOperation(UnaryOperation* expr) {
1481 TagScope tag(this, "UnaryOperation");
1482 {
1483 AttributesScope attributes(this);
1484 AddAttribute("op", Token::Name(expr->op()));
1485 }
1486 Visit(expr->expression());
1487}
1488
1489
ricow@chromium.org65fae842010-08-25 15:26:24 +00001490void JsonAstBuilder::VisitIncrementOperation(IncrementOperation* expr) {
1491 UNREACHABLE();
1492}
1493
1494
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001495void JsonAstBuilder::VisitCountOperation(CountOperation* expr) {
1496 TagScope tag(this, "CountOperation");
1497 {
1498 AttributesScope attributes(this);
1499 AddAttribute("is_prefix", expr->is_prefix());
1500 AddAttribute("op", Token::Name(expr->op()));
1501 }
1502 Visit(expr->expression());
1503}
1504
1505
1506void JsonAstBuilder::VisitBinaryOperation(BinaryOperation* expr) {
1507 TagScope tag(this, "BinaryOperation");
1508 {
1509 AttributesScope attributes(this);
1510 AddAttribute("op", Token::Name(expr->op()));
1511 }
1512 Visit(expr->left());
1513 Visit(expr->right());
1514}
1515
1516
1517void JsonAstBuilder::VisitCompareOperation(CompareOperation* expr) {
1518 TagScope tag(this, "CompareOperation");
1519 {
1520 AttributesScope attributes(this);
1521 AddAttribute("op", Token::Name(expr->op()));
1522 }
1523 Visit(expr->left());
1524 Visit(expr->right());
1525}
1526
1527
ricow@chromium.org65fae842010-08-25 15:26:24 +00001528void JsonAstBuilder::VisitCompareToNull(CompareToNull* expr) {
1529 TagScope tag(this, "CompareToNull");
1530 {
1531 AttributesScope attributes(this);
1532 AddAttribute("is_strict", expr->is_strict());
1533 }
1534 Visit(expr->expression());
1535}
1536
1537
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001538void JsonAstBuilder::VisitThisFunction(ThisFunction* expr) {
1539 TagScope tag(this, "ThisFunction");
1540}
1541
1542
1543void JsonAstBuilder::VisitDeclaration(Declaration* decl) {
1544 TagScope tag(this, "Declaration");
1545 {
1546 AttributesScope attributes(this);
1547 AddAttribute("mode", Variable::Mode2String(decl->mode()));
1548 }
1549 Visit(decl->proxy());
1550 if (decl->fun() != NULL) Visit(decl->fun());
1551}
1552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001553
1554#endif // DEBUG
1555
1556} } // namespace v8::internal