[go: nahoru, domu]

blob: 663af284b402357d4ba467d326a872d6d3d683f9 [file] [log] [blame]
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +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
36namespace v8 {
37namespace internal {
38
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
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000126void PrettyPrinter::VisitWithStatement(WithStatement* node) {
127 Print("with (");
Steve Blocka7e24c12009-10-30 11:49:00 +0000128 Visit(node->expression());
129 Print(") ");
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000130 Visit(node->statement());
Steve Blocka7e24c12009-10-30 11:49:00 +0000131}
132
133
Steve Blocka7e24c12009-10-30 11:49:00 +0000134void PrettyPrinter::VisitSwitchStatement(SwitchStatement* node) {
135 PrintLabels(node->labels());
136 Print("switch (");
137 Visit(node->tag());
138 Print(") { ");
139 ZoneList<CaseClause*>* cases = node->cases();
140 for (int i = 0; i < cases->length(); i++)
141 PrintCaseClause(cases->at(i));
142 Print("}");
143}
144
145
Steve Block3ce2e202009-11-05 08:53:23 +0000146void PrettyPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000147 PrintLabels(node->labels());
Steve Block3ce2e202009-11-05 08:53:23 +0000148 Print("do ");
149 Visit(node->body());
150 Print(" while (");
151 Visit(node->cond());
152 Print(");");
153}
Steve Blocka7e24c12009-10-30 11:49:00 +0000154
Steve Blocka7e24c12009-10-30 11:49:00 +0000155
Steve Block3ce2e202009-11-05 08:53:23 +0000156void PrettyPrinter::VisitWhileStatement(WhileStatement* node) {
157 PrintLabels(node->labels());
158 Print("while (");
159 Visit(node->cond());
160 Print(") ");
161 Visit(node->body());
162}
163
164
165void PrettyPrinter::VisitForStatement(ForStatement* node) {
166 PrintLabels(node->labels());
167 Print("for (");
168 if (node->init() != NULL) {
169 Visit(node->init());
170 Print(" ");
171 } else {
172 Print("; ");
Steve Blocka7e24c12009-10-30 11:49:00 +0000173 }
Steve Block3ce2e202009-11-05 08:53:23 +0000174 if (node->cond() != NULL) Visit(node->cond());
175 Print("; ");
176 if (node->next() != NULL) {
177 Visit(node->next()); // prints extra ';', unfortunately
178 // to fix: should use Expression for next
179 }
180 Print(") ");
181 Visit(node->body());
Steve Blocka7e24c12009-10-30 11:49:00 +0000182}
183
184
185void PrettyPrinter::VisitForInStatement(ForInStatement* node) {
186 PrintLabels(node->labels());
187 Print("for (");
188 Visit(node->each());
189 Print(" in ");
190 Visit(node->enumerable());
191 Print(") ");
192 Visit(node->body());
193}
194
195
Steve Block3ce2e202009-11-05 08:53:23 +0000196void PrettyPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000197 Print("try ");
198 Visit(node->try_block());
199 Print(" catch (");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000200 const bool quote = false;
201 PrintLiteral(node->variable()->name(), quote);
Steve Blocka7e24c12009-10-30 11:49:00 +0000202 Print(") ");
203 Visit(node->catch_block());
204}
205
206
Steve Block3ce2e202009-11-05 08:53:23 +0000207void PrettyPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000208 Print("try ");
209 Visit(node->try_block());
210 Print(" finally ");
211 Visit(node->finally_block());
212}
213
214
215void PrettyPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
216 Print("debugger ");
217}
218
219
220void PrettyPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
221 Print("(");
222 PrintFunctionLiteral(node);
223 Print(")");
224}
225
226
Steve Block6ded16b2010-05-10 14:33:55 +0100227void PrettyPrinter::VisitSharedFunctionInfoLiteral(
228 SharedFunctionInfoLiteral* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000229 Print("(");
Steve Block6ded16b2010-05-10 14:33:55 +0100230 PrintLiteral(node->shared_function_info(), true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 Print(")");
232}
233
234
235void PrettyPrinter::VisitConditional(Conditional* node) {
236 Visit(node->condition());
237 Print(" ? ");
238 Visit(node->then_expression());
239 Print(" : ");
240 Visit(node->else_expression());
241}
242
243
244void PrettyPrinter::VisitLiteral(Literal* node) {
245 PrintLiteral(node->handle(), true);
246}
247
248
249void PrettyPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
250 Print(" RegExp(");
251 PrintLiteral(node->pattern(), false);
252 Print(",");
253 PrintLiteral(node->flags(), false);
254 Print(") ");
255}
256
257
258void PrettyPrinter::VisitObjectLiteral(ObjectLiteral* node) {
259 Print("{ ");
260 for (int i = 0; i < node->properties()->length(); i++) {
261 if (i != 0) Print(",");
262 ObjectLiteral::Property* property = node->properties()->at(i);
263 Print(" ");
264 Visit(property->key());
265 Print(": ");
266 Visit(property->value());
267 }
268 Print(" }");
269}
270
271
272void PrettyPrinter::VisitArrayLiteral(ArrayLiteral* node) {
273 Print("[ ");
274 for (int i = 0; i < node->values()->length(); i++) {
275 if (i != 0) Print(",");
276 Visit(node->values()->at(i));
277 }
278 Print(" ]");
279}
280
281
Steve Blocka7e24c12009-10-30 11:49:00 +0000282void PrettyPrinter::VisitVariableProxy(VariableProxy* node) {
283 PrintLiteral(node->name(), false);
284}
285
286
287void PrettyPrinter::VisitAssignment(Assignment* node) {
288 Visit(node->target());
289 Print(" %s ", Token::String(node->op()));
290 Visit(node->value());
291}
292
293
294void PrettyPrinter::VisitThrow(Throw* node) {
295 Print("throw ");
296 Visit(node->exception());
297}
298
299
300void PrettyPrinter::VisitProperty(Property* node) {
301 Expression* key = node->key();
302 Literal* literal = key->AsLiteral();
303 if (literal != NULL && literal->handle()->IsSymbol()) {
304 Print("(");
305 Visit(node->obj());
306 Print(").");
307 PrintLiteral(literal->handle(), false);
308 } else {
309 Visit(node->obj());
310 Print("[");
311 Visit(key);
312 Print("]");
313 }
314}
315
316
317void PrettyPrinter::VisitCall(Call* node) {
318 Visit(node->expression());
319 PrintArguments(node->arguments());
320}
321
322
323void PrettyPrinter::VisitCallNew(CallNew* node) {
324 Print("new (");
325 Visit(node->expression());
326 Print(")");
327 PrintArguments(node->arguments());
328}
329
330
331void PrettyPrinter::VisitCallRuntime(CallRuntime* node) {
332 Print("%%");
333 PrintLiteral(node->name(), false);
334 PrintArguments(node->arguments());
335}
336
337
338void PrettyPrinter::VisitUnaryOperation(UnaryOperation* node) {
Ben Murdoch257744e2011-11-30 15:57:28 +0000339 Token::Value op = node->op();
340 bool needsSpace =
341 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
342 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
Steve Blocka7e24c12009-10-30 11:49:00 +0000343 Visit(node->expression());
344 Print(")");
345}
346
347
348void PrettyPrinter::VisitCountOperation(CountOperation* node) {
349 Print("(");
350 if (node->is_prefix()) Print("%s", Token::String(node->op()));
351 Visit(node->expression());
352 if (node->is_postfix()) Print("%s", Token::String(node->op()));
353 Print(")");
354}
355
356
357void PrettyPrinter::VisitBinaryOperation(BinaryOperation* node) {
358 Print("(");
359 Visit(node->left());
Ben Murdoch257744e2011-11-30 15:57:28 +0000360 Print(" %s ", Token::String(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000361 Visit(node->right());
362 Print(")");
363}
364
365
366void PrettyPrinter::VisitCompareOperation(CompareOperation* node) {
367 Print("(");
368 Visit(node->left());
Ben Murdoch257744e2011-11-30 15:57:28 +0000369 Print(" %s ", Token::String(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +0000370 Visit(node->right());
371 Print(")");
372}
373
374
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100375void PrettyPrinter::VisitCompareToNull(CompareToNull* node) {
376 Print("(");
377 Visit(node->expression());
378 Print("%s null)", Token::String(node->op()));
379}
380
381
Steve Blocka7e24c12009-10-30 11:49:00 +0000382void PrettyPrinter::VisitThisFunction(ThisFunction* node) {
383 Print("<this-function>");
384}
385
386
387const char* PrettyPrinter::Print(AstNode* node) {
388 Init();
389 Visit(node);
390 return output_;
391}
392
393
394const char* PrettyPrinter::PrintExpression(FunctionLiteral* program) {
395 Init();
396 ExpressionStatement* statement =
397 program->body()->at(0)->AsExpressionStatement();
398 Visit(statement->expression());
399 return output_;
400}
401
402
403const char* PrettyPrinter::PrintProgram(FunctionLiteral* program) {
404 Init();
405 PrintStatements(program->body());
406 Print("\n");
407 return output_;
408}
409
410
411void PrettyPrinter::PrintOut(AstNode* node) {
412 PrettyPrinter printer;
413 PrintF("%s", printer.Print(node));
414}
415
416
417void PrettyPrinter::Init() {
418 if (size_ == 0) {
419 ASSERT(output_ == NULL);
420 const int initial_size = 256;
421 output_ = NewArray<char>(initial_size);
422 size_ = initial_size;
423 }
424 output_[0] = '\0';
425 pos_ = 0;
426}
427
428
429void PrettyPrinter::Print(const char* format, ...) {
430 for (;;) {
431 va_list arguments;
432 va_start(arguments, format);
433 int n = OS::VSNPrintF(Vector<char>(output_, size_) + pos_,
434 format,
435 arguments);
436 va_end(arguments);
437
438 if (n >= 0) {
439 // there was enough space - we are done
440 pos_ += n;
441 return;
442 } else {
443 // there was not enough space - allocate more and try again
444 const int slack = 32;
445 int new_size = size_ + (size_ >> 1) + slack;
446 char* new_output = NewArray<char>(new_size);
447 memcpy(new_output, output_, pos_);
448 DeleteArray(output_);
449 output_ = new_output;
450 size_ = new_size;
451 }
452 }
453}
454
455
456void PrettyPrinter::PrintStatements(ZoneList<Statement*>* statements) {
457 for (int i = 0; i < statements->length(); i++) {
458 if (i != 0) Print(" ");
459 Visit(statements->at(i));
460 }
461}
462
463
464void PrettyPrinter::PrintLabels(ZoneStringList* labels) {
465 if (labels != NULL) {
466 for (int i = 0; i < labels->length(); i++) {
467 PrintLiteral(labels->at(i), false);
468 Print(": ");
469 }
470 }
471}
472
473
474void PrettyPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
475 Print("(");
476 for (int i = 0; i < arguments->length(); i++) {
477 if (i != 0) Print(", ");
478 Visit(arguments->at(i));
479 }
480 Print(")");
481}
482
483
484void PrettyPrinter::PrintLiteral(Handle<Object> value, bool quote) {
485 Object* object = *value;
486 if (object->IsString()) {
487 String* string = String::cast(object);
488 if (quote) Print("\"");
489 for (int i = 0; i < string->length(); i++) {
490 Print("%c", string->Get(i));
491 }
492 if (quote) Print("\"");
Steve Block44f0eee2011-05-26 01:26:41 +0100493 } else if (object->IsNull()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000494 Print("null");
Steve Block44f0eee2011-05-26 01:26:41 +0100495 } else if (object->IsTrue()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000496 Print("true");
Steve Block44f0eee2011-05-26 01:26:41 +0100497 } else if (object->IsFalse()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000498 Print("false");
Steve Block44f0eee2011-05-26 01:26:41 +0100499 } else if (object->IsUndefined()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000500 Print("undefined");
501 } else if (object->IsNumber()) {
502 Print("%g", object->Number());
503 } else if (object->IsJSObject()) {
504 // regular expression
505 if (object->IsJSFunction()) {
506 Print("JS-Function");
507 } else if (object->IsJSArray()) {
508 Print("JS-array[%u]", JSArray::cast(object)->length());
509 } else if (object->IsJSObject()) {
510 Print("JS-Object");
511 } else {
512 Print("?UNKNOWN?");
513 }
514 } else if (object->IsFixedArray()) {
515 Print("FixedArray");
516 } else {
517 Print("<unknown literal %p>", object);
518 }
519}
520
521
522void PrettyPrinter::PrintParameters(Scope* scope) {
523 Print("(");
524 for (int i = 0; i < scope->num_parameters(); i++) {
525 if (i > 0) Print(", ");
526 PrintLiteral(scope->parameter(i)->name(), false);
527 }
528 Print(")");
529}
530
531
532void PrettyPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
533 for (int i = 0; i < declarations->length(); i++) {
534 if (i > 0) Print(" ");
535 Visit(declarations->at(i));
536 }
537}
538
539
540void PrettyPrinter::PrintFunctionLiteral(FunctionLiteral* function) {
541 Print("function ");
542 PrintLiteral(function->name(), false);
543 PrintParameters(function->scope());
544 Print(" { ");
545 PrintDeclarations(function->scope()->declarations());
546 PrintStatements(function->body());
547 Print(" }");
548}
549
550
551void PrettyPrinter::PrintCaseClause(CaseClause* clause) {
552 if (clause->is_default()) {
553 Print("default");
554 } else {
555 Print("case ");
556 Visit(clause->label());
557 }
558 Print(": ");
559 PrintStatements(clause->statements());
560 if (clause->statements()->length() > 0)
561 Print(" ");
562}
563
564
565//-----------------------------------------------------------------------------
566
567class IndentedScope BASE_EMBEDDED {
568 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100569 explicit IndentedScope(AstPrinter* printer) : ast_printer_(printer) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000570 ast_printer_->inc_indent();
571 }
572
Steve Block44f0eee2011-05-26 01:26:41 +0100573 IndentedScope(AstPrinter* printer, const char* txt, AstNode* node = NULL)
574 : ast_printer_(printer) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000575 ast_printer_->PrintIndented(txt);
Steve Blocka7e24c12009-10-30 11:49:00 +0000576 ast_printer_->Print("\n");
577 ast_printer_->inc_indent();
578 }
579
580 virtual ~IndentedScope() {
581 ast_printer_->dec_indent();
582 }
583
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100585 AstPrinter* ast_printer_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000586};
587
588
Steve Blocka7e24c12009-10-30 11:49:00 +0000589//-----------------------------------------------------------------------------
590
Steve Blocka7e24c12009-10-30 11:49:00 +0000591
Steve Block44f0eee2011-05-26 01:26:41 +0100592AstPrinter::AstPrinter() : indent_(0) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000593}
594
595
596AstPrinter::~AstPrinter() {
597 ASSERT(indent_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000598}
599
600
601void AstPrinter::PrintIndented(const char* txt) {
602 for (int i = 0; i < indent_; i++) {
603 Print(". ");
604 }
605 Print(txt);
606}
607
608
609void AstPrinter::PrintLiteralIndented(const char* info,
610 Handle<Object> value,
611 bool quote) {
612 PrintIndented(info);
613 Print(" ");
614 PrintLiteral(value, quote);
615 Print("\n");
616}
617
618
619void AstPrinter::PrintLiteralWithModeIndented(const char* info,
620 Variable* var,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100621 Handle<Object> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000622 if (var == NULL) {
623 PrintLiteralIndented(info, value, true);
624 } else {
625 EmbeddedVector<char, 256> buf;
Leon Clarke4515c472010-02-03 11:58:03 +0000626 int pos = OS::SNPrintF(buf, "%s (mode = %s", info,
627 Variable::Mode2String(var->mode()));
Leon Clarke4515c472010-02-03 11:58:03 +0000628 OS::SNPrintF(buf + pos, ")");
Steve Blocka7e24c12009-10-30 11:49:00 +0000629 PrintLiteralIndented(buf.start(), value, true);
630 }
631}
632
633
634void AstPrinter::PrintLabelsIndented(const char* info, ZoneStringList* labels) {
635 if (labels != NULL && labels->length() > 0) {
Ben Murdoch589d6972011-11-30 16:04:58 +0000636 PrintIndented(info == NULL ? "LABELS" : info);
637 Print(" ");
Steve Blocka7e24c12009-10-30 11:49:00 +0000638 PrintLabels(labels);
Ben Murdoch589d6972011-11-30 16:04:58 +0000639 Print("\n");
Steve Blocka7e24c12009-10-30 11:49:00 +0000640 } else if (info != NULL) {
641 PrintIndented(info);
Ben Murdoch589d6972011-11-30 16:04:58 +0000642 Print("\n");
Steve Blocka7e24c12009-10-30 11:49:00 +0000643 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000644}
645
646
647void AstPrinter::PrintIndentedVisit(const char* s, AstNode* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100648 IndentedScope indent(this, s, node);
Steve Blocka7e24c12009-10-30 11:49:00 +0000649 Visit(node);
650}
651
652
653const char* AstPrinter::PrintProgram(FunctionLiteral* program) {
654 Init();
Steve Block44f0eee2011-05-26 01:26:41 +0100655 { IndentedScope indent(this, "FUNC");
Steve Blocka7e24c12009-10-30 11:49:00 +0000656 PrintLiteralIndented("NAME", program->name(), true);
657 PrintLiteralIndented("INFERRED NAME", program->inferred_name(), true);
658 PrintParameters(program->scope());
659 PrintDeclarations(program->scope()->declarations());
660 PrintStatements(program->body());
661 }
662 return Output();
663}
664
665
666void AstPrinter::PrintDeclarations(ZoneList<Declaration*>* declarations) {
667 if (declarations->length() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100668 IndentedScope indent(this, "DECLS");
Steve Blocka7e24c12009-10-30 11:49:00 +0000669 for (int i = 0; i < declarations->length(); i++) {
670 Visit(declarations->at(i));
671 }
672 }
673}
674
675
676void AstPrinter::PrintParameters(Scope* scope) {
677 if (scope->num_parameters() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100678 IndentedScope indent(this, "PARAMS");
Steve Blocka7e24c12009-10-30 11:49:00 +0000679 for (int i = 0; i < scope->num_parameters(); i++) {
680 PrintLiteralWithModeIndented("VAR", scope->parameter(i),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100681 scope->parameter(i)->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000682 }
683 }
684}
685
686
687void AstPrinter::PrintStatements(ZoneList<Statement*>* statements) {
688 for (int i = 0; i < statements->length(); i++) {
689 Visit(statements->at(i));
690 }
691}
692
693
694void AstPrinter::PrintArguments(ZoneList<Expression*>* arguments) {
695 for (int i = 0; i < arguments->length(); i++) {
696 Visit(arguments->at(i));
697 }
698}
699
700
701void AstPrinter::PrintCaseClause(CaseClause* clause) {
702 if (clause->is_default()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100703 IndentedScope indent(this, "DEFAULT");
Steve Blocka7e24c12009-10-30 11:49:00 +0000704 PrintStatements(clause->statements());
705 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100706 IndentedScope indent(this, "CASE");
Steve Blocka7e24c12009-10-30 11:49:00 +0000707 Visit(clause->label());
708 PrintStatements(clause->statements());
709 }
710}
711
712
713void AstPrinter::VisitBlock(Block* node) {
714 const char* block_txt = node->is_initializer_block() ? "BLOCK INIT" : "BLOCK";
Steve Block44f0eee2011-05-26 01:26:41 +0100715 IndentedScope indent(this, block_txt);
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 PrintStatements(node->statements());
717}
718
719
720void AstPrinter::VisitDeclaration(Declaration* node) {
721 if (node->fun() == NULL) {
722 // var or const declarations
723 PrintLiteralWithModeIndented(Variable::Mode2String(node->mode()),
Ben Murdoch589d6972011-11-30 16:04:58 +0000724 node->proxy()->var(),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100725 node->proxy()->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000726 } else {
727 // function declarations
728 PrintIndented("FUNCTION ");
729 PrintLiteral(node->proxy()->name(), true);
730 Print(" = function ");
731 PrintLiteral(node->fun()->name(), false);
732 Print("\n");
733 }
734}
735
736
737void AstPrinter::VisitExpressionStatement(ExpressionStatement* node) {
738 Visit(node->expression());
739}
740
741
742void AstPrinter::VisitEmptyStatement(EmptyStatement* node) {
743 PrintIndented("EMPTY\n");
744}
745
746
747void AstPrinter::VisitIfStatement(IfStatement* node) {
748 PrintIndentedVisit("IF", node->condition());
749 PrintIndentedVisit("THEN", node->then_statement());
750 if (node->HasElseStatement()) {
751 PrintIndentedVisit("ELSE", node->else_statement());
752 }
753}
754
755
756void AstPrinter::VisitContinueStatement(ContinueStatement* node) {
757 PrintLabelsIndented("CONTINUE", node->target()->labels());
758}
759
760
761void AstPrinter::VisitBreakStatement(BreakStatement* node) {
762 PrintLabelsIndented("BREAK", node->target()->labels());
763}
764
765
766void AstPrinter::VisitReturnStatement(ReturnStatement* node) {
767 PrintIndentedVisit("RETURN", node->expression());
768}
769
770
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000771void AstPrinter::VisitWithStatement(WithStatement* node) {
772 IndentedScope indent(this, "WITH");
773 PrintIndentedVisit("OBJECT", node->expression());
774 PrintIndentedVisit("BODY", node->statement());
Steve Blocka7e24c12009-10-30 11:49:00 +0000775}
776
777
Steve Blocka7e24c12009-10-30 11:49:00 +0000778void AstPrinter::VisitSwitchStatement(SwitchStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100779 IndentedScope indent(this, "SWITCH");
Steve Blocka7e24c12009-10-30 11:49:00 +0000780 PrintLabelsIndented(NULL, node->labels());
781 PrintIndentedVisit("TAG", node->tag());
782 for (int i = 0; i < node->cases()->length(); i++) {
783 PrintCaseClause(node->cases()->at(i));
784 }
785}
786
787
Steve Block3ce2e202009-11-05 08:53:23 +0000788void AstPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100789 IndentedScope indent(this, "DO");
Steve Block3ce2e202009-11-05 08:53:23 +0000790 PrintLabelsIndented(NULL, node->labels());
791 PrintIndentedVisit("BODY", node->body());
792 PrintIndentedVisit("COND", node->cond());
793}
794
795
796void AstPrinter::VisitWhileStatement(WhileStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100797 IndentedScope indent(this, "WHILE");
Steve Block3ce2e202009-11-05 08:53:23 +0000798 PrintLabelsIndented(NULL, node->labels());
799 PrintIndentedVisit("COND", node->cond());
800 PrintIndentedVisit("BODY", node->body());
801}
802
803
804void AstPrinter::VisitForStatement(ForStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100805 IndentedScope indent(this, "FOR");
Steve Blocka7e24c12009-10-30 11:49:00 +0000806 PrintLabelsIndented(NULL, node->labels());
807 if (node->init()) PrintIndentedVisit("INIT", node->init());
808 if (node->cond()) PrintIndentedVisit("COND", node->cond());
Steve Block3ce2e202009-11-05 08:53:23 +0000809 PrintIndentedVisit("BODY", node->body());
Steve Blocka7e24c12009-10-30 11:49:00 +0000810 if (node->next()) PrintIndentedVisit("NEXT", node->next());
811}
812
813
814void AstPrinter::VisitForInStatement(ForInStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100815 IndentedScope indent(this, "FOR IN");
Steve Blocka7e24c12009-10-30 11:49:00 +0000816 PrintIndentedVisit("FOR", node->each());
817 PrintIndentedVisit("IN", node->enumerable());
818 PrintIndentedVisit("BODY", node->body());
819}
820
821
Steve Block3ce2e202009-11-05 08:53:23 +0000822void AstPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100823 IndentedScope indent(this, "TRY CATCH");
Steve Blocka7e24c12009-10-30 11:49:00 +0000824 PrintIndentedVisit("TRY", node->try_block());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000825 PrintLiteralWithModeIndented("CATCHVAR",
826 node->variable(),
827 node->variable()->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000828 PrintIndentedVisit("CATCH", node->catch_block());
829}
830
831
Steve Block3ce2e202009-11-05 08:53:23 +0000832void AstPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100833 IndentedScope indent(this, "TRY FINALLY");
Steve Blocka7e24c12009-10-30 11:49:00 +0000834 PrintIndentedVisit("TRY", node->try_block());
835 PrintIndentedVisit("FINALLY", node->finally_block());
836}
837
838
839void AstPrinter::VisitDebuggerStatement(DebuggerStatement* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100840 IndentedScope indent(this, "DEBUGGER");
Steve Blocka7e24c12009-10-30 11:49:00 +0000841}
842
843
844void AstPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100845 IndentedScope indent(this, "FUNC LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000846 PrintLiteralIndented("NAME", node->name(), false);
847 PrintLiteralIndented("INFERRED NAME", node->inferred_name(), false);
848 PrintParameters(node->scope());
849 // We don't want to see the function literal in this case: it
850 // will be printed via PrintProgram when the code for it is
851 // generated.
852 // PrintStatements(node->body());
853}
854
855
Steve Block6ded16b2010-05-10 14:33:55 +0100856void AstPrinter::VisitSharedFunctionInfoLiteral(
857 SharedFunctionInfoLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100858 IndentedScope indent(this, "FUNC LITERAL");
Steve Block6ded16b2010-05-10 14:33:55 +0100859 PrintLiteralIndented("SHARED INFO", node->shared_function_info(), true);
Steve Blocka7e24c12009-10-30 11:49:00 +0000860}
861
862
863void AstPrinter::VisitConditional(Conditional* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100864 IndentedScope indent(this, "CONDITIONAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000865 PrintIndentedVisit("?", node->condition());
866 PrintIndentedVisit("THEN", node->then_expression());
867 PrintIndentedVisit("ELSE", node->else_expression());
868}
869
870
871void AstPrinter::VisitLiteral(Literal* node) {
872 PrintLiteralIndented("LITERAL", node->handle(), true);
873}
874
875
876void AstPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100877 IndentedScope indent(this, "REGEXP LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000878 PrintLiteralIndented("PATTERN", node->pattern(), false);
879 PrintLiteralIndented("FLAGS", node->flags(), false);
880}
881
882
883void AstPrinter::VisitObjectLiteral(ObjectLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100884 IndentedScope indent(this, "OBJ LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000885 for (int i = 0; i < node->properties()->length(); i++) {
886 const char* prop_kind = NULL;
887 switch (node->properties()->at(i)->kind()) {
888 case ObjectLiteral::Property::CONSTANT:
889 prop_kind = "PROPERTY - CONSTANT";
890 break;
891 case ObjectLiteral::Property::COMPUTED:
892 prop_kind = "PROPERTY - COMPUTED";
893 break;
894 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
895 prop_kind = "PROPERTY - MATERIALIZED_LITERAL";
896 break;
897 case ObjectLiteral::Property::PROTOTYPE:
898 prop_kind = "PROPERTY - PROTOTYPE";
899 break;
900 case ObjectLiteral::Property::GETTER:
901 prop_kind = "PROPERTY - GETTER";
902 break;
903 case ObjectLiteral::Property::SETTER:
904 prop_kind = "PROPERTY - SETTER";
905 break;
906 default:
907 UNREACHABLE();
908 }
Steve Block44f0eee2011-05-26 01:26:41 +0100909 IndentedScope prop(this, prop_kind);
Steve Blocka7e24c12009-10-30 11:49:00 +0000910 PrintIndentedVisit("KEY", node->properties()->at(i)->key());
911 PrintIndentedVisit("VALUE", node->properties()->at(i)->value());
912 }
913}
914
915
916void AstPrinter::VisitArrayLiteral(ArrayLiteral* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100917 IndentedScope indent(this, "ARRAY LITERAL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 if (node->values()->length() > 0) {
Steve Block44f0eee2011-05-26 01:26:41 +0100919 IndentedScope indent(this, "VALUES");
Steve Blocka7e24c12009-10-30 11:49:00 +0000920 for (int i = 0; i < node->values()->length(); i++) {
921 Visit(node->values()->at(i));
922 }
923 }
924}
925
926
Steve Blocka7e24c12009-10-30 11:49:00 +0000927void AstPrinter::VisitVariableProxy(VariableProxy* node) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000928 Variable* var = node->var();
Ben Murdoch589d6972011-11-30 16:04:58 +0000929 EmbeddedVector<char, 128> buf;
930 int pos = OS::SNPrintF(buf, "VAR PROXY");
931 switch (var->location()) {
932 case Variable::UNALLOCATED:
933 break;
934 case Variable::PARAMETER:
935 OS::SNPrintF(buf + pos, " parameter[%d]", var->index());
936 break;
937 case Variable::LOCAL:
938 OS::SNPrintF(buf + pos, " local[%d]", var->index());
939 break;
940 case Variable::CONTEXT:
941 OS::SNPrintF(buf + pos, " context[%d]", var->index());
942 break;
943 case Variable::LOOKUP:
944 OS::SNPrintF(buf + pos, " lookup");
945 break;
Steve Blocka7e24c12009-10-30 11:49:00 +0000946 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000947 PrintLiteralWithModeIndented(buf.start(), var, node->name());
Steve Blocka7e24c12009-10-30 11:49:00 +0000948}
949
950
951void AstPrinter::VisitAssignment(Assignment* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100952 IndentedScope indent(this, Token::Name(node->op()), node);
Steve Blocka7e24c12009-10-30 11:49:00 +0000953 Visit(node->target());
954 Visit(node->value());
955}
956
957
958void AstPrinter::VisitThrow(Throw* node) {
959 PrintIndentedVisit("THROW", node->exception());
960}
961
962
963void AstPrinter::VisitProperty(Property* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100964 IndentedScope indent(this, "PROPERTY", node);
Steve Blocka7e24c12009-10-30 11:49:00 +0000965 Visit(node->obj());
966 Literal* literal = node->key()->AsLiteral();
967 if (literal != NULL && literal->handle()->IsSymbol()) {
968 PrintLiteralIndented("NAME", literal->handle(), false);
969 } else {
970 PrintIndentedVisit("KEY", node->key());
971 }
972}
973
974
975void AstPrinter::VisitCall(Call* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100976 IndentedScope indent(this, "CALL");
Steve Blocka7e24c12009-10-30 11:49:00 +0000977 Visit(node->expression());
978 PrintArguments(node->arguments());
979}
980
981
982void AstPrinter::VisitCallNew(CallNew* node) {
Steve Block44f0eee2011-05-26 01:26:41 +0100983 IndentedScope indent(this, "CALL NEW");
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 Visit(node->expression());
985 PrintArguments(node->arguments());
986}
987
988
989void AstPrinter::VisitCallRuntime(CallRuntime* node) {
990 PrintLiteralIndented("CALL RUNTIME ", node->name(), false);
Steve Block44f0eee2011-05-26 01:26:41 +0100991 IndentedScope indent(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000992 PrintArguments(node->arguments());
993}
994
995
996void AstPrinter::VisitUnaryOperation(UnaryOperation* node) {
997 PrintIndentedVisit(Token::Name(node->op()), node->expression());
998}
999
1000
1001void AstPrinter::VisitCountOperation(CountOperation* node) {
1002 EmbeddedVector<char, 128> buf;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001003 OS::SNPrintF(buf, "%s %s", (node->is_prefix() ? "PRE" : "POST"),
1004 Token::Name(node->op()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001005 PrintIndentedVisit(buf.start(), node->expression());
1006}
1007
1008
1009void AstPrinter::VisitBinaryOperation(BinaryOperation* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001010 IndentedScope indent(this, Token::Name(node->op()), node);
Steve Blocka7e24c12009-10-30 11:49:00 +00001011 Visit(node->left());
1012 Visit(node->right());
1013}
1014
1015
1016void AstPrinter::VisitCompareOperation(CompareOperation* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001017 IndentedScope indent(this, Token::Name(node->op()), node);
Steve Blocka7e24c12009-10-30 11:49:00 +00001018 Visit(node->left());
1019 Visit(node->right());
1020}
1021
1022
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001023void AstPrinter::VisitCompareToNull(CompareToNull* node) {
1024 const char* name = node->is_strict()
1025 ? "COMPARE-TO-NULL-STRICT"
1026 : "COMPARE-TO-NULL";
Steve Block44f0eee2011-05-26 01:26:41 +01001027 IndentedScope indent(this, name, node);
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001028 Visit(node->expression());
1029}
1030
1031
Steve Blocka7e24c12009-10-30 11:49:00 +00001032void AstPrinter::VisitThisFunction(ThisFunction* node) {
Steve Block44f0eee2011-05-26 01:26:41 +01001033 IndentedScope indent(this, "THIS-FUNCTION");
Steve Blocka7e24c12009-10-30 11:49:00 +00001034}
1035
1036
Steve Block3ce2e202009-11-05 08:53:23 +00001037TagScope::TagScope(JsonAstBuilder* builder, const char* name)
1038 : builder_(builder), next_(builder->tag()), has_body_(false) {
1039 if (next_ != NULL) {
1040 next_->use();
1041 builder->Print(",\n");
1042 }
1043 builder->set_tag(this);
1044 builder->PrintIndented("[");
1045 builder->Print("\"%s\"", name);
1046 builder->increase_indent(JsonAstBuilder::kTagIndentSize);
1047}
1048
1049
1050TagScope::~TagScope() {
1051 builder_->decrease_indent(JsonAstBuilder::kTagIndentSize);
1052 if (has_body_) {
1053 builder_->Print("\n");
1054 builder_->PrintIndented("]");
1055 } else {
1056 builder_->Print("]");
1057 }
1058 builder_->set_tag(next_);
1059}
1060
1061
1062AttributesScope::AttributesScope(JsonAstBuilder* builder)
1063 : builder_(builder), attribute_count_(0) {
1064 builder->set_attributes(this);
1065 builder->tag()->use();
1066 builder->Print(",\n");
1067 builder->PrintIndented("{");
1068 builder->increase_indent(JsonAstBuilder::kAttributesIndentSize);
1069}
1070
1071
1072AttributesScope::~AttributesScope() {
1073 builder_->decrease_indent(JsonAstBuilder::kAttributesIndentSize);
1074 if (attribute_count_ > 1) {
1075 builder_->Print("\n");
1076 builder_->PrintIndented("}");
1077 } else {
1078 builder_->Print("}");
1079 }
1080 builder_->set_attributes(NULL);
1081}
1082
1083
1084const char* JsonAstBuilder::BuildProgram(FunctionLiteral* program) {
1085 Init();
1086 Visit(program);
1087 Print("\n");
1088 return Output();
1089}
1090
1091
1092void JsonAstBuilder::AddAttributePrefix(const char* name) {
1093 if (attributes()->is_used()) {
1094 Print(",\n");
1095 PrintIndented("\"");
1096 } else {
1097 Print("\"");
1098 }
1099 Print("%s\":", name);
1100 attributes()->use();
1101}
1102
1103
1104void JsonAstBuilder::AddAttribute(const char* name, Handle<String> value) {
Ben Murdoch589d6972011-11-30 16:04:58 +00001105 SmartArrayPointer<char> value_string = value->ToCString();
Steve Block3ce2e202009-11-05 08:53:23 +00001106 AddAttributePrefix(name);
1107 Print("\"%s\"", *value_string);
1108}
1109
1110
1111void JsonAstBuilder::AddAttribute(const char* name, const char* value) {
1112 AddAttributePrefix(name);
1113 Print("\"%s\"", value);
1114}
1115
1116
1117void JsonAstBuilder::AddAttribute(const char* name, int value) {
1118 AddAttributePrefix(name);
1119 Print("%d", value);
1120}
1121
1122
1123void JsonAstBuilder::AddAttribute(const char* name, bool value) {
1124 AddAttributePrefix(name);
1125 Print(value ? "true" : "false");
1126}
1127
1128
1129void JsonAstBuilder::VisitBlock(Block* stmt) {
1130 TagScope tag(this, "Block");
1131 VisitStatements(stmt->statements());
1132}
1133
1134
1135void JsonAstBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
1136 TagScope tag(this, "ExpressionStatement");
1137 Visit(stmt->expression());
1138}
1139
1140
1141void JsonAstBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
1142 TagScope tag(this, "EmptyStatement");
1143}
1144
1145
1146void JsonAstBuilder::VisitIfStatement(IfStatement* stmt) {
1147 TagScope tag(this, "IfStatement");
1148 Visit(stmt->condition());
1149 Visit(stmt->then_statement());
1150 Visit(stmt->else_statement());
1151}
1152
1153
1154void JsonAstBuilder::VisitContinueStatement(ContinueStatement* stmt) {
1155 TagScope tag(this, "ContinueStatement");
1156}
1157
1158
1159void JsonAstBuilder::VisitBreakStatement(BreakStatement* stmt) {
1160 TagScope tag(this, "BreakStatement");
1161}
1162
1163
1164void JsonAstBuilder::VisitReturnStatement(ReturnStatement* stmt) {
1165 TagScope tag(this, "ReturnStatement");
1166 Visit(stmt->expression());
1167}
1168
1169
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001170void JsonAstBuilder::VisitWithStatement(WithStatement* stmt) {
1171 TagScope tag(this, "WithStatement");
Steve Block3ce2e202009-11-05 08:53:23 +00001172 Visit(stmt->expression());
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001173 Visit(stmt->statement());
Steve Block3ce2e202009-11-05 08:53:23 +00001174}
1175
1176
Steve Block3ce2e202009-11-05 08:53:23 +00001177void JsonAstBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
1178 TagScope tag(this, "SwitchStatement");
1179}
1180
1181
1182void JsonAstBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
1183 TagScope tag(this, "DoWhileStatement");
1184 Visit(stmt->body());
1185 Visit(stmt->cond());
1186}
1187
1188
1189void JsonAstBuilder::VisitWhileStatement(WhileStatement* stmt) {
1190 TagScope tag(this, "WhileStatement");
1191 Visit(stmt->cond());
1192 Visit(stmt->body());
1193}
1194
1195
1196void JsonAstBuilder::VisitForStatement(ForStatement* stmt) {
1197 TagScope tag(this, "ForStatement");
1198 if (stmt->init() != NULL) Visit(stmt->init());
1199 if (stmt->cond() != NULL) Visit(stmt->cond());
1200 Visit(stmt->body());
1201 if (stmt->next() != NULL) Visit(stmt->next());
1202}
1203
1204
1205void JsonAstBuilder::VisitForInStatement(ForInStatement* stmt) {
1206 TagScope tag(this, "ForInStatement");
1207 Visit(stmt->each());
1208 Visit(stmt->enumerable());
1209 Visit(stmt->body());
1210}
1211
1212
1213void JsonAstBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
1214 TagScope tag(this, "TryCatchStatement");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001215 { AttributesScope attributes(this);
1216 AddAttribute("variable", stmt->variable()->name());
1217 }
Steve Block3ce2e202009-11-05 08:53:23 +00001218 Visit(stmt->try_block());
Steve Block3ce2e202009-11-05 08:53:23 +00001219 Visit(stmt->catch_block());
1220}
1221
1222
1223void JsonAstBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
1224 TagScope tag(this, "TryFinallyStatement");
1225 Visit(stmt->try_block());
1226 Visit(stmt->finally_block());
1227}
1228
1229
1230void JsonAstBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
1231 TagScope tag(this, "DebuggerStatement");
1232}
1233
1234
1235void JsonAstBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
1236 TagScope tag(this, "FunctionLiteral");
1237 {
1238 AttributesScope attributes(this);
1239 AddAttribute("name", expr->name());
1240 }
1241 VisitDeclarations(expr->scope()->declarations());
1242 VisitStatements(expr->body());
1243}
1244
1245
Steve Block6ded16b2010-05-10 14:33:55 +01001246void JsonAstBuilder::VisitSharedFunctionInfoLiteral(
1247 SharedFunctionInfoLiteral* expr) {
1248 TagScope tag(this, "SharedFunctionInfoLiteral");
Steve Block3ce2e202009-11-05 08:53:23 +00001249}
1250
1251
1252void JsonAstBuilder::VisitConditional(Conditional* expr) {
1253 TagScope tag(this, "Conditional");
1254}
1255
1256
Ben Murdoch589d6972011-11-30 16:04:58 +00001257void JsonAstBuilder::VisitVariableProxy(VariableProxy* expr) {
1258 TagScope tag(this, "Variable");
Steve Block3ce2e202009-11-05 08:53:23 +00001259 {
1260 AttributesScope attributes(this);
Ben Murdoch589d6972011-11-30 16:04:58 +00001261 Variable* var = expr->var();
1262 AddAttribute("name", var->name());
1263 switch (var->location()) {
1264 case Variable::UNALLOCATED:
1265 AddAttribute("location", "UNALLOCATED");
Steve Block3ce2e202009-11-05 08:53:23 +00001266 break;
Ben Murdoch589d6972011-11-30 16:04:58 +00001267 case Variable::PARAMETER:
1268 AddAttribute("location", "PARAMETER");
1269 AddAttribute("index", var->index());
Steve Block3ce2e202009-11-05 08:53:23 +00001270 break;
Ben Murdoch589d6972011-11-30 16:04:58 +00001271 case Variable::LOCAL:
1272 AddAttribute("location", "LOCAL");
1273 AddAttribute("index", var->index());
Steve Block3ce2e202009-11-05 08:53:23 +00001274 break;
Ben Murdoch589d6972011-11-30 16:04:58 +00001275 case Variable::CONTEXT:
1276 AddAttribute("location", "CONTEXT");
1277 AddAttribute("index", var->index());
1278 break;
1279 case Variable::LOOKUP:
1280 AddAttribute("location", "LOOKUP");
Steve Block3ce2e202009-11-05 08:53:23 +00001281 break;
Steve Block3ce2e202009-11-05 08:53:23 +00001282 }
Steve Block3ce2e202009-11-05 08:53:23 +00001283 }
1284}
1285
1286
1287void JsonAstBuilder::VisitLiteral(Literal* expr) {
1288 TagScope tag(this, "Literal");
1289 {
1290 AttributesScope attributes(this);
1291 Handle<Object> handle = expr->handle();
1292 if (handle->IsString()) {
1293 AddAttribute("handle", Handle<String>(String::cast(*handle)));
1294 } else if (handle->IsSmi()) {
1295 AddAttribute("handle", Smi::cast(*handle)->value());
1296 }
1297 }
1298}
1299
1300
1301void JsonAstBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
1302 TagScope tag(this, "RegExpLiteral");
1303}
1304
1305
1306void JsonAstBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
1307 TagScope tag(this, "ObjectLiteral");
1308}
1309
1310
1311void JsonAstBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
1312 TagScope tag(this, "ArrayLiteral");
1313}
1314
1315
Steve Block3ce2e202009-11-05 08:53:23 +00001316void JsonAstBuilder::VisitAssignment(Assignment* expr) {
1317 TagScope tag(this, "Assignment");
1318 {
1319 AttributesScope attributes(this);
1320 AddAttribute("op", Token::Name(expr->op()));
1321 }
1322 Visit(expr->target());
1323 Visit(expr->value());
1324}
1325
1326
1327void JsonAstBuilder::VisitThrow(Throw* expr) {
1328 TagScope tag(this, "Throw");
1329 Visit(expr->exception());
1330}
1331
1332
1333void JsonAstBuilder::VisitProperty(Property* expr) {
1334 TagScope tag(this, "Property");
Steve Block3ce2e202009-11-05 08:53:23 +00001335 Visit(expr->obj());
1336 Visit(expr->key());
1337}
1338
1339
1340void JsonAstBuilder::VisitCall(Call* expr) {
1341 TagScope tag(this, "Call");
1342 Visit(expr->expression());
1343 VisitExpressions(expr->arguments());
1344}
1345
1346
1347void JsonAstBuilder::VisitCallNew(CallNew* expr) {
1348 TagScope tag(this, "CallNew");
1349 Visit(expr->expression());
1350 VisitExpressions(expr->arguments());
1351}
1352
1353
1354void JsonAstBuilder::VisitCallRuntime(CallRuntime* expr) {
1355 TagScope tag(this, "CallRuntime");
1356 {
1357 AttributesScope attributes(this);
1358 AddAttribute("name", expr->name());
1359 }
1360 VisitExpressions(expr->arguments());
1361}
1362
1363
1364void JsonAstBuilder::VisitUnaryOperation(UnaryOperation* expr) {
1365 TagScope tag(this, "UnaryOperation");
1366 {
1367 AttributesScope attributes(this);
1368 AddAttribute("op", Token::Name(expr->op()));
1369 }
1370 Visit(expr->expression());
1371}
1372
1373
1374void JsonAstBuilder::VisitCountOperation(CountOperation* expr) {
1375 TagScope tag(this, "CountOperation");
1376 {
1377 AttributesScope attributes(this);
1378 AddAttribute("is_prefix", expr->is_prefix());
1379 AddAttribute("op", Token::Name(expr->op()));
1380 }
1381 Visit(expr->expression());
1382}
1383
1384
1385void JsonAstBuilder::VisitBinaryOperation(BinaryOperation* expr) {
1386 TagScope tag(this, "BinaryOperation");
1387 {
1388 AttributesScope attributes(this);
1389 AddAttribute("op", Token::Name(expr->op()));
1390 }
1391 Visit(expr->left());
1392 Visit(expr->right());
1393}
1394
1395
1396void JsonAstBuilder::VisitCompareOperation(CompareOperation* expr) {
1397 TagScope tag(this, "CompareOperation");
1398 {
1399 AttributesScope attributes(this);
1400 AddAttribute("op", Token::Name(expr->op()));
1401 }
1402 Visit(expr->left());
1403 Visit(expr->right());
1404}
1405
1406
Kristian Monsen80d68ea2010-09-08 11:05:35 +01001407void JsonAstBuilder::VisitCompareToNull(CompareToNull* expr) {
1408 TagScope tag(this, "CompareToNull");
1409 {
1410 AttributesScope attributes(this);
1411 AddAttribute("is_strict", expr->is_strict());
1412 }
1413 Visit(expr->expression());
1414}
1415
1416
Steve Block3ce2e202009-11-05 08:53:23 +00001417void JsonAstBuilder::VisitThisFunction(ThisFunction* expr) {
1418 TagScope tag(this, "ThisFunction");
1419}
1420
1421
1422void JsonAstBuilder::VisitDeclaration(Declaration* decl) {
1423 TagScope tag(this, "Declaration");
1424 {
1425 AttributesScope attributes(this);
1426 AddAttribute("mode", Variable::Mode2String(decl->mode()));
1427 }
1428 Visit(decl->proxy());
1429 if (decl->fun() != NULL) Visit(decl->fun());
1430}
1431
Steve Blocka7e24c12009-10-30 11:49:00 +00001432
1433#endif // DEBUG
1434
1435} } // namespace v8::internal