| 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) { | 16 CallPrinter::CallPrinter(Isolate* isolate, bool is_builtin) { |
| 17 output_ = NULL; | 17 output_ = NULL; |
| 18 size_ = 0; | 18 size_ = 0; |
| 19 pos_ = 0; | 19 pos_ = 0; |
| 20 position_ = 0; | 20 position_ = 0; |
| 21 found_ = false; | 21 found_ = false; |
| 22 done_ = false; | 22 done_ = false; |
| 23 is_builtin_ = is_builtin; |
| 23 InitializeAstVisitor(isolate); | 24 InitializeAstVisitor(isolate); |
| 24 } | 25 } |
| 25 | 26 |
| 26 | 27 |
| 27 CallPrinter::~CallPrinter() { DeleteArray(output_); } | 28 CallPrinter::~CallPrinter() { DeleteArray(output_); } |
| 28 | 29 |
| 29 | 30 |
| 30 const char* CallPrinter::Print(FunctionLiteral* program, int position) { | 31 const char* CallPrinter::Print(FunctionLiteral* program, int position) { |
| 31 Init(); | 32 Init(); |
| 32 position_ = position; | 33 position_ = position; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 | 186 |
| 186 void CallPrinter::VisitForInStatement(ForInStatement* node) { | 187 void CallPrinter::VisitForInStatement(ForInStatement* node) { |
| 187 Find(node->each()); | 188 Find(node->each()); |
| 188 Find(node->enumerable()); | 189 Find(node->enumerable()); |
| 189 Find(node->body()); | 190 Find(node->body()); |
| 190 } | 191 } |
| 191 | 192 |
| 192 | 193 |
| 193 void CallPrinter::VisitForOfStatement(ForOfStatement* node) { | 194 void CallPrinter::VisitForOfStatement(ForOfStatement* node) { |
| 194 Find(node->each()); | 195 Find(node->each()); |
| 195 Find(node->iterable()); | 196 Find(node->assign_iterator()); |
| 196 Find(node->body()); | 197 Find(node->body()); |
| 198 Find(node->next_result()); |
| 197 } | 199 } |
| 198 | 200 |
| 199 | 201 |
| 200 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) { | 202 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) { |
| 201 Find(node->try_block()); | 203 Find(node->try_block()); |
| 202 Find(node->catch_block()); | 204 Find(node->catch_block()); |
| 203 } | 205 } |
| 204 | 206 |
| 205 | 207 |
| 206 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) { | 208 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 232 | 234 |
| 233 | 235 |
| 234 void CallPrinter::VisitConditional(Conditional* node) { | 236 void CallPrinter::VisitConditional(Conditional* node) { |
| 235 Find(node->condition()); | 237 Find(node->condition()); |
| 236 Find(node->then_expression()); | 238 Find(node->then_expression()); |
| 237 Find(node->else_expression()); | 239 Find(node->else_expression()); |
| 238 } | 240 } |
| 239 | 241 |
| 240 | 242 |
| 241 void CallPrinter::VisitLiteral(Literal* node) { | 243 void CallPrinter::VisitLiteral(Literal* node) { |
| 242 PrintLiteral(node->value(), true); | 244 PrintLiteral(*node->value(), true); |
| 243 } | 245 } |
| 244 | 246 |
| 245 | 247 |
| 246 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) { | 248 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) { |
| 247 Print("/"); | 249 Print("/"); |
| 248 PrintLiteral(node->pattern(), false); | 250 PrintLiteral(*node->pattern(), false); |
| 249 Print("/"); | 251 Print("/"); |
| 250 if (node->flags() & RegExp::kGlobal) Print("g"); | 252 if (node->flags() & RegExp::kGlobal) Print("g"); |
| 251 if (node->flags() & RegExp::kIgnoreCase) Print("i"); | 253 if (node->flags() & RegExp::kIgnoreCase) Print("i"); |
| 252 if (node->flags() & RegExp::kMultiline) Print("m"); | 254 if (node->flags() & RegExp::kMultiline) Print("m"); |
| 253 if (node->flags() & RegExp::kUnicode) Print("u"); | 255 if (node->flags() & RegExp::kUnicode) Print("u"); |
| 254 if (node->flags() & RegExp::kSticky) Print("y"); | 256 if (node->flags() & RegExp::kSticky) Print("y"); |
| 255 } | 257 } |
| 256 | 258 |
| 257 | 259 |
| 258 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) { | 260 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) { |
| 259 for (int i = 0; i < node->properties()->length(); i++) { | 261 for (int i = 0; i < node->properties()->length(); i++) { |
| 260 Find(node->properties()->at(i)->value()); | 262 Find(node->properties()->at(i)->value()); |
| 261 } | 263 } |
| 262 } | 264 } |
| 263 | 265 |
| 264 | 266 |
| 265 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) { | 267 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) { |
| 266 Print("["); | 268 Print("["); |
| 267 for (int i = 0; i < node->values()->length(); i++) { | 269 for (int i = 0; i < node->values()->length(); i++) { |
| 268 if (i != 0) Print(","); | 270 if (i != 0) Print(","); |
| 269 Find(node->values()->at(i), true); | 271 Find(node->values()->at(i), true); |
| 270 } | 272 } |
| 271 Print("]"); | 273 Print("]"); |
| 272 } | 274 } |
| 273 | 275 |
| 274 | 276 |
| 275 void CallPrinter::VisitVariableProxy(VariableProxy* node) { | 277 void CallPrinter::VisitVariableProxy(VariableProxy* node) { |
| 276 PrintLiteral(node->name(), false); | 278 if (is_builtin_) { |
| 279 // Variable names of builtins are meaningless due to minification. |
| 280 Print("(var)"); |
| 281 } else { |
| 282 PrintLiteral(*node->name(), false); |
| 283 } |
| 277 } | 284 } |
| 278 | 285 |
| 279 | 286 |
| 280 void CallPrinter::VisitAssignment(Assignment* node) { | 287 void CallPrinter::VisitAssignment(Assignment* node) { |
| 281 Find(node->target()); | 288 Find(node->target()); |
| 282 Find(node->value()); | 289 Find(node->value()); |
| 283 } | 290 } |
| 284 | 291 |
| 285 | 292 |
| 286 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); } | 293 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); } |
| 287 | 294 |
| 288 | 295 |
| 289 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); } | 296 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); } |
| 290 | 297 |
| 291 | 298 |
| 292 void CallPrinter::VisitProperty(Property* node) { | 299 void CallPrinter::VisitProperty(Property* node) { |
| 293 Expression* key = node->key(); | 300 Expression* key = node->key(); |
| 294 Literal* literal = key->AsLiteral(); | 301 Literal* literal = key->AsLiteral(); |
| 295 if (literal != NULL && literal->value()->IsInternalizedString()) { | 302 if (literal != NULL && literal->value()->IsInternalizedString()) { |
| 296 Find(node->obj(), true); | 303 Find(node->obj(), true); |
| 297 Print("."); | 304 Print("."); |
| 298 PrintLiteral(literal->value(), false); | 305 PrintLiteral(*literal->value(), false); |
| 299 } else { | 306 } else { |
| 300 Find(node->obj(), true); | 307 Find(node->obj(), true); |
| 301 Print("["); | 308 Print("["); |
| 302 Find(key, true); | 309 Find(key, true); |
| 303 Print("]"); | 310 Print("]"); |
| 304 } | 311 } |
| 305 } | 312 } |
| 306 | 313 |
| 307 | 314 |
| 308 void CallPrinter::VisitCall(Call* node) { | 315 void CallPrinter::VisitCall(Call* node) { |
| 309 bool was_found = !found_ && node->position() == position_; | 316 bool was_found = !found_ && node->position() == position_; |
| 310 if (was_found) found_ = true; | 317 if (was_found) { |
| 318 // Bail out if the error is caused by a direct call to a variable in builtin |
| 319 // code. The variable name is meaningless due to minification. |
| 320 if (is_builtin_ && node->expression()->IsVariableProxy()) { |
| 321 done_ = true; |
| 322 return; |
| 323 } |
| 324 found_ = true; |
| 325 } |
| 311 Find(node->expression(), true); | 326 Find(node->expression(), true); |
| 312 if (!was_found) Print("(...)"); | 327 if (!was_found) Print("(...)"); |
| 313 FindArguments(node->arguments()); | 328 FindArguments(node->arguments()); |
| 314 if (was_found) done_ = true; | 329 if (was_found) done_ = true; |
| 315 } | 330 } |
| 316 | 331 |
| 317 | 332 |
| 318 void CallPrinter::VisitCallNew(CallNew* node) { | 333 void CallPrinter::VisitCallNew(CallNew* node) { |
| 319 bool was_found = !found_ && node->position() == position_; | 334 bool was_found = !found_ && node->position() == position_; |
| 320 if (was_found) found_ = true; | 335 if (was_found) { |
| 336 // Bail out if the error is caused by a direct call to a variable in builtin |
| 337 // code. The variable name is meaningless due to minification. |
| 338 if (is_builtin_ && node->expression()->IsVariableProxy()) { |
| 339 done_ = true; |
| 340 return; |
| 341 } |
| 342 found_ = true; |
| 343 } |
| 321 Find(node->expression(), was_found); | 344 Find(node->expression(), was_found); |
| 322 FindArguments(node->arguments()); | 345 FindArguments(node->arguments()); |
| 323 if (was_found) done_ = true; | 346 if (was_found) done_ = true; |
| 324 } | 347 } |
| 325 | 348 |
| 326 | 349 |
| 327 void CallPrinter::VisitCallRuntime(CallRuntime* node) { | 350 void CallPrinter::VisitCallRuntime(CallRuntime* node) { |
| 328 if (!node->is_jsruntime() && | 351 if (!node->is_jsruntime() && |
| 329 node->function() == | 352 node->function() == |
| 330 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper)) { | 353 Runtime::FunctionForId(Runtime::kInlineDefaultConstructorCallSuper)) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 | 429 |
| 407 | 430 |
| 408 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) { | 431 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) { |
| 409 if (found_) return; | 432 if (found_) return; |
| 410 for (int i = 0; i < arguments->length(); i++) { | 433 for (int i = 0; i < arguments->length(); i++) { |
| 411 Find(arguments->at(i)); | 434 Find(arguments->at(i)); |
| 412 } | 435 } |
| 413 } | 436 } |
| 414 | 437 |
| 415 | 438 |
| 416 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) { | 439 void CallPrinter::PrintLiteral(Object* value, bool quote) { |
| 417 Object* object = *value; | 440 Object* object = value; |
| 418 if (object->IsString()) { | 441 if (object->IsString()) { |
| 419 String* string = String::cast(object); | |
| 420 if (quote) Print("\""); | 442 if (quote) Print("\""); |
| 421 for (int i = 0; i < string->length(); i++) { | 443 Print("%s", String::cast(object)->ToCString().get()); |
| 422 Print("%c", string->Get(i)); | |
| 423 } | |
| 424 if (quote) Print("\""); | 444 if (quote) Print("\""); |
| 425 } else if (object->IsNull()) { | 445 } else if (object->IsNull()) { |
| 426 Print("null"); | 446 Print("null"); |
| 427 } else if (object->IsTrue()) { | 447 } else if (object->IsTrue()) { |
| 428 Print("true"); | 448 Print("true"); |
| 429 } else if (object->IsFalse()) { | 449 } else if (object->IsFalse()) { |
| 430 Print("false"); | 450 Print("false"); |
| 431 } else if (object->IsUndefined()) { | 451 } else if (object->IsUndefined()) { |
| 432 Print("undefined"); | 452 Print("undefined"); |
| 433 } else if (object->IsNumber()) { | 453 } else if (object->IsNumber()) { |
| 434 Print("%g", object->Number()); | 454 Print("%g", object->Number()); |
| 455 } else if (object->IsSymbol()) { |
| 456 // Symbols can only occur as literals if they were inserted by the parser. |
| 457 PrintLiteral(Symbol::cast(object)->name(), false); |
| 435 } | 458 } |
| 436 } | 459 } |
| 437 | 460 |
| 438 | 461 |
| 439 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { | 462 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) { |
| 440 PrintLiteral(value->string(), quote); | 463 PrintLiteral(*value->string(), quote); |
| 441 } | 464 } |
| 442 | 465 |
| 443 | 466 |
| 444 //----------------------------------------------------------------------------- | 467 //----------------------------------------------------------------------------- |
| 445 | 468 |
| 446 | 469 |
| 447 #ifdef DEBUG | 470 #ifdef DEBUG |
| 448 | 471 |
| 449 // A helper for ast nodes that use FeedbackVectorSlots. | 472 // A helper for ast nodes that use FeedbackVectorSlots. |
| 450 static int FormatSlotNode(Vector<char>* buf, Expression* node, | 473 static int FormatSlotNode(Vector<char>* buf, Expression* node, |
| (...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1656 | 1679 |
| 1657 void AstPrinter::VisitSuperCallReference(SuperCallReference* node) { | 1680 void AstPrinter::VisitSuperCallReference(SuperCallReference* node) { |
| 1658 IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position()); | 1681 IndentedScope indent(this, "SUPER-CALL-REFERENCE", node->position()); |
| 1659 } | 1682 } |
| 1660 | 1683 |
| 1661 | 1684 |
| 1662 #endif // DEBUG | 1685 #endif // DEBUG |
| 1663 | 1686 |
| 1664 } // namespace internal | 1687 } // namespace internal |
| 1665 } // namespace v8 | 1688 } // namespace v8 |
| OLD | NEW |