Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Side by Side Diff: src/ast/prettyprinter.cc

Issue 2265073002: Handle unicode correctly in CallPrinter (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ast/prettyprinter.h ('k') | src/runtime/runtime-internal.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 197
230 198
231 void CallPrinter::VisitConditional(Conditional* node) { 199 void CallPrinter::VisitConditional(Conditional* node) {
232 Find(node->condition()); 200 Find(node->condition());
233 Find(node->then_expression()); 201 Find(node->then_expression());
234 Find(node->else_expression()); 202 Find(node->else_expression());
235 } 203 }
236 204
237 205
238 void CallPrinter::VisitLiteral(Literal* node) { 206 void CallPrinter::VisitLiteral(Literal* node) {
239 PrintLiteral(*node->value(), true); 207 PrintLiteral(node->value(), true);
240 } 208 }
241 209
242 210
243 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) { 211 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
244 Print("/"); 212 Print("/");
245 PrintLiteral(*node->pattern(), false); 213 PrintLiteral(node->pattern(), false);
246 Print("/"); 214 Print("/");
247 if (node->flags() & RegExp::kGlobal) Print("g"); 215 if (node->flags() & RegExp::kGlobal) Print("g");
248 if (node->flags() & RegExp::kIgnoreCase) Print("i"); 216 if (node->flags() & RegExp::kIgnoreCase) Print("i");
249 if (node->flags() & RegExp::kMultiline) Print("m"); 217 if (node->flags() & RegExp::kMultiline) Print("m");
250 if (node->flags() & RegExp::kUnicode) Print("u"); 218 if (node->flags() & RegExp::kUnicode) Print("u");
251 if (node->flags() & RegExp::kSticky) Print("y"); 219 if (node->flags() & RegExp::kSticky) Print("y");
252 } 220 }
253 221
254 222
255 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) { 223 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
(...skipping 11 matching lines...) Expand all
267 } 235 }
268 Print("]"); 236 Print("]");
269 } 237 }
270 238
271 239
272 void CallPrinter::VisitVariableProxy(VariableProxy* node) { 240 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
273 if (is_builtin_) { 241 if (is_builtin_) {
274 // Variable names of builtins are meaningless due to minification. 242 // Variable names of builtins are meaningless due to minification.
275 Print("(var)"); 243 Print("(var)");
276 } else { 244 } else {
277 PrintLiteral(*node->name(), false); 245 PrintLiteral(node->name(), false);
278 } 246 }
279 } 247 }
280 248
281 249
282 void CallPrinter::VisitAssignment(Assignment* node) { 250 void CallPrinter::VisitAssignment(Assignment* node) {
283 Find(node->target()); 251 Find(node->target());
284 Find(node->value()); 252 Find(node->value());
285 } 253 }
286 254
287 255
288 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); } 256 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
289 257
290 258
291 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); } 259 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
292 260
293 261
294 void CallPrinter::VisitProperty(Property* node) { 262 void CallPrinter::VisitProperty(Property* node) {
295 Expression* key = node->key(); 263 Expression* key = node->key();
296 Literal* literal = key->AsLiteral(); 264 Literal* literal = key->AsLiteral();
297 if (literal != NULL && literal->value()->IsInternalizedString()) { 265 if (literal != NULL && literal->value()->IsInternalizedString()) {
298 Find(node->obj(), true); 266 Find(node->obj(), true);
299 Print("."); 267 Print(".");
300 PrintLiteral(*literal->value(), false); 268 PrintLiteral(literal->value(), false);
301 } else { 269 } else {
302 Find(node->obj(), true); 270 Find(node->obj(), true);
303 Print("["); 271 Print("[");
304 Find(key, true); 272 Find(key, true);
305 Print("]"); 273 Print("]");
306 } 274 }
307 } 275 }
308 276
309 277
310 void CallPrinter::VisitCall(Call* node) { 278 void CallPrinter::VisitCall(Call* node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 28 matching lines...) Expand all
420 } 394 }
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 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
431 void CallPrinter::PrintLiteral(Object* value, bool quote) { 405 if (value->IsString()) {
432 Object* object = value;
433 if (object->IsString()) {
434 if (quote) Print("\""); 406 if (quote) Print("\"");
435 Print("%s", String::cast(object)->ToCString().get()); 407 Print(Handle<String>::cast(value));
436 if (quote) Print("\""); 408 if (quote) Print("\"");
437 } else if (object->IsNull(isolate_)) { 409 } else if (value->IsNull(isolate_)) {
438 Print("null"); 410 Print("null");
439 } else if (object->IsTrue(isolate_)) { 411 } else if (value->IsTrue(isolate_)) {
440 Print("true"); 412 Print("true");
441 } else if (object->IsFalse(isolate_)) { 413 } else if (value->IsFalse(isolate_)) {
442 Print("false"); 414 Print("false");
443 } else if (object->IsUndefined(isolate_)) { 415 } else if (value->IsUndefined(isolate_)) {
444 Print("undefined"); 416 Print("undefined");
445 } else if (object->IsNumber()) { 417 } else if (value->IsNumber()) {
446 Print("%g", object->Number()); 418 Print(isolate_->factory()->NumberToString(value));
447 } else if (object->IsSymbol()) { 419 } else if (value->IsSymbol()) {
448 // Symbols can only occur as literals if they were inserted by the parser. 420 // Symbols can only occur as literals if they were inserted by the parser.
449 PrintLiteral(Symbol::cast(object)->name(), false); 421 PrintLiteral(handle(Handle<Symbol>::cast(value)->name(), isolate_), false);
450 } 422 }
451 } 423 }
452 424
453 425
454 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { 426 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
455 PrintLiteral(*value->string(), quote); 427 PrintLiteral(value->string(), quote);
456 } 428 }
457 429
458 430
459 //----------------------------------------------------------------------------- 431 //-----------------------------------------------------------------------------
460 432
461 433
462 #ifdef DEBUG 434 #ifdef DEBUG
463 435
464 // A helper for ast nodes that use FeedbackVectorSlots. 436 // A helper for ast nodes that use FeedbackVectorSlots.
465 static int FormatSlotNode(Vector<char>* buf, Expression* node, 437 static int FormatSlotNode(Vector<char>* buf, Expression* node,
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 1163
1192 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) { 1164 void AstPrinter::VisitRewritableExpression(RewritableExpression* node) {
1193 Visit(node->expression()); 1165 Visit(node->expression());
1194 } 1166 }
1195 1167
1196 1168
1197 #endif // DEBUG 1169 #endif // DEBUG
1198 1170
1199 } // namespace internal 1171 } // namespace internal
1200 } // namespace v8 1172 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/prettyprinter.h ('k') | src/runtime/runtime-internal.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698