OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/ast/prettyprinter.h" | 5 #include "src/ast/prettyprinter.h" |
6 | 6 |
7 #include <stdarg.h> | 7 #include <stdarg.h> |
8 | 8 |
9 #include "src/ast/ast-value-factory.h" | 9 #include "src/ast/ast-value-factory.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
11 #include "src/base/platform/platform.h" | 11 #include "src/base/platform/platform.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 CallPrinter::CallPrinter(Isolate* isolate, bool is_builtin) { | 16 CallPrinter::CallPrinter(Isolate* isolate, bool is_builtin) |
17 : builder_(isolate) { | |
17 isolate_ = isolate; | 18 isolate_ = isolate; |
18 output_ = NULL; | |
19 size_ = 0; | |
20 pos_ = 0; | |
21 position_ = 0; | 19 position_ = 0; |
20 num_prints_ = 0; | |
22 found_ = false; | 21 found_ = false; |
23 done_ = false; | 22 done_ = false; |
24 is_builtin_ = is_builtin; | 23 is_builtin_ = is_builtin; |
25 InitializeAstVisitor(isolate); | 24 InitializeAstVisitor(isolate); |
26 } | 25 } |
27 | 26 |
28 | 27 Handle<String> CallPrinter::Print(FunctionLiteral* program, int position) { |
29 CallPrinter::~CallPrinter() { DeleteArray(output_); } | 28 num_prints_ = 0; |
30 | |
31 | |
32 const char* CallPrinter::Print(FunctionLiteral* program, int position) { | |
33 Init(); | |
34 position_ = position; | 29 position_ = position; |
35 Find(program); | 30 Find(program); |
36 return output_; | 31 return builder_.Finish().ToHandleChecked(); |
37 } | 32 } |
38 | 33 |
39 | 34 |
40 void CallPrinter::Find(AstNode* node, bool print) { | 35 void CallPrinter::Find(AstNode* node, bool print) { |
41 if (done_) return; | 36 if (done_) return; |
42 if (found_) { | 37 if (found_) { |
43 if (print) { | 38 if (print) { |
44 int start = pos_; | 39 int prev_num_prints = num_prints_; |
45 Visit(node); | 40 Visit(node); |
46 if (start != pos_) return; | 41 if (prev_num_prints != num_prints_) return; |
47 } | 42 } |
48 Print("(intermediate value)"); | 43 Print("(intermediate value)"); |
49 } else { | 44 } else { |
50 Visit(node); | 45 Visit(node); |
51 } | 46 } |
52 } | 47 } |
53 | 48 |
54 | 49 void CallPrinter::Print(const char* str) { |
55 void CallPrinter::Init() { | 50 if (!found_ || done_) return; |
56 if (size_ == 0) { | 51 num_prints_++; |
57 DCHECK(output_ == NULL); | 52 builder_.AppendCString(str); |
58 const int initial_size = 256; | |
59 output_ = NewArray<char>(initial_size); | |
60 size_ = initial_size; | |
61 } | |
62 output_[0] = '\0'; | |
63 pos_ = 0; | |
64 } | 53 } |
65 | 54 |
66 | 55 void CallPrinter::Print(Handle<String> str) { |
67 void CallPrinter::Print(const char* format, ...) { | |
68 if (!found_ || done_) return; | 56 if (!found_ || done_) return; |
69 for (;;) { | 57 num_prints_++; |
70 va_list arguments; | 58 builder_.AppendString(str); |
71 va_start(arguments, format); | |
72 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, format, arguments); | |
73 va_end(arguments); | |
74 | |
75 if (n >= 0) { | |
76 // there was enough space - we are done | |
77 pos_ += n; | |
78 return; | |
79 } else { | |
80 // there was not enough space - allocate more and try again | |
81 const int slack = 32; | |
82 int new_size = size_ + (size_ >> 1) + slack; | |
83 char* new_output = NewArray<char>(new_size); | |
84 MemCopy(new_output, output_, pos_); | |
85 DeleteArray(output_); | |
86 output_ = new_output; | |
87 size_ = new_size; | |
88 } | |
89 } | |
90 } | 59 } |
91 | 60 |
92 | |
93 void CallPrinter::VisitBlock(Block* node) { | 61 void CallPrinter::VisitBlock(Block* node) { |
94 FindStatements(node->statements()); | 62 FindStatements(node->statements()); |
95 } | 63 } |
96 | 64 |
97 | 65 |
98 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {} | 66 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {} |
99 | 67 |
100 | 68 |
101 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {} | 69 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {} |
102 | 70 |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 | 312 |
345 void CallPrinter::VisitCallRuntime(CallRuntime* node) { | 313 void CallPrinter::VisitCallRuntime(CallRuntime* node) { |
346 FindArguments(node->arguments()); | 314 FindArguments(node->arguments()); |
347 } | 315 } |
348 | 316 |
349 | 317 |
350 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) { | 318 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) { |
351 Token::Value op = node->op(); | 319 Token::Value op = node->op(); |
352 bool needsSpace = | 320 bool needsSpace = |
353 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID; | 321 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID; |
354 Print("(%s%s", Token::String(op), needsSpace ? " " : ""); | 322 Print("("); |
323 Print(Token::String(op)); | |
324 if (needsSpace) Print(" "); | |
355 Find(node->expression(), true); | 325 Find(node->expression(), true); |
356 Print(")"); | 326 Print(")"); |
357 } | 327 } |
358 | 328 |
359 | 329 |
360 void CallPrinter::VisitCountOperation(CountOperation* node) { | 330 void CallPrinter::VisitCountOperation(CountOperation* node) { |
361 Print("("); | 331 Print("("); |
362 if (node->is_prefix()) Print("%s", Token::String(node->op())); | 332 if (node->is_prefix()) Print(Token::String(node->op())); |
363 Find(node->expression(), true); | 333 Find(node->expression(), true); |
364 if (node->is_postfix()) Print("%s", Token::String(node->op())); | 334 if (node->is_postfix()) Print(Token::String(node->op())); |
365 Print(")"); | 335 Print(")"); |
366 } | 336 } |
367 | 337 |
368 | 338 |
369 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) { | 339 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) { |
370 Print("("); | 340 Print("("); |
371 Find(node->left(), true); | 341 Find(node->left(), true); |
372 Print(" %s ", Token::String(node->op())); | 342 Print(" "); |
343 Print(Token::String(node->op())); | |
344 Print(" "); | |
373 Find(node->right(), true); | 345 Find(node->right(), true); |
374 Print(")"); | 346 Print(")"); |
375 } | 347 } |
376 | 348 |
377 | 349 |
378 void CallPrinter::VisitCompareOperation(CompareOperation* node) { | 350 void CallPrinter::VisitCompareOperation(CompareOperation* node) { |
379 Print("("); | 351 Print("("); |
380 Find(node->left(), true); | 352 Find(node->left(), true); |
381 Print(" %s ", Token::String(node->op())); | 353 Print(" "); |
354 Print(Token::String(node->op())); | |
355 Print(" "); | |
382 Find(node->right(), true); | 356 Find(node->right(), true); |
383 Print(")"); | 357 Print(")"); |
384 } | 358 } |
385 | 359 |
386 | 360 |
387 void CallPrinter::VisitSpread(Spread* node) { | 361 void CallPrinter::VisitSpread(Spread* node) { |
388 Print("(..."); | 362 Print("(..."); |
389 Find(node->expression(), true); | 363 Find(node->expression(), true); |
390 Print(")"); | 364 Print(")"); |
391 } | 365 } |
(...skipping 29 matching lines...) Expand all Loading... | |
421 | 395 |
422 | 396 |
423 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) { | 397 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) { |
424 if (found_) return; | 398 if (found_) return; |
425 for (int i = 0; i < arguments->length(); i++) { | 399 for (int i = 0; i < arguments->length(); i++) { |
426 Find(arguments->at(i)); | 400 Find(arguments->at(i)); |
427 } | 401 } |
428 } | 402 } |
429 | 403 |
430 | 404 |
431 void CallPrinter::PrintLiteral(Object* value, bool quote) { | 405 void CallPrinter::PrintLiteral(Object* value, bool quote) { |
Toon Verwaest
2016/08/22 14:23:12
Pass in Handle<Object> value rather than Object*
jgruber
2016/08/22 14:43:25
Done.
| |
432 Object* object = value; | 406 Object* object = value; |
433 if (object->IsString()) { | 407 if (object->IsString()) { |
434 if (quote) Print("\""); | 408 if (quote) Print("\""); |
435 Print("%s", String::cast(object)->ToCString().get()); | 409 Print(handle(String::cast(object), isolate_)); |
436 if (quote) Print("\""); | 410 if (quote) Print("\""); |
437 } else if (object->IsNull(isolate_)) { | 411 } else if (object->IsNull(isolate_)) { |
438 Print("null"); | 412 Print("null"); |
439 } else if (object->IsTrue(isolate_)) { | 413 } else if (object->IsTrue(isolate_)) { |
440 Print("true"); | 414 Print("true"); |
441 } else if (object->IsFalse(isolate_)) { | 415 } else if (object->IsFalse(isolate_)) { |
442 Print("false"); | 416 Print("false"); |
443 } else if (object->IsUndefined(isolate_)) { | 417 } else if (object->IsUndefined(isolate_)) { |
444 Print("undefined"); | 418 Print("undefined"); |
445 } else if (object->IsNumber()) { | 419 } else if (object->IsNumber()) { |
446 Print("%g", object->Number()); | 420 Print(isolate_->factory()->NumberToString(handle(object, isolate_))); |
447 } else if (object->IsSymbol()) { | 421 } else if (object->IsSymbol()) { |
448 // Symbols can only occur as literals if they were inserted by the parser. | 422 // Symbols can only occur as literals if they were inserted by the parser. |
449 PrintLiteral(Symbol::cast(object)->name(), false); | 423 PrintLiteral(Symbol::cast(object)->name(), false); |
450 } | 424 } |
451 } | 425 } |
452 | 426 |
453 | 427 |
454 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { | 428 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { |
455 PrintLiteral(*value->string(), quote); | 429 PrintLiteral(*value->string(), quote); |
456 } | 430 } |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1191 | 1165 |
1192 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { | 1166 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { |
1193 Visit(node->expression()); | 1167 Visit(node->expression()); |
1194 } | 1168 } |
1195 | 1169 |
1196 | 1170 |
1197 #endif // DEBUG | 1171 #endif // DEBUG |
1198 | 1172 |
1199 } // namespace internal | 1173 } // namespace internal |
1200 } // namespace v8 | 1174 } // namespace v8 |
OLD | NEW |