| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "ast.h" | 31 #include "ast.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "codegen.h" | 33 #include "codegen.h" |
| 34 #include "compiler.h" | 34 #include "compiler.h" |
| 35 #include "func-name-inferrer.h" | 35 #include "func-name-inferrer.h" |
| 36 #include "messages.h" | 36 #include "messages.h" |
| 37 #include "parser.h" | 37 #include "parser.h" |
| 38 #include "platform.h" | 38 #include "platform.h" |
| 39 #include "preparser.h" |
| 39 #include "runtime.h" | 40 #include "runtime.h" |
| 40 #include "scopeinfo.h" | 41 #include "scopeinfo.h" |
| 41 #include "scopes.h" | |
| 42 #include "string-stream.h" | 42 #include "string-stream.h" |
| 43 | 43 |
| 44 #include "ast-inl.h" | 44 #include "ast-inl.h" |
| 45 #include "jump-target-inl.h" | 45 #include "jump-target-inl.h" |
| 46 | 46 |
| 47 namespace v8 { | 47 namespace v8 { |
| 48 namespace internal { | 48 namespace internal { |
| 49 | 49 |
| 50 // PositionStack is used for on-stack allocation of token positions for | 50 // PositionStack is used for on-stack allocation of token positions for |
| 51 // new expressions. Please look at ParseNewExpression. | 51 // new expressions. Please look at ParseNewExpression. |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 parent_(*variable) { | 316 parent_(*variable) { |
| 317 *variable = this; | 317 *variable = this; |
| 318 } | 318 } |
| 319 | 319 |
| 320 | 320 |
| 321 TemporaryScope::~TemporaryScope() { | 321 TemporaryScope::~TemporaryScope() { |
| 322 *variable_ = parent_; | 322 *variable_ = parent_; |
| 323 } | 323 } |
| 324 | 324 |
| 325 | 325 |
| 326 // A zone list wrapper lets code either access a access a zone list | 326 Handle<String> Parser::LookupSymbol(int symbol_id, |
| 327 // or appear to do so while actually ignoring all operations. | 327 Vector<const char> string) { |
| 328 template <typename T> | 328 // Length of symbol cache is the number of identified symbols. |
| 329 class ZoneListWrapper { | 329 // If we are larger than that, or negative, it's not a cached symbol. |
| 330 public: | 330 // This might also happen if there is no preparser symbol data, even |
| 331 ZoneListWrapper() : list_(NULL) { } | 331 // if there is some preparser data. |
| 332 explicit ZoneListWrapper(int size) : list_(new ZoneList<T*>(size)) { } | 332 if (static_cast<unsigned>(symbol_id) |
| 333 void Add(T* that) { if (list_) list_->Add(that); } | 333 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 334 int length() { return list_->length(); } | 334 return Factory::LookupSymbol(string); |
| 335 ZoneList<T*>* elements() { return list_; } | 335 } |
| 336 T* at(int index) { return list_->at(index); } | 336 return LookupCachedSymbol(symbol_id, string); |
| 337 private: | 337 } |
| 338 ZoneList<T*>* list_; | |
| 339 }; | |
| 340 | 338 |
| 341 | 339 |
| 342 // Allocation macro that should be used to allocate objects that must | 340 Handle<String> Parser::LookupCachedSymbol(int symbol_id, |
| 343 // only be allocated in real parsing mode. Note that in preparse mode | 341 Vector<const char> string) { |
| 344 // not only is the syntax tree not created but the constructor | 342 // Make sure the cache is large enough to hold the symbol identifier. |
| 345 // arguments are not evaluated. | 343 if (symbol_cache_.length() <= symbol_id) { |
| 346 #define NEW(expr) (is_pre_parsing_ ? NULL : new expr) | 344 // Increase length to index + 1. |
| 345 symbol_cache_.AddBlock(Handle<String>::null(), |
| 346 symbol_id + 1 - symbol_cache_.length()); |
| 347 } |
| 348 Handle<String> result = symbol_cache_.at(symbol_id); |
| 349 if (result.is_null()) { |
| 350 result = Factory::LookupSymbol(string); |
| 351 symbol_cache_.at(symbol_id) = result; |
| 352 return result; |
| 353 } |
| 354 Counters::total_preparse_symbols_skipped.Increment(); |
| 355 return result; |
| 356 } |
| 347 | 357 |
| 348 | 358 |
| 349 class ParserFactory BASE_EMBEDDED { | 359 Vector<unsigned> PartialParserRecorder::ExtractData() { |
| 350 public: | 360 int function_size = function_store_.size(); |
| 351 explicit ParserFactory(bool is_pre_parsing) : | 361 int total_size = ScriptDataImpl::kHeaderSize + function_size; |
| 352 is_pre_parsing_(is_pre_parsing) { } | 362 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 353 | 363 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 354 virtual ~ParserFactory() { } | 364 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 355 | 365 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 356 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | 366 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 357 | 367 if (function_size > 0) { |
| 358 virtual Handle<String> LookupSymbol(int index, Vector<const char> string) { | 368 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 359 return Handle<String>(); | 369 symbol_start)); |
| 360 } | 370 } |
| 361 | 371 return data; |
| 362 virtual Handle<String> EmptySymbol() { | 372 } |
| 363 return Handle<String>(); | |
| 364 } | |
| 365 | |
| 366 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | |
| 367 if (obj == VariableProxySentinel::this_proxy()) { | |
| 368 return Property::this_property(); | |
| 369 } else { | |
| 370 return ValidLeftHandSideSentinel::instance(); | |
| 371 } | |
| 372 } | |
| 373 | |
| 374 virtual Expression* NewCall(Expression* expression, | |
| 375 ZoneList<Expression*>* arguments, | |
| 376 int pos) { | |
| 377 return Call::sentinel(); | |
| 378 } | |
| 379 | |
| 380 virtual Statement* EmptyStatement() { | |
| 381 return NULL; | |
| 382 } | |
| 383 | |
| 384 template <typename T> ZoneListWrapper<T> NewList(int size) { | |
| 385 return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size); | |
| 386 } | |
| 387 | |
| 388 private: | |
| 389 bool is_pre_parsing_; | |
| 390 }; | |
| 391 | 373 |
| 392 | 374 |
| 393 class ParserLog BASE_EMBEDDED { | 375 void CompleteParserRecorder::LogSymbol(int start, Vector<const char> literal) { |
| 394 public: | 376 if (!is_recording_) return; |
| 395 virtual ~ParserLog() { } | |
| 396 | 377 |
| 397 // Records the occurrence of a function. | 378 int hash = vector_hash(literal); |
| 398 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } | 379 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
| 399 virtual void LogSymbol(int start, Vector<const char> symbol) {} | 380 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 400 virtual void LogError() { } | 381 if (id == 0) { |
| 401 // Return the current position in the function entry log. | 382 // Put (symbol_id_ + 1) into entry and increment it. |
| 402 virtual int function_position() { return 0; } | 383 id = ++symbol_id_; |
| 403 virtual int symbol_position() { return 0; } | 384 entry->value = reinterpret_cast<void*>(id); |
| 404 virtual int symbol_ids() { return 0; } | 385 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
| 405 virtual void PauseRecording() {} | 386 entry->key = &symbol[0]; |
| 406 virtual void ResumeRecording() {} | 387 } |
| 407 virtual Vector<unsigned> ExtractData() { | 388 WriteNumber(id - 1); |
| 408 return Vector<unsigned>(); | 389 } |
| 409 }; | |
| 410 }; | |
| 411 | 390 |
| 412 | 391 |
| 413 | 392 Vector<unsigned> CompleteParserRecorder::ExtractData() { |
| 414 class ConditionalLogPauseScope { | 393 int function_size = function_store_.size(); |
| 415 public: | 394 // Add terminator to symbols, then pad to unsigned size. |
| 416 ConditionalLogPauseScope(bool pause, ParserLog* log) | 395 int symbol_size = symbol_store_.size(); |
| 417 : log_(log), pause_(pause) { | 396 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); |
| 418 if (pause) log->PauseRecording(); | 397 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator); |
| 398 symbol_size += padding; |
| 399 int total_size = ScriptDataImpl::kHeaderSize + function_size |
| 400 + (symbol_size / sizeof(unsigned)); |
| 401 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 402 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 403 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; |
| 404 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 405 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 406 if (function_size > 0) { |
| 407 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 408 symbol_start)); |
| 419 } | 409 } |
| 420 ~ConditionalLogPauseScope() { | 410 if (!has_error()) { |
| 421 if (pause_) log_->ResumeRecording(); | 411 symbol_store_.WriteTo( |
| 412 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); |
| 422 } | 413 } |
| 423 private: | 414 return data; |
| 424 ParserLog* log_; | 415 } |
| 425 bool pause_; | |
| 426 }; | |
| 427 | |
| 428 | |
| 429 class AstBuildingParserFactory : public ParserFactory { | |
| 430 public: | |
| 431 explicit AstBuildingParserFactory(int expected_symbols) | |
| 432 : ParserFactory(false), symbol_cache_(expected_symbols) { } | |
| 433 | |
| 434 virtual Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with); | |
| 435 | |
| 436 virtual Handle<String> LookupSymbol(int symbol_id, | |
| 437 Vector<const char> string) { | |
| 438 // Length of symbol cache is the number of identified symbols. | |
| 439 // If we are larger than that, or negative, it's not a cached symbol. | |
| 440 // This might also happen if there is no preparser symbol data, even | |
| 441 // if there is some preparser data. | |
| 442 if (static_cast<unsigned>(symbol_id) | |
| 443 >= static_cast<unsigned>(symbol_cache_.length())) { | |
| 444 return Factory::LookupSymbol(string); | |
| 445 } | |
| 446 return LookupCachedSymbol(symbol_id, string); | |
| 447 } | |
| 448 | |
| 449 Handle<String> LookupCachedSymbol(int symbol_id, | |
| 450 Vector<const char> string) { | |
| 451 // Make sure the cache is large enough to hold the symbol identifier. | |
| 452 if (symbol_cache_.length() <= symbol_id) { | |
| 453 // Increase length to index + 1. | |
| 454 symbol_cache_.AddBlock(Handle<String>::null(), | |
| 455 symbol_id + 1 - symbol_cache_.length()); | |
| 456 } | |
| 457 Handle<String> result = symbol_cache_.at(symbol_id); | |
| 458 if (result.is_null()) { | |
| 459 result = Factory::LookupSymbol(string); | |
| 460 symbol_cache_.at(symbol_id) = result; | |
| 461 return result; | |
| 462 } | |
| 463 Counters::total_preparse_symbols_skipped.Increment(); | |
| 464 return result; | |
| 465 } | |
| 466 | |
| 467 virtual Handle<String> EmptySymbol() { | |
| 468 return Factory::empty_symbol(); | |
| 469 } | |
| 470 | |
| 471 virtual Expression* NewProperty(Expression* obj, Expression* key, int pos) { | |
| 472 return new Property(obj, key, pos); | |
| 473 } | |
| 474 | |
| 475 virtual Expression* NewCall(Expression* expression, | |
| 476 ZoneList<Expression*>* arguments, | |
| 477 int pos) { | |
| 478 return new Call(expression, arguments, pos); | |
| 479 } | |
| 480 | |
| 481 virtual Statement* EmptyStatement(); | |
| 482 private: | |
| 483 List<Handle<String> > symbol_cache_; | |
| 484 }; | |
| 485 | |
| 486 | |
| 487 // Record only functions. | |
| 488 class PartialParserRecorder: public ParserLog { | |
| 489 public: | |
| 490 PartialParserRecorder(); | |
| 491 virtual FunctionEntry LogFunction(int start); | |
| 492 | |
| 493 virtual int function_position() { return function_store_.size(); } | |
| 494 | |
| 495 virtual void LogError() { } | |
| 496 | |
| 497 virtual void LogMessage(Scanner::Location loc, | |
| 498 const char* message, | |
| 499 Vector<const char*> args); | |
| 500 | |
| 501 virtual Vector<unsigned> ExtractData() { | |
| 502 int function_size = function_store_.size(); | |
| 503 int total_size = ScriptDataImpl::kHeaderSize + function_size; | |
| 504 Vector<unsigned> data = Vector<unsigned>::New(total_size); | |
| 505 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | |
| 506 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; | |
| 507 memcpy(data.start(), preamble_, sizeof(preamble_)); | |
| 508 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | |
| 509 if (function_size > 0) { | |
| 510 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | |
| 511 symbol_start)); | |
| 512 } | |
| 513 return data; | |
| 514 } | |
| 515 | |
| 516 virtual void PauseRecording() { | |
| 517 pause_count_++; | |
| 518 is_recording_ = false; | |
| 519 } | |
| 520 | |
| 521 virtual void ResumeRecording() { | |
| 522 ASSERT(pause_count_ > 0); | |
| 523 if (--pause_count_ == 0) is_recording_ = !has_error(); | |
| 524 } | |
| 525 | |
| 526 protected: | |
| 527 bool has_error() { | |
| 528 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); | |
| 529 } | |
| 530 bool is_recording() { | |
| 531 return is_recording_; | |
| 532 } | |
| 533 | |
| 534 void WriteString(Vector<const char> str); | |
| 535 | |
| 536 Collector<unsigned> function_store_; | |
| 537 unsigned preamble_[ScriptDataImpl::kHeaderSize]; | |
| 538 bool is_recording_; | |
| 539 int pause_count_; | |
| 540 | |
| 541 #ifdef DEBUG | |
| 542 int prev_start; | |
| 543 #endif | |
| 544 }; | |
| 545 | |
| 546 | |
| 547 // Record both functions and symbols. | |
| 548 class CompleteParserRecorder: public PartialParserRecorder { | |
| 549 public: | |
| 550 CompleteParserRecorder(); | |
| 551 | |
| 552 virtual void LogSymbol(int start, Vector<const char> literal) { | |
| 553 if (!is_recording_) return; | |
| 554 int hash = vector_hash(literal); | |
| 555 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); | |
| 556 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | |
| 557 if (id == 0) { | |
| 558 // Put (symbol_id_ + 1) into entry and increment it. | |
| 559 id = ++symbol_id_; | |
| 560 entry->value = reinterpret_cast<void*>(id); | |
| 561 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); | |
| 562 entry->key = &symbol[0]; | |
| 563 } | |
| 564 WriteNumber(id - 1); | |
| 565 } | |
| 566 | |
| 567 virtual Vector<unsigned> ExtractData() { | |
| 568 int function_size = function_store_.size(); | |
| 569 // Add terminator to symbols, then pad to unsigned size. | |
| 570 int symbol_size = symbol_store_.size(); | |
| 571 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); | |
| 572 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator); | |
| 573 symbol_size += padding; | |
| 574 int total_size = ScriptDataImpl::kHeaderSize + function_size | |
| 575 + (symbol_size / sizeof(unsigned)); | |
| 576 Vector<unsigned> data = Vector<unsigned>::New(total_size); | |
| 577 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | |
| 578 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; | |
| 579 memcpy(data.start(), preamble_, sizeof(preamble_)); | |
| 580 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | |
| 581 if (function_size > 0) { | |
| 582 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | |
| 583 symbol_start)); | |
| 584 } | |
| 585 if (!has_error()) { | |
| 586 symbol_store_.WriteTo( | |
| 587 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); | |
| 588 } | |
| 589 return data; | |
| 590 } | |
| 591 | |
| 592 virtual int symbol_position() { return symbol_store_.size(); } | |
| 593 virtual int symbol_ids() { return symbol_id_; } | |
| 594 private: | |
| 595 static int vector_hash(Vector<const char> string) { | |
| 596 int hash = 0; | |
| 597 for (int i = 0; i < string.length(); i++) { | |
| 598 int c = string[i]; | |
| 599 hash += c; | |
| 600 hash += (hash << 10); | |
| 601 hash ^= (hash >> 6); | |
| 602 } | |
| 603 return hash; | |
| 604 } | |
| 605 | |
| 606 static bool vector_compare(void* a, void* b) { | |
| 607 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); | |
| 608 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); | |
| 609 int length = string1->length(); | |
| 610 if (string2->length() != length) return false; | |
| 611 return memcmp(string1->start(), string2->start(), length) == 0; | |
| 612 } | |
| 613 | |
| 614 // Write a non-negative number to the symbol store. | |
| 615 void WriteNumber(int number); | |
| 616 | |
| 617 Collector<byte> symbol_store_; | |
| 618 Collector<Vector<const char> > symbol_entries_; | |
| 619 HashMap symbol_table_; | |
| 620 int symbol_id_; | |
| 621 }; | |
| 622 | 416 |
| 623 | 417 |
| 624 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 418 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 625 // The current pre-data entry must be a FunctionEntry with the given | 419 // The current pre-data entry must be a FunctionEntry with the given |
| 626 // start position. | 420 // start position. |
| 627 if ((function_index_ + FunctionEntry::kSize <= store_.length()) | 421 if ((function_index_ + FunctionEntry::kSize <= store_.length()) |
| 628 && (static_cast<int>(store_[function_index_]) == start)) { | 422 && (static_cast<int>(store_[function_index_]) == start)) { |
| 629 int index = function_index_; | 423 int index = function_index_; |
| 630 function_index_ += FunctionEntry::kSize; | 424 function_index_ += FunctionEntry::kSize; |
| 631 return FunctionEntry(store_.SubVector(index, | 425 return FunctionEntry(store_.SubVector(index, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 is_recording_(true), | 478 is_recording_(true), |
| 685 pause_count_(0) { | 479 pause_count_(0) { |
| 686 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 480 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
| 687 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | 481 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; |
| 688 preamble_[ScriptDataImpl::kHasErrorOffset] = false; | 482 preamble_[ScriptDataImpl::kHasErrorOffset] = false; |
| 689 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; | 483 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; |
| 690 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; | 484 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 691 preamble_[ScriptDataImpl::kSizeOffset] = 0; | 485 preamble_[ScriptDataImpl::kSizeOffset] = 0; |
| 692 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); | 486 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); |
| 693 #ifdef DEBUG | 487 #ifdef DEBUG |
| 694 prev_start = -1; | 488 prev_start_ = -1; |
| 695 #endif | 489 #endif |
| 696 } | 490 } |
| 697 | 491 |
| 698 | 492 |
| 699 CompleteParserRecorder::CompleteParserRecorder() | 493 CompleteParserRecorder::CompleteParserRecorder() |
| 700 : PartialParserRecorder(), | 494 : PartialParserRecorder(), |
| 701 symbol_store_(0), | 495 symbol_store_(0), |
| 702 symbol_entries_(0), | 496 symbol_entries_(0), |
| 703 symbol_table_(vector_compare), | 497 symbol_table_(vector_compare), |
| 704 symbol_id_(0) { | 498 symbol_id_(0) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 735 for (int i = 0; i < length; i++) { | 529 for (int i = 0; i < length; i++) { |
| 736 result[i] = start[i + 1]; | 530 result[i] = start[i + 1]; |
| 737 } | 531 } |
| 738 result[length] = '\0'; | 532 result[length] = '\0'; |
| 739 if (chars != NULL) *chars = length; | 533 if (chars != NULL) *chars = length; |
| 740 return result; | 534 return result; |
| 741 } | 535 } |
| 742 | 536 |
| 743 | 537 |
| 744 void PartialParserRecorder::LogMessage(Scanner::Location loc, | 538 void PartialParserRecorder::LogMessage(Scanner::Location loc, |
| 745 const char* message, | 539 const char* message, |
| 746 Vector<const char*> args) { | 540 Vector<const char*> args) { |
| 747 if (has_error()) return; | 541 if (has_error()) return; |
| 748 preamble_[ScriptDataImpl::kHasErrorOffset] = true; | 542 preamble_[ScriptDataImpl::kHasErrorOffset] = true; |
| 749 function_store_.Reset(); | 543 function_store_.Reset(); |
| 750 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); | 544 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); |
| 751 function_store_.Add(loc.beg_pos); | 545 function_store_.Add(loc.beg_pos); |
| 752 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); | 546 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); |
| 753 function_store_.Add(loc.end_pos); | 547 function_store_.Add(loc.end_pos); |
| 754 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); | 548 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); |
| 755 function_store_.Add(args.length()); | 549 function_store_.Add(args.length()); |
| 756 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); | 550 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 unsigned ScriptDataImpl::Read(int position) { | 587 unsigned ScriptDataImpl::Read(int position) { |
| 794 return store_[ScriptDataImpl::kHeaderSize + position]; | 588 return store_[ScriptDataImpl::kHeaderSize + position]; |
| 795 } | 589 } |
| 796 | 590 |
| 797 | 591 |
| 798 unsigned* ScriptDataImpl::ReadAddress(int position) { | 592 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 799 return &store_[ScriptDataImpl::kHeaderSize + position]; | 593 return &store_[ScriptDataImpl::kHeaderSize + position]; |
| 800 } | 594 } |
| 801 | 595 |
| 802 | 596 |
| 803 FunctionEntry PartialParserRecorder::LogFunction(int start) { | 597 Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { |
| 804 #ifdef DEBUG | |
| 805 ASSERT(start > prev_start); | |
| 806 prev_start = start; | |
| 807 #endif | |
| 808 if (!is_recording_) return FunctionEntry(); | |
| 809 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0)); | |
| 810 result.set_start_pos(start); | |
| 811 return result; | |
| 812 } | |
| 813 | |
| 814 | |
| 815 class AstBuildingParser : public Parser { | |
| 816 public: | |
| 817 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | |
| 818 v8::Extension* extension, ScriptDataImpl* pre_data) | |
| 819 : Parser(script, | |
| 820 allow_natives_syntax, | |
| 821 extension, | |
| 822 PARSE, | |
| 823 factory(), | |
| 824 log(), | |
| 825 pre_data), | |
| 826 factory_(pre_data ? pre_data->symbol_count() : 0) { } | |
| 827 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | |
| 828 Vector<const char*> args); | |
| 829 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | |
| 830 FunctionLiteral* fun, bool resolve, bool* ok); | |
| 831 AstBuildingParserFactory* factory() { return &factory_; } | |
| 832 ParserLog* log() { return &log_; } | |
| 833 | |
| 834 private: | |
| 835 ParserLog log_; | |
| 836 AstBuildingParserFactory factory_; | |
| 837 }; | |
| 838 | |
| 839 | |
| 840 class PreParser : public Parser { | |
| 841 public: | |
| 842 PreParser(Handle<Script> script, bool allow_natives_syntax, | |
| 843 v8::Extension* extension, ParserLog* recorder) | |
| 844 : Parser(script, allow_natives_syntax, extension, PREPARSE, | |
| 845 factory(), recorder, NULL), | |
| 846 factory_(true) { } | |
| 847 virtual void ReportMessageAt(Scanner::Location loc, const char* message, | |
| 848 Vector<const char*> args); | |
| 849 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | |
| 850 FunctionLiteral* fun, bool resolve, bool* ok); | |
| 851 ParserFactory* factory() { return &factory_; } | |
| 852 virtual PartialParserRecorder* recorder() = 0; | |
| 853 | |
| 854 private: | |
| 855 ParserFactory factory_; | |
| 856 }; | |
| 857 | |
| 858 | |
| 859 class CompletePreParser : public PreParser { | |
| 860 public: | |
| 861 CompletePreParser(Handle<Script> script, bool allow_natives_syntax, | |
| 862 v8::Extension* extension) | |
| 863 : PreParser(script, allow_natives_syntax, extension, &recorder_), | |
| 864 recorder_() { } | |
| 865 virtual PartialParserRecorder* recorder() { return &recorder_; } | |
| 866 private: | |
| 867 CompleteParserRecorder recorder_; | |
| 868 }; | |
| 869 | |
| 870 | |
| 871 class PartialPreParser : public PreParser { | |
| 872 public: | |
| 873 PartialPreParser(Handle<Script> script, bool allow_natives_syntax, | |
| 874 v8::Extension* extension) | |
| 875 : PreParser(script, allow_natives_syntax, extension, &recorder_), | |
| 876 recorder_() { } | |
| 877 virtual PartialParserRecorder* recorder() { return &recorder_; } | |
| 878 private: | |
| 879 PartialParserRecorder recorder_; | |
| 880 }; | |
| 881 | |
| 882 | |
| 883 Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type, | |
| 884 bool inside_with) { | |
| 885 Scope* result = new Scope(parent, type); | 598 Scope* result = new Scope(parent, type); |
| 886 result->Initialize(inside_with); | 599 result->Initialize(inside_with); |
| 887 return result; | 600 return result; |
| 888 } | 601 } |
| 889 | 602 |
| 890 | |
| 891 Statement* AstBuildingParserFactory::EmptyStatement() { | |
| 892 // Use a statically allocated empty statement singleton to avoid | |
| 893 // allocating lots and lots of empty statements. | |
| 894 static v8::internal::EmptyStatement empty; | |
| 895 return ∅ | |
| 896 } | |
| 897 | |
| 898 | |
| 899 Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type, | |
| 900 bool inside_with) { | |
| 901 ASSERT(parent != NULL); | |
| 902 parent->type_ = type; | |
| 903 // Initialize function is hijacked by DummyScope to increment scope depth. | |
| 904 parent->Initialize(inside_with); | |
| 905 return parent; | |
| 906 } | |
| 907 | |
| 908 | |
| 909 VariableProxy* PreParser::Declare(Handle<String> name, Variable::Mode mode, | |
| 910 FunctionLiteral* fun, bool resolve, | |
| 911 bool* ok) { | |
| 912 return NULL; | |
| 913 } | |
| 914 | |
| 915 | |
| 916 | |
| 917 // ---------------------------------------------------------------------------- | 603 // ---------------------------------------------------------------------------- |
| 918 // Target is a support class to facilitate manipulation of the | 604 // Target is a support class to facilitate manipulation of the |
| 919 // Parser's target_stack_ (the stack of potential 'break' and | 605 // Parser's target_stack_ (the stack of potential 'break' and |
| 920 // 'continue' statement targets). Upon construction, a new target is | 606 // 'continue' statement targets). Upon construction, a new target is |
| 921 // added; it is removed upon destruction. | 607 // added; it is removed upon destruction. |
| 922 | 608 |
| 923 class Target BASE_EMBEDDED { | 609 class Target BASE_EMBEDDED { |
| 924 public: | 610 public: |
| 925 Target(Target** variable, AstNode* node) | 611 Target(Target** variable, AstNode* node) |
| 926 : variable_(variable), node_(node), previous_(*variable) { | 612 : variable_(variable), node_(node), previous_(*variable) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 ((void)0 | 695 ((void)0 |
| 1010 #define DUMMY ) // to make indentation work | 696 #define DUMMY ) // to make indentation work |
| 1011 #undef DUMMY | 697 #undef DUMMY |
| 1012 | 698 |
| 1013 // ---------------------------------------------------------------------------- | 699 // ---------------------------------------------------------------------------- |
| 1014 // Implementation of Parser | 700 // Implementation of Parser |
| 1015 | 701 |
| 1016 Parser::Parser(Handle<Script> script, | 702 Parser::Parser(Handle<Script> script, |
| 1017 bool allow_natives_syntax, | 703 bool allow_natives_syntax, |
| 1018 v8::Extension* extension, | 704 v8::Extension* extension, |
| 1019 ParserMode is_pre_parsing, | |
| 1020 ParserFactory* factory, | |
| 1021 ParserLog* log, | |
| 1022 ScriptDataImpl* pre_data) | 705 ScriptDataImpl* pre_data) |
| 1023 : script_(script), | 706 : symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
| 707 script_(script), |
| 1024 scanner_(), | 708 scanner_(), |
| 1025 top_scope_(NULL), | 709 top_scope_(NULL), |
| 1026 with_nesting_level_(0), | 710 with_nesting_level_(0), |
| 1027 temp_scope_(NULL), | 711 temp_scope_(NULL), |
| 1028 target_stack_(NULL), | 712 target_stack_(NULL), |
| 1029 allow_natives_syntax_(allow_natives_syntax), | 713 allow_natives_syntax_(allow_natives_syntax), |
| 1030 extension_(extension), | 714 extension_(extension), |
| 1031 factory_(factory), | |
| 1032 log_(log), | |
| 1033 is_pre_parsing_(is_pre_parsing == PREPARSE), | |
| 1034 pre_data_(pre_data), | 715 pre_data_(pre_data), |
| 1035 fni_(NULL) { | 716 fni_(NULL) { |
| 1036 } | 717 } |
| 1037 | 718 |
| 1038 | 719 |
| 1039 bool Parser::PreParseProgram(Handle<String> source, | |
| 1040 unibrow::CharacterStream* stream) { | |
| 1041 HistogramTimerScope timer(&Counters::pre_parse); | |
| 1042 AssertNoZoneAllocation assert_no_zone_allocation; | |
| 1043 AssertNoAllocation assert_no_allocation; | |
| 1044 NoHandleAllocation no_handle_allocation; | |
| 1045 scanner_.Initialize(source, stream, JAVASCRIPT); | |
| 1046 ASSERT(target_stack_ == NULL); | |
| 1047 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | |
| 1048 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | |
| 1049 DummyScope top_scope; | |
| 1050 LexicalScope scope(&this->top_scope_, &this->with_nesting_level_, &top_scope); | |
| 1051 TemporaryScope temp_scope(&this->temp_scope_); | |
| 1052 ZoneListWrapper<Statement> processor; | |
| 1053 bool ok = true; | |
| 1054 ParseSourceElements(&processor, Token::EOS, &ok); | |
| 1055 return !scanner().stack_overflow(); | |
| 1056 } | |
| 1057 | |
| 1058 | |
| 1059 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 720 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 1060 bool in_global_context) { | 721 bool in_global_context) { |
| 1061 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 722 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 1062 | 723 |
| 1063 HistogramTimerScope timer(&Counters::parse); | 724 HistogramTimerScope timer(&Counters::parse); |
| 1064 Counters::total_parse_size.Increment(source->length()); | 725 Counters::total_parse_size.Increment(source->length()); |
| 1065 fni_ = new FuncNameInferrer(); | 726 fni_ = new FuncNameInferrer(); |
| 1066 | 727 |
| 1067 // Initialize parser state. | 728 // Initialize parser state. |
| 1068 source->TryFlatten(); | 729 source->TryFlatten(); |
| 1069 scanner_.Initialize(source, JAVASCRIPT); | 730 scanner_.Initialize(source, JAVASCRIPT); |
| 1070 ASSERT(target_stack_ == NULL); | 731 ASSERT(target_stack_ == NULL); |
| 1071 if (pre_data_ != NULL) pre_data_->Initialize(); | 732 if (pre_data_ != NULL) pre_data_->Initialize(); |
| 1072 | 733 |
| 1073 // Compute the parsing mode. | 734 // Compute the parsing mode. |
| 1074 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 735 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 1075 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 736 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 1076 | 737 |
| 1077 Scope::Type type = | 738 Scope::Type type = |
| 1078 in_global_context | 739 in_global_context |
| 1079 ? Scope::GLOBAL_SCOPE | 740 ? Scope::GLOBAL_SCOPE |
| 1080 : Scope::EVAL_SCOPE; | 741 : Scope::EVAL_SCOPE; |
| 1081 Handle<String> no_name = factory()->EmptySymbol(); | 742 Handle<String> no_name = Factory::empty_symbol(); |
| 1082 | 743 |
| 1083 FunctionLiteral* result = NULL; | 744 FunctionLiteral* result = NULL; |
| 1084 { Scope* scope = factory()->NewScope(top_scope_, type, inside_with()); | 745 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 1085 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 746 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 1086 scope); | 747 scope); |
| 1087 TemporaryScope temp_scope(&this->temp_scope_); | 748 TemporaryScope temp_scope(&this->temp_scope_); |
| 1088 ZoneListWrapper<Statement> body(16); | 749 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 1089 bool ok = true; | 750 bool ok = true; |
| 1090 ParseSourceElements(&body, Token::EOS, &ok); | 751 ParseSourceElements(body, Token::EOS, &ok); |
| 1091 if (ok) { | 752 if (ok) { |
| 1092 result = NEW(FunctionLiteral( | 753 result = new FunctionLiteral( |
| 1093 no_name, | 754 no_name, |
| 1094 top_scope_, | 755 top_scope_, |
| 1095 body.elements(), | 756 body, |
| 1096 temp_scope.materialized_literal_count(), | 757 temp_scope.materialized_literal_count(), |
| 1097 temp_scope.expected_property_count(), | 758 temp_scope.expected_property_count(), |
| 1098 temp_scope.only_simple_this_property_assignments(), | 759 temp_scope.only_simple_this_property_assignments(), |
| 1099 temp_scope.this_property_assignments(), | 760 temp_scope.this_property_assignments(), |
| 1100 0, | 761 0, |
| 1101 0, | 762 0, |
| 1102 source->length(), | 763 source->length(), |
| 1103 false, | 764 false, |
| 1104 temp_scope.ContainsLoops())); | 765 temp_scope.ContainsLoops()); |
| 1105 } else if (scanner().stack_overflow()) { | 766 } else if (scanner().stack_overflow()) { |
| 1106 Top::StackOverflow(); | 767 Top::StackOverflow(); |
| 1107 } | 768 } |
| 1108 } | 769 } |
| 1109 | 770 |
| 1110 // Make sure the target stack is empty. | 771 // Make sure the target stack is empty. |
| 1111 ASSERT(target_stack_ == NULL); | 772 ASSERT(target_stack_ == NULL); |
| 1112 | 773 |
| 1113 // If there was a syntax error we have to get rid of the AST | 774 // If there was a syntax error we have to get rid of the AST |
| 1114 // and it is not safe to do so before the scope has been deleted. | 775 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1132 scanner_.Initialize(source, info->start_position(), info->end_position(), | 793 scanner_.Initialize(source, info->start_position(), info->end_position(), |
| 1133 JAVASCRIPT); | 794 JAVASCRIPT); |
| 1134 ASSERT(target_stack_ == NULL); | 795 ASSERT(target_stack_ == NULL); |
| 1135 mode_ = PARSE_EAGERLY; | 796 mode_ = PARSE_EAGERLY; |
| 1136 | 797 |
| 1137 // Place holder for the result. | 798 // Place holder for the result. |
| 1138 FunctionLiteral* result = NULL; | 799 FunctionLiteral* result = NULL; |
| 1139 | 800 |
| 1140 { | 801 { |
| 1141 // Parse the function literal. | 802 // Parse the function literal. |
| 1142 Handle<String> no_name = factory()->EmptySymbol(); | 803 Handle<String> no_name = Factory::empty_symbol(); |
| 1143 Scope* scope = | 804 Scope* scope = |
| 1144 factory()->NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 805 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 1145 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 806 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 1146 scope); | 807 scope); |
| 1147 TemporaryScope temp_scope(&this->temp_scope_); | 808 TemporaryScope temp_scope(&this->temp_scope_); |
| 1148 | 809 |
| 1149 FunctionLiteralType type = | 810 FunctionLiteralType type = |
| 1150 info->is_expression() ? EXPRESSION : DECLARATION; | 811 info->is_expression() ? EXPRESSION : DECLARATION; |
| 1151 bool ok = true; | 812 bool ok = true; |
| 1152 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); | 813 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); |
| 1153 // Make sure the results agree. | 814 // Make sure the results agree. |
| 1154 ASSERT(ok == (result != NULL)); | 815 ASSERT(ok == (result != NULL)); |
| 1155 // The only errors should be stack overflows. | 816 // The only errors should be stack overflows. |
| 1156 ASSERT(ok || scanner_.stack_overflow()); | 817 ASSERT(ok || scanner_.stack_overflow()); |
| 1157 } | 818 } |
| 1158 | 819 |
| 1159 // Make sure the target stack is empty. | 820 // Make sure the target stack is empty. |
| 1160 ASSERT(target_stack_ == NULL); | 821 ASSERT(target_stack_ == NULL); |
| 1161 | 822 |
| 1162 // If there was a stack overflow we have to get rid of AST and it is | 823 // If there was a stack overflow we have to get rid of AST and it is |
| 1163 // not safe to do before scope has been deleted. | 824 // not safe to do before scope has been deleted. |
| 1164 if (result == NULL) { | 825 if (result == NULL) { |
| 1165 Top::StackOverflow(); | 826 Top::StackOverflow(); |
| 1166 zone_scope.DeleteOnExit(); | 827 zone_scope.DeleteOnExit(); |
| 1167 } | 828 } |
| 1168 return result; | 829 return result; |
| 1169 } | 830 } |
| 1170 | 831 |
| 1171 | 832 |
| 833 Handle<String> Parser::GetSymbol(bool* ok) { |
| 834 int symbol_id = -1; |
| 835 if (pre_data() != NULL) { |
| 836 symbol_id = pre_data()->GetSymbolIdentifier(); |
| 837 } |
| 838 return LookupSymbol(symbol_id, scanner_.literal()); |
| 839 } |
| 840 |
| 841 |
| 1172 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 842 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
| 1173 Scanner::Location source_location = scanner_.location(); | 843 Scanner::Location source_location = scanner_.location(); |
| 1174 ReportMessageAt(source_location, type, args); | 844 ReportMessageAt(source_location, type, args); |
| 1175 } | 845 } |
| 1176 | 846 |
| 1177 | 847 |
| 1178 Handle<String> Parser::GetSymbol(bool* ok) { | 848 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 1179 if (is_pre_parsing_) { | 849 const char* type, |
| 1180 log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal()); | 850 Vector<const char*> args) { |
| 1181 return Handle<String>::null(); | |
| 1182 } | |
| 1183 int symbol_id = -1; | |
| 1184 if (pre_data() != NULL) { | |
| 1185 symbol_id = pre_data()->GetSymbolIdentifier(); | |
| 1186 } | |
| 1187 return factory()->LookupSymbol(symbol_id, scanner_.literal()); | |
| 1188 } | |
| 1189 | |
| 1190 | |
| 1191 void AstBuildingParser::ReportMessageAt(Scanner::Location source_location, | |
| 1192 const char* type, | |
| 1193 Vector<const char*> args) { | |
| 1194 MessageLocation location(script_, | 851 MessageLocation location(script_, |
| 1195 source_location.beg_pos, source_location.end_pos); | 852 source_location.beg_pos, source_location.end_pos); |
| 1196 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 853 Handle<JSArray> array = Factory::NewJSArray(args.length()); |
| 1197 for (int i = 0; i < args.length(); i++) { | 854 for (int i = 0; i < args.length(); i++) { |
| 1198 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); | 855 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); |
| 1199 } | 856 } |
| 1200 Handle<Object> result = Factory::NewSyntaxError(type, array); | 857 Handle<Object> result = Factory::NewSyntaxError(type, array); |
| 1201 Top::Throw(*result, &location); | 858 Top::Throw(*result, &location); |
| 1202 } | 859 } |
| 1203 | 860 |
| 1204 | 861 |
| 1205 void PreParser::ReportMessageAt(Scanner::Location source_location, | |
| 1206 const char* type, | |
| 1207 Vector<const char*> args) { | |
| 1208 recorder()->LogMessage(source_location, type, args); | |
| 1209 } | |
| 1210 | |
| 1211 | |
| 1212 // Base class containing common code for the different finder classes used by | 862 // Base class containing common code for the different finder classes used by |
| 1213 // the parser. | 863 // the parser. |
| 1214 class ParserFinder { | 864 class ParserFinder { |
| 1215 protected: | 865 protected: |
| 1216 ParserFinder() {} | 866 ParserFinder() {} |
| 1217 static Assignment* AsAssignment(Statement* stat) { | 867 static Assignment* AsAssignment(Statement* stat) { |
| 1218 if (stat == NULL) return NULL; | 868 if (stat == NULL) return NULL; |
| 1219 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); | 869 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); |
| 1220 if (exp_stat == NULL) return NULL; | 870 if (exp_stat == NULL) return NULL; |
| 1221 return exp_stat->expression()->AsAssignment(); | 871 return exp_stat->expression()->AsAssignment(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1243 EndBlock(); | 893 EndBlock(); |
| 1244 } | 894 } |
| 1245 } | 895 } |
| 1246 if (!InBlock() && (assignment != NULL) && | 896 if (!InBlock() && (assignment != NULL) && |
| 1247 (assignment->op() == Token::ASSIGN)) { | 897 (assignment->op() == Token::ASSIGN)) { |
| 1248 StartBlock(assignment); | 898 StartBlock(assignment); |
| 1249 } | 899 } |
| 1250 } | 900 } |
| 1251 | 901 |
| 1252 private: | 902 private: |
| 903 // The minimum number of contiguous assignment that will |
| 904 // be treated as an initialization block. Benchmarks show that |
| 905 // the overhead exceeds the savings below this limit. |
| 906 static const int kMinInitializationBlock = 3; |
| 907 |
| 1253 // Returns true if the expressions appear to denote the same object. | 908 // Returns true if the expressions appear to denote the same object. |
| 1254 // In the context of initialization blocks, we only consider expressions | 909 // In the context of initialization blocks, we only consider expressions |
| 1255 // of the form 'expr.x' or expr["x"]. | 910 // of the form 'expr.x' or expr["x"]. |
| 1256 static bool SameObject(Expression* e1, Expression* e2) { | 911 static bool SameObject(Expression* e1, Expression* e2) { |
| 1257 VariableProxy* v1 = e1->AsVariableProxy(); | 912 VariableProxy* v1 = e1->AsVariableProxy(); |
| 1258 VariableProxy* v2 = e2->AsVariableProxy(); | 913 VariableProxy* v2 = e2->AsVariableProxy(); |
| 1259 if (v1 != NULL && v2 != NULL) { | 914 if (v1 != NULL && v2 != NULL) { |
| 1260 return v1->name()->Equals(*v2->name()); | 915 return v1->name()->Equals(*v2->name()); |
| 1261 } | 916 } |
| 1262 Property* p1 = e1->AsProperty(); | 917 Property* p1 = e1->AsProperty(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1295 last_in_block_ = assignment; | 950 last_in_block_ = assignment; |
| 1296 block_size_ = 1; | 951 block_size_ = 1; |
| 1297 } | 952 } |
| 1298 | 953 |
| 1299 void UpdateBlock(Assignment* assignment) { | 954 void UpdateBlock(Assignment* assignment) { |
| 1300 last_in_block_ = assignment; | 955 last_in_block_ = assignment; |
| 1301 ++block_size_; | 956 ++block_size_; |
| 1302 } | 957 } |
| 1303 | 958 |
| 1304 void EndBlock() { | 959 void EndBlock() { |
| 1305 if (block_size_ >= Parser::kMinInitializationBlock) { | 960 if (block_size_ >= kMinInitializationBlock) { |
| 1306 first_in_block_->mark_block_start(); | 961 first_in_block_->mark_block_start(); |
| 1307 last_in_block_->mark_block_end(); | 962 last_in_block_->mark_block_end(); |
| 1308 } | 963 } |
| 1309 last_in_block_ = first_in_block_ = NULL; | 964 last_in_block_ = first_in_block_ = NULL; |
| 1310 block_size_ = 0; | 965 block_size_ = 0; |
| 1311 } | 966 } |
| 1312 | 967 |
| 1313 bool InBlock() { return first_in_block_ != NULL; } | 968 bool InBlock() { return first_in_block_ != NULL; } |
| 1314 | 969 |
| 1315 Assignment* first_in_block_; | 970 Assignment* first_in_block_; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 } | 1108 } |
| 1454 } | 1109 } |
| 1455 | 1110 |
| 1456 bool only_simple_this_property_assignments_; | 1111 bool only_simple_this_property_assignments_; |
| 1457 ZoneStringList* names_; | 1112 ZoneStringList* names_; |
| 1458 ZoneList<int>* assigned_arguments_; | 1113 ZoneList<int>* assigned_arguments_; |
| 1459 ZoneObjectList* assigned_constants_; | 1114 ZoneObjectList* assigned_constants_; |
| 1460 }; | 1115 }; |
| 1461 | 1116 |
| 1462 | 1117 |
| 1463 void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor, | 1118 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1464 int end_token, | 1119 int end_token, |
| 1465 bool* ok) { | 1120 bool* ok) { |
| 1466 // SourceElements :: | 1121 // SourceElements :: |
| 1467 // (Statement)* <end_token> | 1122 // (Statement)* <end_token> |
| 1468 | 1123 |
| 1469 // Allocate a target stack to use for this set of source | 1124 // Allocate a target stack to use for this set of source |
| 1470 // elements. This way, all scripts and functions get their own | 1125 // elements. This way, all scripts and functions get their own |
| 1471 // target stack thus avoiding illegal breaks and continues across | 1126 // target stack thus avoiding illegal breaks and continues across |
| 1472 // functions. | 1127 // functions. |
| 1473 TargetScope scope(&this->target_stack_); | 1128 TargetScope scope(&this->target_stack_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1485 block_finder.Update(stat); | 1140 block_finder.Update(stat); |
| 1486 } | 1141 } |
| 1487 // Find and mark all assignments to named properties in this (this.x =) | 1142 // Find and mark all assignments to named properties in this (this.x =) |
| 1488 if (top_scope_->is_function_scope()) { | 1143 if (top_scope_->is_function_scope()) { |
| 1489 this_property_assignment_finder.Update(top_scope_, stat); | 1144 this_property_assignment_finder.Update(top_scope_, stat); |
| 1490 } | 1145 } |
| 1491 processor->Add(stat); | 1146 processor->Add(stat); |
| 1492 } | 1147 } |
| 1493 | 1148 |
| 1494 // Propagate the collected information on this property assignments. | 1149 // Propagate the collected information on this property assignments. |
| 1495 if (!is_pre_parsing_ && top_scope_->is_function_scope()) { | 1150 if (top_scope_->is_function_scope()) { |
| 1496 bool only_simple_this_property_assignments = | 1151 bool only_simple_this_property_assignments = |
| 1497 this_property_assignment_finder.only_simple_this_property_assignments() | 1152 this_property_assignment_finder.only_simple_this_property_assignments() |
| 1498 && top_scope_->declarations()->length() == 0; | 1153 && top_scope_->declarations()->length() == 0; |
| 1499 if (only_simple_this_property_assignments) { | 1154 if (only_simple_this_property_assignments) { |
| 1500 temp_scope_->SetThisPropertyAssignmentInfo( | 1155 temp_scope_->SetThisPropertyAssignmentInfo( |
| 1501 only_simple_this_property_assignments, | 1156 only_simple_this_property_assignments, |
| 1502 this_property_assignment_finder.GetThisPropertyAssignments()); | 1157 this_property_assignment_finder.GetThisPropertyAssignments()); |
| 1503 } | 1158 } |
| 1504 } | 1159 } |
| 1505 return 0; | 1160 return 0; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1538 case Token::LBRACE: | 1193 case Token::LBRACE: |
| 1539 return ParseBlock(labels, ok); | 1194 return ParseBlock(labels, ok); |
| 1540 | 1195 |
| 1541 case Token::CONST: // fall through | 1196 case Token::CONST: // fall through |
| 1542 case Token::VAR: | 1197 case Token::VAR: |
| 1543 stmt = ParseVariableStatement(ok); | 1198 stmt = ParseVariableStatement(ok); |
| 1544 break; | 1199 break; |
| 1545 | 1200 |
| 1546 case Token::SEMICOLON: | 1201 case Token::SEMICOLON: |
| 1547 Next(); | 1202 Next(); |
| 1548 return factory()->EmptyStatement(); | 1203 return EmptyStatement(); |
| 1549 | 1204 |
| 1550 case Token::IF: | 1205 case Token::IF: |
| 1551 stmt = ParseIfStatement(labels, ok); | 1206 stmt = ParseIfStatement(labels, ok); |
| 1552 break; | 1207 break; |
| 1553 | 1208 |
| 1554 case Token::DO: | 1209 case Token::DO: |
| 1555 stmt = ParseDoWhileStatement(labels, ok); | 1210 stmt = ParseDoWhileStatement(labels, ok); |
| 1556 break; | 1211 break; |
| 1557 | 1212 |
| 1558 case Token::WHILE: | 1213 case Token::WHILE: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1586 case Token::THROW: | 1241 case Token::THROW: |
| 1587 stmt = ParseThrowStatement(ok); | 1242 stmt = ParseThrowStatement(ok); |
| 1588 break; | 1243 break; |
| 1589 | 1244 |
| 1590 case Token::TRY: { | 1245 case Token::TRY: { |
| 1591 // NOTE: It is somewhat complicated to have labels on | 1246 // NOTE: It is somewhat complicated to have labels on |
| 1592 // try-statements. When breaking out of a try-finally statement, | 1247 // try-statements. When breaking out of a try-finally statement, |
| 1593 // one must take great care not to treat it as a | 1248 // one must take great care not to treat it as a |
| 1594 // fall-through. It is much easier just to wrap the entire | 1249 // fall-through. It is much easier just to wrap the entire |
| 1595 // try-statement in a statement block and put the labels there | 1250 // try-statement in a statement block and put the labels there |
| 1596 Block* result = NEW(Block(labels, 1, false)); | 1251 Block* result = new Block(labels, 1, false); |
| 1597 Target target(&this->target_stack_, result); | 1252 Target target(&this->target_stack_, result); |
| 1598 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1253 TryStatement* statement = ParseTryStatement(CHECK_OK); |
| 1599 if (statement) { | 1254 if (statement) { |
| 1600 statement->set_statement_pos(statement_pos); | 1255 statement->set_statement_pos(statement_pos); |
| 1601 } | 1256 } |
| 1602 if (result) result->AddStatement(statement); | 1257 if (result) result->AddStatement(statement); |
| 1603 return result; | 1258 return result; |
| 1604 } | 1259 } |
| 1605 | 1260 |
| 1606 case Token::FUNCTION: | 1261 case Token::FUNCTION: |
| 1607 return ParseFunctionDeclaration(ok); | 1262 return ParseFunctionDeclaration(ok); |
| 1608 | 1263 |
| 1609 case Token::NATIVE: | 1264 case Token::NATIVE: |
| 1610 return ParseNativeDeclaration(ok); | 1265 return ParseNativeDeclaration(ok); |
| 1611 | 1266 |
| 1612 case Token::DEBUGGER: | 1267 case Token::DEBUGGER: |
| 1613 stmt = ParseDebuggerStatement(ok); | 1268 stmt = ParseDebuggerStatement(ok); |
| 1614 break; | 1269 break; |
| 1615 | 1270 |
| 1616 default: | 1271 default: |
| 1617 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1272 stmt = ParseExpressionOrLabelledStatement(labels, ok); |
| 1618 } | 1273 } |
| 1619 | 1274 |
| 1620 // Store the source position of the statement | 1275 // Store the source position of the statement |
| 1621 if (stmt != NULL) stmt->set_statement_pos(statement_pos); | 1276 if (stmt != NULL) stmt->set_statement_pos(statement_pos); |
| 1622 return stmt; | 1277 return stmt; |
| 1623 } | 1278 } |
| 1624 | 1279 |
| 1625 | 1280 |
| 1626 VariableProxy* AstBuildingParser::Declare(Handle<String> name, | 1281 VariableProxy* Parser::Declare(Handle<String> name, |
| 1627 Variable::Mode mode, | 1282 Variable::Mode mode, |
| 1628 FunctionLiteral* fun, | 1283 FunctionLiteral* fun, |
| 1629 bool resolve, | 1284 bool resolve, |
| 1630 bool* ok) { | 1285 bool* ok) { |
| 1631 Variable* var = NULL; | 1286 Variable* var = NULL; |
| 1632 // If we are inside a function, a declaration of a variable | 1287 // If we are inside a function, a declaration of a variable |
| 1633 // is a truly local variable, and the scope of the variable | 1288 // is a truly local variable, and the scope of the variable |
| 1634 // is always the function scope. | 1289 // is always the function scope. |
| 1635 | 1290 |
| 1636 // If a function scope exists, then we can statically declare this | 1291 // If a function scope exists, then we can statically declare this |
| 1637 // variable and also set its mode. In any case, a Declaration node | 1292 // variable and also set its mode. In any case, a Declaration node |
| 1638 // will be added to the scope so that the declaration can be added | 1293 // will be added to the scope so that the declaration can be added |
| 1639 // to the corresponding activation frame at runtime if necessary. | 1294 // to the corresponding activation frame at runtime if necessary. |
| 1640 // For instance declarations inside an eval scope need to be added | 1295 // For instance declarations inside an eval scope need to be added |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1675 // parameters) if the proxy is needed or not. The proxy will be | 1330 // parameters) if the proxy is needed or not. The proxy will be |
| 1676 // bound during variable resolution time unless it was pre-bound | 1331 // bound during variable resolution time unless it was pre-bound |
| 1677 // below. | 1332 // below. |
| 1678 // | 1333 // |
| 1679 // WARNING: This will lead to multiple declaration nodes for the | 1334 // WARNING: This will lead to multiple declaration nodes for the |
| 1680 // same variable if it is declared several times. This is not a | 1335 // same variable if it is declared several times. This is not a |
| 1681 // semantic issue as long as we keep the source order, but it may be | 1336 // semantic issue as long as we keep the source order, but it may be |
| 1682 // a performance issue since it may lead to repeated | 1337 // a performance issue since it may lead to repeated |
| 1683 // Runtime::DeclareContextSlot() calls. | 1338 // Runtime::DeclareContextSlot() calls. |
| 1684 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); | 1339 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); |
| 1685 top_scope_->AddDeclaration(NEW(Declaration(proxy, mode, fun))); | 1340 top_scope_->AddDeclaration(new Declaration(proxy, mode, fun)); |
| 1686 | 1341 |
| 1687 // For global const variables we bind the proxy to a variable. | 1342 // For global const variables we bind the proxy to a variable. |
| 1688 if (mode == Variable::CONST && top_scope_->is_global_scope()) { | 1343 if (mode == Variable::CONST && top_scope_->is_global_scope()) { |
| 1689 ASSERT(resolve); // should be set by all callers | 1344 ASSERT(resolve); // should be set by all callers |
| 1690 Variable::Kind kind = Variable::NORMAL; | 1345 Variable::Kind kind = Variable::NORMAL; |
| 1691 var = NEW(Variable(top_scope_, name, Variable::CONST, true, kind)); | 1346 var = new Variable(top_scope_, name, Variable::CONST, true, kind); |
| 1692 } | 1347 } |
| 1693 | 1348 |
| 1694 // If requested and we have a local variable, bind the proxy to the variable | 1349 // If requested and we have a local variable, bind the proxy to the variable |
| 1695 // at parse-time. This is used for functions (and consts) declared inside | 1350 // at parse-time. This is used for functions (and consts) declared inside |
| 1696 // statements: the corresponding function (or const) variable must be in the | 1351 // statements: the corresponding function (or const) variable must be in the |
| 1697 // function scope and not a statement-local scope, e.g. as provided with a | 1352 // function scope and not a statement-local scope, e.g. as provided with a |
| 1698 // 'with' statement: | 1353 // 'with' statement: |
| 1699 // | 1354 // |
| 1700 // with (obj) { | 1355 // with (obj) { |
| 1701 // function f() {} | 1356 // function f() {} |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 } | 1388 } |
| 1734 | 1389 |
| 1735 Expect(Token::NATIVE, CHECK_OK); | 1390 Expect(Token::NATIVE, CHECK_OK); |
| 1736 Expect(Token::FUNCTION, CHECK_OK); | 1391 Expect(Token::FUNCTION, CHECK_OK); |
| 1737 Handle<String> name = ParseIdentifier(CHECK_OK); | 1392 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1738 Expect(Token::LPAREN, CHECK_OK); | 1393 Expect(Token::LPAREN, CHECK_OK); |
| 1739 bool done = (peek() == Token::RPAREN); | 1394 bool done = (peek() == Token::RPAREN); |
| 1740 while (!done) { | 1395 while (!done) { |
| 1741 ParseIdentifier(CHECK_OK); | 1396 ParseIdentifier(CHECK_OK); |
| 1742 done = (peek() == Token::RPAREN); | 1397 done = (peek() == Token::RPAREN); |
| 1743 if (!done) Expect(Token::COMMA, CHECK_OK); | 1398 if (!done) { |
| 1399 Expect(Token::COMMA, CHECK_OK); |
| 1400 } |
| 1744 } | 1401 } |
| 1745 Expect(Token::RPAREN, CHECK_OK); | 1402 Expect(Token::RPAREN, CHECK_OK); |
| 1746 Expect(Token::SEMICOLON, CHECK_OK); | 1403 Expect(Token::SEMICOLON, CHECK_OK); |
| 1747 | 1404 |
| 1748 if (is_pre_parsing_) return NULL; | |
| 1749 | |
| 1750 // Make sure that the function containing the native declaration | 1405 // Make sure that the function containing the native declaration |
| 1751 // isn't lazily compiled. The extension structures are only | 1406 // isn't lazily compiled. The extension structures are only |
| 1752 // accessible while parsing the first time not when reparsing | 1407 // accessible while parsing the first time not when reparsing |
| 1753 // because of lazy compilation. | 1408 // because of lazy compilation. |
| 1754 top_scope_->ForceEagerCompilation(); | 1409 top_scope_->ForceEagerCompilation(); |
| 1755 | 1410 |
| 1756 // Compute the function template for the native function. | 1411 // Compute the function template for the native function. |
| 1757 v8::Handle<v8::FunctionTemplate> fun_template = | 1412 v8::Handle<v8::FunctionTemplate> fun_template = |
| 1758 extension_->GetNativeFunction(v8::Utils::ToLocal(name)); | 1413 extension_->GetNativeFunction(v8::Utils::ToLocal(name)); |
| 1759 ASSERT(!fun_template.IsEmpty()); | 1414 ASSERT(!fun_template.IsEmpty()); |
| 1760 | 1415 |
| 1761 // Instantiate the function and create a shared function info from it. | 1416 // Instantiate the function and create a shared function info from it. |
| 1762 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); | 1417 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); |
| 1763 const int literals = fun->NumberOfLiterals(); | 1418 const int literals = fun->NumberOfLiterals(); |
| 1764 Handle<Code> code = Handle<Code>(fun->shared()->code()); | 1419 Handle<Code> code = Handle<Code>(fun->shared()->code()); |
| 1765 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); | 1420 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); |
| 1766 Handle<SharedFunctionInfo> shared = | 1421 Handle<SharedFunctionInfo> shared = |
| 1767 Factory::NewSharedFunctionInfo(name, literals, code, | 1422 Factory::NewSharedFunctionInfo(name, literals, code, |
| 1768 Handle<SerializedScopeInfo>(fun->shared()->scope_info())); | 1423 Handle<SerializedScopeInfo>(fun->shared()->scope_info())); |
| 1769 shared->set_construct_stub(*construct_stub); | 1424 shared->set_construct_stub(*construct_stub); |
| 1770 | 1425 |
| 1771 // Copy the function data to the shared function info. | 1426 // Copy the function data to the shared function info. |
| 1772 shared->set_function_data(fun->shared()->function_data()); | 1427 shared->set_function_data(fun->shared()->function_data()); |
| 1773 int parameters = fun->shared()->formal_parameter_count(); | 1428 int parameters = fun->shared()->formal_parameter_count(); |
| 1774 shared->set_formal_parameter_count(parameters); | 1429 shared->set_formal_parameter_count(parameters); |
| 1775 | 1430 |
| 1776 // TODO(1240846): It's weird that native function declarations are | 1431 // TODO(1240846): It's weird that native function declarations are |
| 1777 // introduced dynamically when we meet their declarations, whereas | 1432 // introduced dynamically when we meet their declarations, whereas |
| 1778 // other functions are setup when entering the surrounding scope. | 1433 // other functions are setup when entering the surrounding scope. |
| 1779 SharedFunctionInfoLiteral* lit = NEW(SharedFunctionInfoLiteral(shared)); | 1434 SharedFunctionInfoLiteral* lit = new SharedFunctionInfoLiteral(shared); |
| 1780 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); | 1435 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); |
| 1781 return NEW(ExpressionStatement( | 1436 return new ExpressionStatement( |
| 1782 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition))); | 1437 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); |
| 1783 } | 1438 } |
| 1784 | 1439 |
| 1785 | 1440 |
| 1786 Statement* Parser::ParseFunctionDeclaration(bool* ok) { | 1441 Statement* Parser::ParseFunctionDeclaration(bool* ok) { |
| 1787 // FunctionDeclaration :: | 1442 // FunctionDeclaration :: |
| 1788 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1443 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1789 Expect(Token::FUNCTION, CHECK_OK); | 1444 Expect(Token::FUNCTION, CHECK_OK); |
| 1790 int function_token_position = scanner().location().beg_pos; | 1445 int function_token_position = scanner().location().beg_pos; |
| 1791 Handle<String> name = ParseIdentifier(CHECK_OK); | 1446 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1792 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1447 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1793 function_token_position, | 1448 function_token_position, |
| 1794 DECLARATION, | 1449 DECLARATION, |
| 1795 CHECK_OK); | 1450 CHECK_OK); |
| 1796 // Even if we're not at the top-level of the global or a function | 1451 // Even if we're not at the top-level of the global or a function |
| 1797 // scope, we treat is as such and introduce the function with it's | 1452 // scope, we treat is as such and introduce the function with it's |
| 1798 // initial value upon entering the corresponding scope. | 1453 // initial value upon entering the corresponding scope. |
| 1799 Declare(name, Variable::VAR, fun, true, CHECK_OK); | 1454 Declare(name, Variable::VAR, fun, true, CHECK_OK); |
| 1800 return factory()->EmptyStatement(); | 1455 return EmptyStatement(); |
| 1801 } | 1456 } |
| 1802 | 1457 |
| 1803 | 1458 |
| 1804 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1459 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1805 // Block :: | 1460 // Block :: |
| 1806 // '{' Statement* '}' | 1461 // '{' Statement* '}' |
| 1807 | 1462 |
| 1808 // Note that a Block does not introduce a new execution scope! | 1463 // Note that a Block does not introduce a new execution scope! |
| 1809 // (ECMA-262, 3rd, 12.2) | 1464 // (ECMA-262, 3rd, 12.2) |
| 1810 // | 1465 // |
| 1811 // Construct block expecting 16 statements. | 1466 // Construct block expecting 16 statements. |
| 1812 Block* result = NEW(Block(labels, 16, false)); | 1467 Block* result = new Block(labels, 16, false); |
| 1813 Target target(&this->target_stack_, result); | 1468 Target target(&this->target_stack_, result); |
| 1814 Expect(Token::LBRACE, CHECK_OK); | 1469 Expect(Token::LBRACE, CHECK_OK); |
| 1815 while (peek() != Token::RBRACE) { | 1470 while (peek() != Token::RBRACE) { |
| 1816 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1471 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 1817 if (stat && !stat->IsEmpty()) result->AddStatement(stat); | 1472 if (stat && !stat->IsEmpty()) result->AddStatement(stat); |
| 1818 } | 1473 } |
| 1819 Expect(Token::RBRACE, CHECK_OK); | 1474 Expect(Token::RBRACE, CHECK_OK); |
| 1820 return result; | 1475 return result; |
| 1821 } | 1476 } |
| 1822 | 1477 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1861 // Scope declaration, and rewrite the source-level initialization into an | 1516 // Scope declaration, and rewrite the source-level initialization into an |
| 1862 // assignment statement. We use a block to collect multiple assignments. | 1517 // assignment statement. We use a block to collect multiple assignments. |
| 1863 // | 1518 // |
| 1864 // We mark the block as initializer block because we don't want the | 1519 // We mark the block as initializer block because we don't want the |
| 1865 // rewriter to add a '.result' assignment to such a block (to get compliant | 1520 // rewriter to add a '.result' assignment to such a block (to get compliant |
| 1866 // behavior for code such as print(eval('var x = 7')), and for cosmetic | 1521 // behavior for code such as print(eval('var x = 7')), and for cosmetic |
| 1867 // reasons when pretty-printing. Also, unless an assignment (initialization) | 1522 // reasons when pretty-printing. Also, unless an assignment (initialization) |
| 1868 // is inside an initializer block, it is ignored. | 1523 // is inside an initializer block, it is ignored. |
| 1869 // | 1524 // |
| 1870 // Create new block with one expected declaration. | 1525 // Create new block with one expected declaration. |
| 1871 Block* block = NEW(Block(NULL, 1, true)); | 1526 Block* block = new Block(NULL, 1, true); |
| 1872 VariableProxy* last_var = NULL; // the last variable declared | 1527 VariableProxy* last_var = NULL; // the last variable declared |
| 1873 int nvars = 0; // the number of variables declared | 1528 int nvars = 0; // the number of variables declared |
| 1874 do { | 1529 do { |
| 1875 if (fni_ != NULL) fni_->Enter(); | 1530 if (fni_ != NULL) fni_->Enter(); |
| 1876 | 1531 |
| 1877 // Parse variable name. | 1532 // Parse variable name. |
| 1878 if (nvars > 0) Consume(Token::COMMA); | 1533 if (nvars > 0) Consume(Token::COMMA); |
| 1879 Handle<String> name = ParseIdentifier(CHECK_OK); | 1534 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1880 if (fni_ != NULL) fni_->PushVariableName(name); | 1535 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1881 | 1536 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1952 // | 1607 // |
| 1953 // Executing the variable declaration statement will always | 1608 // Executing the variable declaration statement will always |
| 1954 // guarantee to give the global object a "local" variable; a | 1609 // guarantee to give the global object a "local" variable; a |
| 1955 // variable defined in the global object and not in any | 1610 // variable defined in the global object and not in any |
| 1956 // prototype. This way, global variable declarations can shadow | 1611 // prototype. This way, global variable declarations can shadow |
| 1957 // properties in the prototype chain, but only after the variable | 1612 // properties in the prototype chain, but only after the variable |
| 1958 // declaration statement has been executed. This is important in | 1613 // declaration statement has been executed. This is important in |
| 1959 // browsers where the global object (window) has lots of | 1614 // browsers where the global object (window) has lots of |
| 1960 // properties defined in prototype objects. | 1615 // properties defined in prototype objects. |
| 1961 | 1616 |
| 1962 if (!is_pre_parsing_ && top_scope_->is_global_scope()) { | 1617 if (top_scope_->is_global_scope()) { |
| 1963 // Compute the arguments for the runtime call. | 1618 // Compute the arguments for the runtime call. |
| 1964 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2); | 1619 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2); |
| 1965 // Be careful not to assign a value to the global variable if | 1620 // Be careful not to assign a value to the global variable if |
| 1966 // we're in a with. The initialization value should not | 1621 // we're in a with. The initialization value should not |
| 1967 // necessarily be stored in the global object in that case, | 1622 // necessarily be stored in the global object in that case, |
| 1968 // which is why we need to generate a separate assignment node. | 1623 // which is why we need to generate a separate assignment node. |
| 1969 arguments->Add(NEW(Literal(name))); // we have at least 1 parameter | 1624 arguments->Add(new Literal(name)); // we have at least 1 parameter |
| 1970 if (is_const || (value != NULL && !inside_with())) { | 1625 if (is_const || (value != NULL && !inside_with())) { |
| 1971 arguments->Add(value); | 1626 arguments->Add(value); |
| 1972 value = NULL; // zap the value to avoid the unnecessary assignment | 1627 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1973 } | 1628 } |
| 1974 // Construct the call to Runtime::DeclareGlobal{Variable,Const}Locally | 1629 // Construct the call to Runtime::DeclareGlobal{Variable,Const}Locally |
| 1975 // and add it to the initialization statement block. Note that | 1630 // and add it to the initialization statement block. Note that |
| 1976 // this function does different things depending on if we have | 1631 // this function does different things depending on if we have |
| 1977 // 1 or 2 parameters. | 1632 // 1 or 2 parameters. |
| 1978 CallRuntime* initialize; | 1633 CallRuntime* initialize; |
| 1979 if (is_const) { | 1634 if (is_const) { |
| 1980 initialize = | 1635 initialize = |
| 1981 NEW(CallRuntime( | 1636 new CallRuntime( |
| 1982 Factory::InitializeConstGlobal_symbol(), | 1637 Factory::InitializeConstGlobal_symbol(), |
| 1983 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1638 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1984 arguments)); | 1639 arguments); |
| 1985 } else { | 1640 } else { |
| 1986 initialize = | 1641 initialize = |
| 1987 NEW(CallRuntime( | 1642 new CallRuntime( |
| 1988 Factory::InitializeVarGlobal_symbol(), | 1643 Factory::InitializeVarGlobal_symbol(), |
| 1989 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | 1644 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 1990 arguments)); | 1645 arguments); |
| 1991 } | 1646 } |
| 1992 block->AddStatement(NEW(ExpressionStatement(initialize))); | 1647 block->AddStatement(new ExpressionStatement(initialize)); |
| 1993 } | 1648 } |
| 1994 | 1649 |
| 1995 // Add an assignment node to the initialization statement block if | 1650 // Add an assignment node to the initialization statement block if |
| 1996 // we still have a pending initialization value. We must distinguish | 1651 // we still have a pending initialization value. We must distinguish |
| 1997 // between variables and constants: Variable initializations are simply | 1652 // between variables and constants: Variable initializations are simply |
| 1998 // assignments (with all the consequences if they are inside a 'with' | 1653 // assignments (with all the consequences if they are inside a 'with' |
| 1999 // statement - they may change a 'with' object property). Constant | 1654 // statement - they may change a 'with' object property). Constant |
| 2000 // initializations always assign to the declared constant which is | 1655 // initializations always assign to the declared constant which is |
| 2001 // always at the function scope level. This is only relevant for | 1656 // always at the function scope level. This is only relevant for |
| 2002 // dynamically looked-up variables and constants (the start context | 1657 // dynamically looked-up variables and constants (the start context |
| 2003 // for constant lookups is always the function context, while it is | 1658 // for constant lookups is always the function context, while it is |
| 2004 // the top context for variables). Sigh... | 1659 // the top context for variables). Sigh... |
| 2005 if (value != NULL) { | 1660 if (value != NULL) { |
| 2006 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); | 1661 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); |
| 2007 Assignment* assignment = NEW(Assignment(op, last_var, value, position)); | 1662 Assignment* assignment = new Assignment(op, last_var, value, position); |
| 2008 if (block) block->AddStatement(NEW(ExpressionStatement(assignment))); | 1663 if (block) block->AddStatement(new ExpressionStatement(assignment)); |
| 2009 } | 1664 } |
| 2010 | 1665 |
| 2011 if (fni_ != NULL) fni_->Leave(); | 1666 if (fni_ != NULL) fni_->Leave(); |
| 2012 } while (peek() == Token::COMMA); | 1667 } while (peek() == Token::COMMA); |
| 2013 | 1668 |
| 2014 if (!is_const && nvars == 1) { | 1669 if (!is_const && nvars == 1) { |
| 2015 // We have a single, non-const variable. | 1670 // We have a single, non-const variable. |
| 2016 if (is_pre_parsing_) { | 1671 ASSERT(last_var != NULL); |
| 2017 // If we're preparsing then we need to set the var to something | 1672 *var = last_var; |
| 2018 // in order for for-in loops to parse correctly. | |
| 2019 *var = ValidLeftHandSideSentinel::instance(); | |
| 2020 } else { | |
| 2021 ASSERT(last_var != NULL); | |
| 2022 *var = last_var; | |
| 2023 } | |
| 2024 } | 1673 } |
| 2025 | 1674 |
| 2026 return block; | 1675 return block; |
| 2027 } | 1676 } |
| 2028 | 1677 |
| 2029 | 1678 |
| 2030 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { | 1679 static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { |
| 2031 ASSERT(!label.is_null()); | 1680 ASSERT(!label.is_null()); |
| 2032 if (labels != NULL) | 1681 if (labels != NULL) |
| 2033 for (int i = labels->length(); i-- > 0; ) | 1682 for (int i = labels->length(); i-- > 0; ) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2048 if (peek() == Token::COLON && expr && | 1697 if (peek() == Token::COLON && expr && |
| 2049 expr->AsVariableProxy() != NULL && | 1698 expr->AsVariableProxy() != NULL && |
| 2050 !expr->AsVariableProxy()->is_this()) { | 1699 !expr->AsVariableProxy()->is_this()) { |
| 2051 VariableProxy* var = expr->AsVariableProxy(); | 1700 VariableProxy* var = expr->AsVariableProxy(); |
| 2052 Handle<String> label = var->name(); | 1701 Handle<String> label = var->name(); |
| 2053 // TODO(1240780): We don't check for redeclaration of labels | 1702 // TODO(1240780): We don't check for redeclaration of labels |
| 2054 // during preparsing since keeping track of the set of active | 1703 // during preparsing since keeping track of the set of active |
| 2055 // labels requires nontrivial changes to the way scopes are | 1704 // labels requires nontrivial changes to the way scopes are |
| 2056 // structured. However, these are probably changes we want to | 1705 // structured. However, these are probably changes we want to |
| 2057 // make later anyway so we should go back and fix this then. | 1706 // make later anyway so we should go back and fix this then. |
| 2058 if (!is_pre_parsing_) { | 1707 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { |
| 2059 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { | 1708 SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS); |
| 2060 SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS); | 1709 const char* elms[2] = { "Label", *c_string }; |
| 2061 const char* elms[2] = { "Label", *c_string }; | 1710 Vector<const char*> args(elms, 2); |
| 2062 Vector<const char*> args(elms, 2); | 1711 ReportMessage("redeclaration", args); |
| 2063 ReportMessage("redeclaration", args); | 1712 *ok = false; |
| 2064 *ok = false; | 1713 return NULL; |
| 2065 return NULL; | |
| 2066 } | |
| 2067 if (labels == NULL) labels = new ZoneStringList(4); | |
| 2068 labels->Add(label); | |
| 2069 // Remove the "ghost" variable that turned out to be a label | |
| 2070 // from the top scope. This way, we don't try to resolve it | |
| 2071 // during the scope processing. | |
| 2072 top_scope_->RemoveUnresolved(var); | |
| 2073 } | 1714 } |
| 1715 if (labels == NULL) labels = new ZoneStringList(4); |
| 1716 labels->Add(label); |
| 1717 // Remove the "ghost" variable that turned out to be a label |
| 1718 // from the top scope. This way, we don't try to resolve it |
| 1719 // during the scope processing. |
| 1720 top_scope_->RemoveUnresolved(var); |
| 2074 Expect(Token::COLON, CHECK_OK); | 1721 Expect(Token::COLON, CHECK_OK); |
| 2075 return ParseStatement(labels, ok); | 1722 return ParseStatement(labels, ok); |
| 2076 } | 1723 } |
| 2077 | 1724 |
| 2078 // Parsed expression statement. | 1725 // Parsed expression statement. |
| 2079 ExpectSemicolon(CHECK_OK); | 1726 ExpectSemicolon(CHECK_OK); |
| 2080 return NEW(ExpressionStatement(expr)); | 1727 return new ExpressionStatement(expr); |
| 2081 } | 1728 } |
| 2082 | 1729 |
| 2083 | 1730 |
| 2084 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 1731 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2085 // IfStatement :: | 1732 // IfStatement :: |
| 2086 // 'if' '(' Expression ')' Statement ('else' Statement)? | 1733 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2087 | 1734 |
| 2088 Expect(Token::IF, CHECK_OK); | 1735 Expect(Token::IF, CHECK_OK); |
| 2089 Expect(Token::LPAREN, CHECK_OK); | 1736 Expect(Token::LPAREN, CHECK_OK); |
| 2090 Expression* condition = ParseExpression(true, CHECK_OK); | 1737 Expression* condition = ParseExpression(true, CHECK_OK); |
| 2091 Expect(Token::RPAREN, CHECK_OK); | 1738 Expect(Token::RPAREN, CHECK_OK); |
| 2092 Statement* then_statement = ParseStatement(labels, CHECK_OK); | 1739 Statement* then_statement = ParseStatement(labels, CHECK_OK); |
| 2093 Statement* else_statement = NULL; | 1740 Statement* else_statement = NULL; |
| 2094 if (peek() == Token::ELSE) { | 1741 if (peek() == Token::ELSE) { |
| 2095 Next(); | 1742 Next(); |
| 2096 else_statement = ParseStatement(labels, CHECK_OK); | 1743 else_statement = ParseStatement(labels, CHECK_OK); |
| 2097 } else if (!is_pre_parsing_) { | 1744 } else { |
| 2098 else_statement = factory()->EmptyStatement(); | 1745 else_statement = EmptyStatement(); |
| 2099 } | 1746 } |
| 2100 return NEW(IfStatement(condition, then_statement, else_statement)); | 1747 return new IfStatement(condition, then_statement, else_statement); |
| 2101 } | 1748 } |
| 2102 | 1749 |
| 2103 | 1750 |
| 2104 Statement* Parser::ParseContinueStatement(bool* ok) { | 1751 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2105 // ContinueStatement :: | 1752 // ContinueStatement :: |
| 2106 // 'continue' Identifier? ';' | 1753 // 'continue' Identifier? ';' |
| 2107 | 1754 |
| 2108 Expect(Token::CONTINUE, CHECK_OK); | 1755 Expect(Token::CONTINUE, CHECK_OK); |
| 2109 Handle<String> label = Handle<String>::null(); | 1756 Handle<String> label = Handle<String>::null(); |
| 2110 Token::Value tok = peek(); | 1757 Token::Value tok = peek(); |
| 2111 if (!scanner_.has_line_terminator_before_next() && | 1758 if (!scanner_.has_line_terminator_before_next() && |
| 2112 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1759 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2113 label = ParseIdentifier(CHECK_OK); | 1760 label = ParseIdentifier(CHECK_OK); |
| 2114 } | 1761 } |
| 2115 IterationStatement* target = NULL; | 1762 IterationStatement* target = NULL; |
| 2116 if (!is_pre_parsing_) { | 1763 target = LookupContinueTarget(label, CHECK_OK); |
| 2117 target = LookupContinueTarget(label, CHECK_OK); | 1764 if (target == NULL) { |
| 2118 if (target == NULL) { | 1765 // Illegal continue statement. To be consistent with KJS we delay |
| 2119 // Illegal continue statement. To be consistent with KJS we delay | 1766 // reporting of the syntax error until runtime. |
| 2120 // reporting of the syntax error until runtime. | 1767 Handle<String> error_type = Factory::illegal_continue_symbol(); |
| 2121 Handle<String> error_type = Factory::illegal_continue_symbol(); | 1768 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); |
| 2122 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); | 1769 Expression* throw_error = NewThrowSyntaxError(error_type, label); |
| 2123 Expression* throw_error = NewThrowSyntaxError(error_type, label); | 1770 return new ExpressionStatement(throw_error); |
| 2124 return NEW(ExpressionStatement(throw_error)); | |
| 2125 } | |
| 2126 } | 1771 } |
| 2127 ExpectSemicolon(CHECK_OK); | 1772 ExpectSemicolon(CHECK_OK); |
| 2128 return NEW(ContinueStatement(target)); | 1773 return new ContinueStatement(target); |
| 2129 } | 1774 } |
| 2130 | 1775 |
| 2131 | 1776 |
| 2132 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 1777 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2133 // BreakStatement :: | 1778 // BreakStatement :: |
| 2134 // 'break' Identifier? ';' | 1779 // 'break' Identifier? ';' |
| 2135 | 1780 |
| 2136 Expect(Token::BREAK, CHECK_OK); | 1781 Expect(Token::BREAK, CHECK_OK); |
| 2137 Handle<String> label; | 1782 Handle<String> label; |
| 2138 Token::Value tok = peek(); | 1783 Token::Value tok = peek(); |
| 2139 if (!scanner_.has_line_terminator_before_next() && | 1784 if (!scanner_.has_line_terminator_before_next() && |
| 2140 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 1785 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2141 label = ParseIdentifier(CHECK_OK); | 1786 label = ParseIdentifier(CHECK_OK); |
| 2142 } | 1787 } |
| 2143 // Parse labeled break statements that target themselves into | 1788 // Parse labeled break statements that target themselves into |
| 2144 // empty statements, e.g. 'l1: l2: l3: break l2;' | 1789 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2145 if (!label.is_null() && ContainsLabel(labels, label)) { | 1790 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2146 return factory()->EmptyStatement(); | 1791 return EmptyStatement(); |
| 2147 } | 1792 } |
| 2148 BreakableStatement* target = NULL; | 1793 BreakableStatement* target = NULL; |
| 2149 if (!is_pre_parsing_) { | 1794 target = LookupBreakTarget(label, CHECK_OK); |
| 2150 target = LookupBreakTarget(label, CHECK_OK); | 1795 if (target == NULL) { |
| 2151 if (target == NULL) { | 1796 // Illegal break statement. To be consistent with KJS we delay |
| 2152 // Illegal break statement. To be consistent with KJS we delay | 1797 // reporting of the syntax error until runtime. |
| 2153 // reporting of the syntax error until runtime. | 1798 Handle<String> error_type = Factory::illegal_break_symbol(); |
| 2154 Handle<String> error_type = Factory::illegal_break_symbol(); | 1799 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); |
| 2155 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); | 1800 Expression* throw_error = NewThrowSyntaxError(error_type, label); |
| 2156 Expression* throw_error = NewThrowSyntaxError(error_type, label); | 1801 return new ExpressionStatement(throw_error); |
| 2157 return NEW(ExpressionStatement(throw_error)); | |
| 2158 } | |
| 2159 } | 1802 } |
| 2160 ExpectSemicolon(CHECK_OK); | 1803 ExpectSemicolon(CHECK_OK); |
| 2161 return NEW(BreakStatement(target)); | 1804 return new BreakStatement(target); |
| 2162 } | 1805 } |
| 2163 | 1806 |
| 2164 | 1807 |
| 2165 Statement* Parser::ParseReturnStatement(bool* ok) { | 1808 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2166 // ReturnStatement :: | 1809 // ReturnStatement :: |
| 2167 // 'return' Expression? ';' | 1810 // 'return' Expression? ';' |
| 2168 | 1811 |
| 2169 // Consume the return token. It is necessary to do the before | 1812 // Consume the return token. It is necessary to do the before |
| 2170 // reporting any errors on it, because of the way errors are | 1813 // reporting any errors on it, because of the way errors are |
| 2171 // reported (underlining). | 1814 // reported (underlining). |
| 2172 Expect(Token::RETURN, CHECK_OK); | 1815 Expect(Token::RETURN, CHECK_OK); |
| 2173 | 1816 |
| 2174 // An ECMAScript program is considered syntactically incorrect if it | 1817 // An ECMAScript program is considered syntactically incorrect if it |
| 2175 // contains a return statement that is not within the body of a | 1818 // contains a return statement that is not within the body of a |
| 2176 // function. See ECMA-262, section 12.9, page 67. | 1819 // function. See ECMA-262, section 12.9, page 67. |
| 2177 // | 1820 // |
| 2178 // To be consistent with KJS we report the syntax error at runtime. | 1821 // To be consistent with KJS we report the syntax error at runtime. |
| 2179 if (!is_pre_parsing_ && !top_scope_->is_function_scope()) { | 1822 if (!top_scope_->is_function_scope()) { |
| 2180 Handle<String> type = Factory::illegal_return_symbol(); | 1823 Handle<String> type = Factory::illegal_return_symbol(); |
| 2181 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); | 1824 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); |
| 2182 return NEW(ExpressionStatement(throw_error)); | 1825 return new ExpressionStatement(throw_error); |
| 2183 } | 1826 } |
| 2184 | 1827 |
| 2185 Token::Value tok = peek(); | 1828 Token::Value tok = peek(); |
| 2186 if (scanner_.has_line_terminator_before_next() || | 1829 if (scanner_.has_line_terminator_before_next() || |
| 2187 tok == Token::SEMICOLON || | 1830 tok == Token::SEMICOLON || |
| 2188 tok == Token::RBRACE || | 1831 tok == Token::RBRACE || |
| 2189 tok == Token::EOS) { | 1832 tok == Token::EOS) { |
| 2190 ExpectSemicolon(CHECK_OK); | 1833 ExpectSemicolon(CHECK_OK); |
| 2191 return NEW(ReturnStatement(GetLiteralUndefined())); | 1834 return new ReturnStatement(GetLiteralUndefined()); |
| 2192 } | 1835 } |
| 2193 | 1836 |
| 2194 Expression* expr = ParseExpression(true, CHECK_OK); | 1837 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2195 ExpectSemicolon(CHECK_OK); | 1838 ExpectSemicolon(CHECK_OK); |
| 2196 return NEW(ReturnStatement(expr)); | 1839 return new ReturnStatement(expr); |
| 2197 } | 1840 } |
| 2198 | 1841 |
| 2199 | 1842 |
| 2200 Block* Parser::WithHelper(Expression* obj, | 1843 Block* Parser::WithHelper(Expression* obj, |
| 2201 ZoneStringList* labels, | 1844 ZoneStringList* labels, |
| 2202 bool is_catch_block, | 1845 bool is_catch_block, |
| 2203 bool* ok) { | 1846 bool* ok) { |
| 2204 // Parse the statement and collect escaping labels. | 1847 // Parse the statement and collect escaping labels. |
| 2205 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); | 1848 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); |
| 2206 TargetCollector collector(target_list); | 1849 TargetCollector collector(target_list); |
| 2207 Statement* stat; | 1850 Statement* stat; |
| 2208 { Target target(&this->target_stack_, &collector); | 1851 { Target target(&this->target_stack_, &collector); |
| 2209 with_nesting_level_++; | 1852 with_nesting_level_++; |
| 2210 top_scope_->RecordWithStatement(); | 1853 top_scope_->RecordWithStatement(); |
| 2211 stat = ParseStatement(labels, CHECK_OK); | 1854 stat = ParseStatement(labels, CHECK_OK); |
| 2212 with_nesting_level_--; | 1855 with_nesting_level_--; |
| 2213 } | 1856 } |
| 2214 // Create resulting block with two statements. | 1857 // Create resulting block with two statements. |
| 2215 // 1: Evaluate the with expression. | 1858 // 1: Evaluate the with expression. |
| 2216 // 2: The try-finally block evaluating the body. | 1859 // 2: The try-finally block evaluating the body. |
| 2217 Block* result = NEW(Block(NULL, 2, false)); | 1860 Block* result = new Block(NULL, 2, false); |
| 2218 | 1861 |
| 2219 if (result != NULL) { | 1862 if (result != NULL) { |
| 2220 result->AddStatement(NEW(WithEnterStatement(obj, is_catch_block))); | 1863 result->AddStatement(new WithEnterStatement(obj, is_catch_block)); |
| 2221 | 1864 |
| 2222 // Create body block. | 1865 // Create body block. |
| 2223 Block* body = NEW(Block(NULL, 1, false)); | 1866 Block* body = new Block(NULL, 1, false); |
| 2224 body->AddStatement(stat); | 1867 body->AddStatement(stat); |
| 2225 | 1868 |
| 2226 // Create exit block. | 1869 // Create exit block. |
| 2227 Block* exit = NEW(Block(NULL, 1, false)); | 1870 Block* exit = new Block(NULL, 1, false); |
| 2228 exit->AddStatement(NEW(WithExitStatement())); | 1871 exit->AddStatement(new WithExitStatement()); |
| 2229 | 1872 |
| 2230 // Return a try-finally statement. | 1873 // Return a try-finally statement. |
| 2231 TryFinallyStatement* wrapper = NEW(TryFinallyStatement(body, exit)); | 1874 TryFinallyStatement* wrapper = new TryFinallyStatement(body, exit); |
| 2232 wrapper->set_escaping_targets(collector.targets()); | 1875 wrapper->set_escaping_targets(collector.targets()); |
| 2233 result->AddStatement(wrapper); | 1876 result->AddStatement(wrapper); |
| 2234 } | 1877 } |
| 2235 return result; | 1878 return result; |
| 2236 } | 1879 } |
| 2237 | 1880 |
| 2238 | 1881 |
| 2239 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1882 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2240 // WithStatement :: | 1883 // WithStatement :: |
| 2241 // 'with' '(' Expression ')' Statement | 1884 // 'with' '(' Expression ')' Statement |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2263 if (*default_seen_ptr) { | 1906 if (*default_seen_ptr) { |
| 2264 ReportMessage("multiple_defaults_in_switch", | 1907 ReportMessage("multiple_defaults_in_switch", |
| 2265 Vector<const char*>::empty()); | 1908 Vector<const char*>::empty()); |
| 2266 *ok = false; | 1909 *ok = false; |
| 2267 return NULL; | 1910 return NULL; |
| 2268 } | 1911 } |
| 2269 *default_seen_ptr = true; | 1912 *default_seen_ptr = true; |
| 2270 } | 1913 } |
| 2271 Expect(Token::COLON, CHECK_OK); | 1914 Expect(Token::COLON, CHECK_OK); |
| 2272 | 1915 |
| 2273 ZoneListWrapper<Statement> statements = factory()->NewList<Statement>(5); | 1916 ZoneList<Statement*>* statements = new ZoneList<Statement*>(5); |
| 2274 while (peek() != Token::CASE && | 1917 while (peek() != Token::CASE && |
| 2275 peek() != Token::DEFAULT && | 1918 peek() != Token::DEFAULT && |
| 2276 peek() != Token::RBRACE) { | 1919 peek() != Token::RBRACE) { |
| 2277 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1920 Statement* stat = ParseStatement(NULL, CHECK_OK); |
| 2278 statements.Add(stat); | 1921 statements->Add(stat); |
| 2279 } | 1922 } |
| 2280 | 1923 |
| 2281 return NEW(CaseClause(label, statements.elements())); | 1924 return new CaseClause(label, statements); |
| 2282 } | 1925 } |
| 2283 | 1926 |
| 2284 | 1927 |
| 2285 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, | 1928 SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, |
| 2286 bool* ok) { | 1929 bool* ok) { |
| 2287 // SwitchStatement :: | 1930 // SwitchStatement :: |
| 2288 // 'switch' '(' Expression ')' '{' CaseClause* '}' | 1931 // 'switch' '(' Expression ')' '{' CaseClause* '}' |
| 2289 | 1932 |
| 2290 SwitchStatement* statement = NEW(SwitchStatement(labels)); | 1933 SwitchStatement* statement = new SwitchStatement(labels); |
| 2291 Target target(&this->target_stack_, statement); | 1934 Target target(&this->target_stack_, statement); |
| 2292 | 1935 |
| 2293 Expect(Token::SWITCH, CHECK_OK); | 1936 Expect(Token::SWITCH, CHECK_OK); |
| 2294 Expect(Token::LPAREN, CHECK_OK); | 1937 Expect(Token::LPAREN, CHECK_OK); |
| 2295 Expression* tag = ParseExpression(true, CHECK_OK); | 1938 Expression* tag = ParseExpression(true, CHECK_OK); |
| 2296 Expect(Token::RPAREN, CHECK_OK); | 1939 Expect(Token::RPAREN, CHECK_OK); |
| 2297 | 1940 |
| 2298 bool default_seen = false; | 1941 bool default_seen = false; |
| 2299 ZoneListWrapper<CaseClause> cases = factory()->NewList<CaseClause>(4); | 1942 ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4); |
| 2300 Expect(Token::LBRACE, CHECK_OK); | 1943 Expect(Token::LBRACE, CHECK_OK); |
| 2301 while (peek() != Token::RBRACE) { | 1944 while (peek() != Token::RBRACE) { |
| 2302 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); | 1945 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); |
| 2303 cases.Add(clause); | 1946 cases->Add(clause); |
| 2304 } | 1947 } |
| 2305 Expect(Token::RBRACE, CHECK_OK); | 1948 Expect(Token::RBRACE, CHECK_OK); |
| 2306 | 1949 |
| 2307 if (statement) statement->Initialize(tag, cases.elements()); | 1950 if (statement) statement->Initialize(tag, cases); |
| 2308 return statement; | 1951 return statement; |
| 2309 } | 1952 } |
| 2310 | 1953 |
| 2311 | 1954 |
| 2312 Statement* Parser::ParseThrowStatement(bool* ok) { | 1955 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2313 // ThrowStatement :: | 1956 // ThrowStatement :: |
| 2314 // 'throw' Expression ';' | 1957 // 'throw' Expression ';' |
| 2315 | 1958 |
| 2316 Expect(Token::THROW, CHECK_OK); | 1959 Expect(Token::THROW, CHECK_OK); |
| 2317 int pos = scanner().location().beg_pos; | 1960 int pos = scanner().location().beg_pos; |
| 2318 if (scanner_.has_line_terminator_before_next()) { | 1961 if (scanner_.has_line_terminator_before_next()) { |
| 2319 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 1962 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2320 *ok = false; | 1963 *ok = false; |
| 2321 return NULL; | 1964 return NULL; |
| 2322 } | 1965 } |
| 2323 Expression* exception = ParseExpression(true, CHECK_OK); | 1966 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2324 ExpectSemicolon(CHECK_OK); | 1967 ExpectSemicolon(CHECK_OK); |
| 2325 | 1968 |
| 2326 return NEW(ExpressionStatement(new Throw(exception, pos))); | 1969 return new ExpressionStatement(new Throw(exception, pos)); |
| 2327 } | 1970 } |
| 2328 | 1971 |
| 2329 | 1972 |
| 2330 TryStatement* Parser::ParseTryStatement(bool* ok) { | 1973 TryStatement* Parser::ParseTryStatement(bool* ok) { |
| 2331 // TryStatement :: | 1974 // TryStatement :: |
| 2332 // 'try' Block Catch | 1975 // 'try' Block Catch |
| 2333 // 'try' Block Finally | 1976 // 'try' Block Finally |
| 2334 // 'try' Block Catch Finally | 1977 // 'try' Block Catch Finally |
| 2335 // | 1978 // |
| 2336 // Catch :: | 1979 // Catch :: |
| 2337 // 'catch' '(' Identifier ')' Block | 1980 // 'catch' '(' Identifier ')' Block |
| 2338 // | 1981 // |
| 2339 // Finally :: | 1982 // Finally :: |
| 2340 // 'finally' Block | 1983 // 'finally' Block |
| 2341 | 1984 |
| 2342 Expect(Token::TRY, CHECK_OK); | 1985 Expect(Token::TRY, CHECK_OK); |
| 2343 | 1986 |
| 2344 ZoneList<BreakTarget*>* target_list = NEW(ZoneList<BreakTarget*>(0)); | 1987 ZoneList<BreakTarget*>* target_list = new ZoneList<BreakTarget*>(0); |
| 2345 TargetCollector collector(target_list); | 1988 TargetCollector collector(target_list); |
| 2346 Block* try_block; | 1989 Block* try_block; |
| 2347 | 1990 |
| 2348 { Target target(&this->target_stack_, &collector); | 1991 { Target target(&this->target_stack_, &collector); |
| 2349 try_block = ParseBlock(NULL, CHECK_OK); | 1992 try_block = ParseBlock(NULL, CHECK_OK); |
| 2350 } | 1993 } |
| 2351 | 1994 |
| 2352 Block* catch_block = NULL; | 1995 Block* catch_block = NULL; |
| 2353 VariableProxy* catch_var = NULL; | 1996 VariableProxy* catch_var = NULL; |
| 2354 Block* finally_block = NULL; | 1997 Block* finally_block = NULL; |
| 2355 | 1998 |
| 2356 Token::Value tok = peek(); | 1999 Token::Value tok = peek(); |
| 2357 if (tok != Token::CATCH && tok != Token::FINALLY) { | 2000 if (tok != Token::CATCH && tok != Token::FINALLY) { |
| 2358 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); | 2001 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); |
| 2359 *ok = false; | 2002 *ok = false; |
| 2360 return NULL; | 2003 return NULL; |
| 2361 } | 2004 } |
| 2362 | 2005 |
| 2363 // If we can break out from the catch block and there is a finally block, | 2006 // If we can break out from the catch block and there is a finally block, |
| 2364 // then we will need to collect jump targets from the catch block. Since | 2007 // then we will need to collect jump targets from the catch block. Since |
| 2365 // we don't know yet if there will be a finally block, we always collect | 2008 // we don't know yet if there will be a finally block, we always collect |
| 2366 // the jump targets. | 2009 // the jump targets. |
| 2367 ZoneList<BreakTarget*>* catch_target_list = NEW(ZoneList<BreakTarget*>(0)); | 2010 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 2368 TargetCollector catch_collector(catch_target_list); | 2011 TargetCollector catch_collector(catch_target_list); |
| 2369 bool has_catch = false; | 2012 bool has_catch = false; |
| 2370 if (tok == Token::CATCH) { | 2013 if (tok == Token::CATCH) { |
| 2371 has_catch = true; | 2014 has_catch = true; |
| 2372 Consume(Token::CATCH); | 2015 Consume(Token::CATCH); |
| 2373 | 2016 |
| 2374 Expect(Token::LPAREN, CHECK_OK); | 2017 Expect(Token::LPAREN, CHECK_OK); |
| 2375 Handle<String> name = ParseIdentifier(CHECK_OK); | 2018 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2376 Expect(Token::RPAREN, CHECK_OK); | 2019 Expect(Token::RPAREN, CHECK_OK); |
| 2377 | 2020 |
| 2378 if (peek() == Token::LBRACE) { | 2021 if (peek() == Token::LBRACE) { |
| 2379 // Allocate a temporary for holding the finally state while | 2022 // Allocate a temporary for holding the finally state while |
| 2380 // executing the finally block. | 2023 // executing the finally block. |
| 2381 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); | 2024 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); |
| 2382 Literal* name_literal = NEW(Literal(name)); | 2025 Literal* name_literal = new Literal(name); |
| 2383 Expression* obj = NEW(CatchExtensionObject(name_literal, catch_var)); | 2026 Expression* obj = new CatchExtensionObject(name_literal, catch_var); |
| 2384 { Target target(&this->target_stack_, &catch_collector); | 2027 { Target target(&this->target_stack_, &catch_collector); |
| 2385 catch_block = WithHelper(obj, NULL, true, CHECK_OK); | 2028 catch_block = WithHelper(obj, NULL, true, CHECK_OK); |
| 2386 } | 2029 } |
| 2387 } else { | 2030 } else { |
| 2388 Expect(Token::LBRACE, CHECK_OK); | 2031 Expect(Token::LBRACE, CHECK_OK); |
| 2389 } | 2032 } |
| 2390 | 2033 |
| 2391 tok = peek(); | 2034 tok = peek(); |
| 2392 } | 2035 } |
| 2393 | 2036 |
| 2394 if (tok == Token::FINALLY || !has_catch) { | 2037 if (tok == Token::FINALLY || !has_catch) { |
| 2395 Consume(Token::FINALLY); | 2038 Consume(Token::FINALLY); |
| 2396 // Declare a variable for holding the finally state while | 2039 // Declare a variable for holding the finally state while |
| 2397 // executing the finally block. | 2040 // executing the finally block. |
| 2398 finally_block = ParseBlock(NULL, CHECK_OK); | 2041 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2399 } | 2042 } |
| 2400 | 2043 |
| 2401 // Simplify the AST nodes by converting: | 2044 // Simplify the AST nodes by converting: |
| 2402 // 'try { } catch { } finally { }' | 2045 // 'try { } catch { } finally { }' |
| 2403 // to: | 2046 // to: |
| 2404 // 'try { try { } catch { } } finally { }' | 2047 // 'try { try { } catch { } } finally { }' |
| 2405 | 2048 |
| 2406 if (!is_pre_parsing_ && catch_block != NULL && finally_block != NULL) { | 2049 if (catch_block != NULL && finally_block != NULL) { |
| 2407 TryCatchStatement* statement = | 2050 TryCatchStatement* statement = |
| 2408 NEW(TryCatchStatement(try_block, catch_var, catch_block)); | 2051 new TryCatchStatement(try_block, catch_var, catch_block); |
| 2409 statement->set_escaping_targets(collector.targets()); | 2052 statement->set_escaping_targets(collector.targets()); |
| 2410 try_block = NEW(Block(NULL, 1, false)); | 2053 try_block = new Block(NULL, 1, false); |
| 2411 try_block->AddStatement(statement); | 2054 try_block->AddStatement(statement); |
| 2412 catch_block = NULL; | 2055 catch_block = NULL; |
| 2413 } | 2056 } |
| 2414 | 2057 |
| 2415 TryStatement* result = NULL; | 2058 TryStatement* result = NULL; |
| 2416 if (!is_pre_parsing_) { | 2059 if (catch_block != NULL) { |
| 2417 if (catch_block != NULL) { | 2060 ASSERT(finally_block == NULL); |
| 2418 ASSERT(finally_block == NULL); | 2061 result = new TryCatchStatement(try_block, catch_var, catch_block); |
| 2419 result = NEW(TryCatchStatement(try_block, catch_var, catch_block)); | 2062 result->set_escaping_targets(collector.targets()); |
| 2420 result->set_escaping_targets(collector.targets()); | 2063 } else { |
| 2421 } else { | 2064 ASSERT(finally_block != NULL); |
| 2422 ASSERT(finally_block != NULL); | 2065 result = new TryFinallyStatement(try_block, finally_block); |
| 2423 result = NEW(TryFinallyStatement(try_block, finally_block)); | 2066 // Add the jump targets of the try block and the catch block. |
| 2424 // Add the jump targets of the try block and the catch block. | 2067 for (int i = 0; i < collector.targets()->length(); i++) { |
| 2425 for (int i = 0; i < collector.targets()->length(); i++) { | 2068 catch_collector.AddTarget(collector.targets()->at(i)); |
| 2426 catch_collector.AddTarget(collector.targets()->at(i)); | |
| 2427 } | |
| 2428 result->set_escaping_targets(catch_collector.targets()); | |
| 2429 } | 2069 } |
| 2070 result->set_escaping_targets(catch_collector.targets()); |
| 2430 } | 2071 } |
| 2431 | 2072 |
| 2432 return result; | 2073 return result; |
| 2433 } | 2074 } |
| 2434 | 2075 |
| 2435 | 2076 |
| 2436 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, | 2077 DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, |
| 2437 bool* ok) { | 2078 bool* ok) { |
| 2438 // DoStatement :: | 2079 // DoStatement :: |
| 2439 // 'do' Statement 'while' '(' Expression ')' ';' | 2080 // 'do' Statement 'while' '(' Expression ')' ';' |
| 2440 | 2081 |
| 2441 temp_scope_->AddLoop(); | 2082 temp_scope_->AddLoop(); |
| 2442 DoWhileStatement* loop = NEW(DoWhileStatement(labels)); | 2083 DoWhileStatement* loop = new DoWhileStatement(labels); |
| 2443 Target target(&this->target_stack_, loop); | 2084 Target target(&this->target_stack_, loop); |
| 2444 | 2085 |
| 2445 Expect(Token::DO, CHECK_OK); | 2086 Expect(Token::DO, CHECK_OK); |
| 2446 Statement* body = ParseStatement(NULL, CHECK_OK); | 2087 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2447 Expect(Token::WHILE, CHECK_OK); | 2088 Expect(Token::WHILE, CHECK_OK); |
| 2448 Expect(Token::LPAREN, CHECK_OK); | 2089 Expect(Token::LPAREN, CHECK_OK); |
| 2449 | 2090 |
| 2450 if (loop != NULL) { | 2091 if (loop != NULL) { |
| 2451 int position = scanner().location().beg_pos; | 2092 int position = scanner().location().beg_pos; |
| 2452 loop->set_condition_position(position); | 2093 loop->set_condition_position(position); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2465 if (loop != NULL) loop->Initialize(cond, body); | 2106 if (loop != NULL) loop->Initialize(cond, body); |
| 2466 return loop; | 2107 return loop; |
| 2467 } | 2108 } |
| 2468 | 2109 |
| 2469 | 2110 |
| 2470 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { | 2111 WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { |
| 2471 // WhileStatement :: | 2112 // WhileStatement :: |
| 2472 // 'while' '(' Expression ')' Statement | 2113 // 'while' '(' Expression ')' Statement |
| 2473 | 2114 |
| 2474 temp_scope_->AddLoop(); | 2115 temp_scope_->AddLoop(); |
| 2475 WhileStatement* loop = NEW(WhileStatement(labels)); | 2116 WhileStatement* loop = new WhileStatement(labels); |
| 2476 Target target(&this->target_stack_, loop); | 2117 Target target(&this->target_stack_, loop); |
| 2477 | 2118 |
| 2478 Expect(Token::WHILE, CHECK_OK); | 2119 Expect(Token::WHILE, CHECK_OK); |
| 2479 Expect(Token::LPAREN, CHECK_OK); | 2120 Expect(Token::LPAREN, CHECK_OK); |
| 2480 Expression* cond = ParseExpression(true, CHECK_OK); | 2121 Expression* cond = ParseExpression(true, CHECK_OK); |
| 2481 if (cond != NULL) cond->set_is_loop_condition(true); | 2122 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2482 Expect(Token::RPAREN, CHECK_OK); | 2123 Expect(Token::RPAREN, CHECK_OK); |
| 2483 Statement* body = ParseStatement(NULL, CHECK_OK); | 2124 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2484 | 2125 |
| 2485 if (loop != NULL) loop->Initialize(cond, body); | 2126 if (loop != NULL) loop->Initialize(cond, body); |
| 2486 return loop; | 2127 return loop; |
| 2487 } | 2128 } |
| 2488 | 2129 |
| 2489 | 2130 |
| 2490 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2131 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2491 // ForStatement :: | 2132 // ForStatement :: |
| 2492 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2133 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2493 | 2134 |
| 2494 temp_scope_->AddLoop(); | 2135 temp_scope_->AddLoop(); |
| 2495 Statement* init = NULL; | 2136 Statement* init = NULL; |
| 2496 | 2137 |
| 2497 Expect(Token::FOR, CHECK_OK); | 2138 Expect(Token::FOR, CHECK_OK); |
| 2498 Expect(Token::LPAREN, CHECK_OK); | 2139 Expect(Token::LPAREN, CHECK_OK); |
| 2499 if (peek() != Token::SEMICOLON) { | 2140 if (peek() != Token::SEMICOLON) { |
| 2500 if (peek() == Token::VAR || peek() == Token::CONST) { | 2141 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2501 Expression* each = NULL; | 2142 Expression* each = NULL; |
| 2502 Block* variable_statement = | 2143 Block* variable_statement = |
| 2503 ParseVariableDeclarations(false, &each, CHECK_OK); | 2144 ParseVariableDeclarations(false, &each, CHECK_OK); |
| 2504 if (peek() == Token::IN && each != NULL) { | 2145 if (peek() == Token::IN && each != NULL) { |
| 2505 ForInStatement* loop = NEW(ForInStatement(labels)); | 2146 ForInStatement* loop = new ForInStatement(labels); |
| 2506 Target target(&this->target_stack_, loop); | 2147 Target target(&this->target_stack_, loop); |
| 2507 | 2148 |
| 2508 Expect(Token::IN, CHECK_OK); | 2149 Expect(Token::IN, CHECK_OK); |
| 2509 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2150 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2510 Expect(Token::RPAREN, CHECK_OK); | 2151 Expect(Token::RPAREN, CHECK_OK); |
| 2511 | 2152 |
| 2512 Statement* body = ParseStatement(NULL, CHECK_OK); | 2153 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2513 if (is_pre_parsing_) { | 2154 loop->Initialize(each, enumerable, body); |
| 2514 return NULL; | 2155 Block* result = new Block(NULL, 2, false); |
| 2515 } else { | 2156 result->AddStatement(variable_statement); |
| 2516 loop->Initialize(each, enumerable, body); | 2157 result->AddStatement(loop); |
| 2517 Block* result = NEW(Block(NULL, 2, false)); | 2158 // Parsed for-in loop w/ variable/const declaration. |
| 2518 result->AddStatement(variable_statement); | 2159 return result; |
| 2519 result->AddStatement(loop); | |
| 2520 // Parsed for-in loop w/ variable/const declaration. | |
| 2521 return result; | |
| 2522 } | |
| 2523 | |
| 2524 } else { | 2160 } else { |
| 2525 init = variable_statement; | 2161 init = variable_statement; |
| 2526 } | 2162 } |
| 2527 | 2163 |
| 2528 } else { | 2164 } else { |
| 2529 Expression* expression = ParseExpression(false, CHECK_OK); | 2165 Expression* expression = ParseExpression(false, CHECK_OK); |
| 2530 if (peek() == Token::IN) { | 2166 if (peek() == Token::IN) { |
| 2531 // Signal a reference error if the expression is an invalid | 2167 // Signal a reference error if the expression is an invalid |
| 2532 // left-hand side expression. We could report this as a syntax | 2168 // left-hand side expression. We could report this as a syntax |
| 2533 // error here but for compatibility with JSC we choose to report | 2169 // error here but for compatibility with JSC we choose to report |
| 2534 // the error at runtime. | 2170 // the error at runtime. |
| 2535 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2171 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2536 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); | 2172 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); |
| 2537 expression = NewThrowReferenceError(type); | 2173 expression = NewThrowReferenceError(type); |
| 2538 } | 2174 } |
| 2539 ForInStatement* loop = NEW(ForInStatement(labels)); | 2175 ForInStatement* loop = new ForInStatement(labels); |
| 2540 Target target(&this->target_stack_, loop); | 2176 Target target(&this->target_stack_, loop); |
| 2541 | 2177 |
| 2542 Expect(Token::IN, CHECK_OK); | 2178 Expect(Token::IN, CHECK_OK); |
| 2543 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2179 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2544 Expect(Token::RPAREN, CHECK_OK); | 2180 Expect(Token::RPAREN, CHECK_OK); |
| 2545 | 2181 |
| 2546 Statement* body = ParseStatement(NULL, CHECK_OK); | 2182 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2547 if (loop) loop->Initialize(expression, enumerable, body); | 2183 if (loop) loop->Initialize(expression, enumerable, body); |
| 2548 // Parsed for-in loop. | 2184 // Parsed for-in loop. |
| 2549 return loop; | 2185 return loop; |
| 2550 | 2186 |
| 2551 } else { | 2187 } else { |
| 2552 init = NEW(ExpressionStatement(expression)); | 2188 init = new ExpressionStatement(expression); |
| 2553 } | 2189 } |
| 2554 } | 2190 } |
| 2555 } | 2191 } |
| 2556 | 2192 |
| 2557 // Standard 'for' loop | 2193 // Standard 'for' loop |
| 2558 ForStatement* loop = NEW(ForStatement(labels)); | 2194 ForStatement* loop = new ForStatement(labels); |
| 2559 Target target(&this->target_stack_, loop); | 2195 Target target(&this->target_stack_, loop); |
| 2560 | 2196 |
| 2561 // Parsed initializer at this point. | 2197 // Parsed initializer at this point. |
| 2562 Expect(Token::SEMICOLON, CHECK_OK); | 2198 Expect(Token::SEMICOLON, CHECK_OK); |
| 2563 | 2199 |
| 2564 Expression* cond = NULL; | 2200 Expression* cond = NULL; |
| 2565 if (peek() != Token::SEMICOLON) { | 2201 if (peek() != Token::SEMICOLON) { |
| 2566 cond = ParseExpression(true, CHECK_OK); | 2202 cond = ParseExpression(true, CHECK_OK); |
| 2567 if (cond != NULL) cond->set_is_loop_condition(true); | 2203 if (cond != NULL) cond->set_is_loop_condition(true); |
| 2568 } | 2204 } |
| 2569 Expect(Token::SEMICOLON, CHECK_OK); | 2205 Expect(Token::SEMICOLON, CHECK_OK); |
| 2570 | 2206 |
| 2571 Statement* next = NULL; | 2207 Statement* next = NULL; |
| 2572 if (peek() != Token::RPAREN) { | 2208 if (peek() != Token::RPAREN) { |
| 2573 Expression* exp = ParseExpression(true, CHECK_OK); | 2209 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2574 next = NEW(ExpressionStatement(exp)); | 2210 next = new ExpressionStatement(exp); |
| 2575 } | 2211 } |
| 2576 Expect(Token::RPAREN, CHECK_OK); | 2212 Expect(Token::RPAREN, CHECK_OK); |
| 2577 | 2213 |
| 2578 Statement* body = ParseStatement(NULL, CHECK_OK); | 2214 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2579 if (loop) loop->Initialize(init, cond, next, body); | 2215 if (loop) loop->Initialize(init, cond, next, body); |
| 2580 return loop; | 2216 return loop; |
| 2581 } | 2217 } |
| 2582 | 2218 |
| 2583 | 2219 |
| 2584 // Precedence = 1 | 2220 // Precedence = 1 |
| 2585 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2221 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2586 // Expression :: | 2222 // Expression :: |
| 2587 // AssignmentExpression | 2223 // AssignmentExpression |
| 2588 // Expression ',' AssignmentExpression | 2224 // Expression ',' AssignmentExpression |
| 2589 | 2225 |
| 2590 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2226 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2591 while (peek() == Token::COMMA) { | 2227 while (peek() == Token::COMMA) { |
| 2592 Expect(Token::COMMA, CHECK_OK); | 2228 Expect(Token::COMMA, CHECK_OK); |
| 2593 int position = scanner().location().beg_pos; | 2229 int position = scanner().location().beg_pos; |
| 2594 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2230 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2595 result = NEW(BinaryOperation(Token::COMMA, result, right, position)); | 2231 result = new BinaryOperation(Token::COMMA, result, right, position); |
| 2596 } | 2232 } |
| 2597 return result; | 2233 return result; |
| 2598 } | 2234 } |
| 2599 | 2235 |
| 2600 | 2236 |
| 2601 // Precedence = 2 | 2237 // Precedence = 2 |
| 2602 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2238 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2603 // AssignmentExpression :: | 2239 // AssignmentExpression :: |
| 2604 // ConditionalExpression | 2240 // ConditionalExpression |
| 2605 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2241 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2645 // expression. | 2281 // expression. |
| 2646 if ((op == Token::INIT_VAR | 2282 if ((op == Token::INIT_VAR |
| 2647 || op == Token::INIT_CONST | 2283 || op == Token::INIT_CONST |
| 2648 || op == Token::ASSIGN) | 2284 || op == Token::ASSIGN) |
| 2649 && (right->AsCall() == NULL)) { | 2285 && (right->AsCall() == NULL)) { |
| 2650 fni_->Infer(); | 2286 fni_->Infer(); |
| 2651 } | 2287 } |
| 2652 fni_->Leave(); | 2288 fni_->Leave(); |
| 2653 } | 2289 } |
| 2654 | 2290 |
| 2655 return NEW(Assignment(op, expression, right, pos)); | 2291 return new Assignment(op, expression, right, pos); |
| 2656 } | 2292 } |
| 2657 | 2293 |
| 2658 | 2294 |
| 2659 // Precedence = 3 | 2295 // Precedence = 3 |
| 2660 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2296 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 2661 // ConditionalExpression :: | 2297 // ConditionalExpression :: |
| 2662 // LogicalOrExpression | 2298 // LogicalOrExpression |
| 2663 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2299 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2664 | 2300 |
| 2665 // We start using the binary expression parser for prec >= 4 only! | 2301 // We start using the binary expression parser for prec >= 4 only! |
| 2666 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2302 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2667 if (peek() != Token::CONDITIONAL) return expression; | 2303 if (peek() != Token::CONDITIONAL) return expression; |
| 2668 Consume(Token::CONDITIONAL); | 2304 Consume(Token::CONDITIONAL); |
| 2669 // In parsing the first assignment expression in conditional | 2305 // In parsing the first assignment expression in conditional |
| 2670 // expressions we always accept the 'in' keyword; see ECMA-262, | 2306 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2671 // section 11.12, page 58. | 2307 // section 11.12, page 58. |
| 2672 int left_position = scanner().peek_location().beg_pos; | 2308 int left_position = scanner().peek_location().beg_pos; |
| 2673 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 2309 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 2674 Expect(Token::COLON, CHECK_OK); | 2310 Expect(Token::COLON, CHECK_OK); |
| 2675 int right_position = scanner().peek_location().beg_pos; | 2311 int right_position = scanner().peek_location().beg_pos; |
| 2676 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2312 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2677 return NEW(Conditional(expression, left, right, | 2313 return new Conditional(expression, left, right, |
| 2678 left_position, right_position)); | 2314 left_position, right_position); |
| 2679 } | 2315 } |
| 2680 | 2316 |
| 2681 | 2317 |
| 2682 static int Precedence(Token::Value tok, bool accept_IN) { | 2318 static int Precedence(Token::Value tok, bool accept_IN) { |
| 2683 if (tok == Token::IN && !accept_IN) | 2319 if (tok == Token::IN && !accept_IN) |
| 2684 return 0; // 0 precedence will terminate binary expression parsing | 2320 return 0; // 0 precedence will terminate binary expression parsing |
| 2685 | 2321 |
| 2686 return Token::Precedence(tok); | 2322 return Token::Precedence(tok); |
| 2687 } | 2323 } |
| 2688 | 2324 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2775 // We have a comparison. | 2411 // We have a comparison. |
| 2776 Token::Value cmp = op; | 2412 Token::Value cmp = op; |
| 2777 switch (op) { | 2413 switch (op) { |
| 2778 case Token::NE: cmp = Token::EQ; break; | 2414 case Token::NE: cmp = Token::EQ; break; |
| 2779 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | 2415 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; |
| 2780 default: break; | 2416 default: break; |
| 2781 } | 2417 } |
| 2782 x = NewCompareNode(cmp, x, y, position); | 2418 x = NewCompareNode(cmp, x, y, position); |
| 2783 if (cmp != op) { | 2419 if (cmp != op) { |
| 2784 // The comparison was negated - add a NOT. | 2420 // The comparison was negated - add a NOT. |
| 2785 x = NEW(UnaryOperation(Token::NOT, x)); | 2421 x = new UnaryOperation(Token::NOT, x); |
| 2786 } | 2422 } |
| 2787 | 2423 |
| 2788 } else { | 2424 } else { |
| 2789 // We have a "normal" binary operation. | 2425 // We have a "normal" binary operation. |
| 2790 x = NEW(BinaryOperation(op, x, y, position)); | 2426 x = new BinaryOperation(op, x, y, position); |
| 2791 } | 2427 } |
| 2792 } | 2428 } |
| 2793 } | 2429 } |
| 2794 return x; | 2430 return x; |
| 2795 } | 2431 } |
| 2796 | 2432 |
| 2797 | 2433 |
| 2798 Expression* Parser::NewCompareNode(Token::Value op, | 2434 Expression* Parser::NewCompareNode(Token::Value op, |
| 2799 Expression* x, | 2435 Expression* x, |
| 2800 Expression* y, | 2436 Expression* y, |
| 2801 int position) { | 2437 int position) { |
| 2802 ASSERT(op != Token::NE && op != Token::NE_STRICT); | 2438 ASSERT(op != Token::NE && op != Token::NE_STRICT); |
| 2803 if (!is_pre_parsing_ && (op == Token::EQ || op == Token::EQ_STRICT)) { | 2439 if (op == Token::EQ || op == Token::EQ_STRICT) { |
| 2804 bool is_strict = (op == Token::EQ_STRICT); | 2440 bool is_strict = (op == Token::EQ_STRICT); |
| 2805 Literal* x_literal = x->AsLiteral(); | 2441 Literal* x_literal = x->AsLiteral(); |
| 2806 if (x_literal != NULL && x_literal->IsNull()) { | 2442 if (x_literal != NULL && x_literal->IsNull()) { |
| 2807 return NEW(CompareToNull(is_strict, y)); | 2443 return new CompareToNull(is_strict, y); |
| 2808 } | 2444 } |
| 2809 | 2445 |
| 2810 Literal* y_literal = y->AsLiteral(); | 2446 Literal* y_literal = y->AsLiteral(); |
| 2811 if (y_literal != NULL && y_literal->IsNull()) { | 2447 if (y_literal != NULL && y_literal->IsNull()) { |
| 2812 return NEW(CompareToNull(is_strict, x)); | 2448 return new CompareToNull(is_strict, x); |
| 2813 } | 2449 } |
| 2814 } | 2450 } |
| 2815 return NEW(CompareOperation(op, x, y, position)); | 2451 return new CompareOperation(op, x, y, position); |
| 2816 } | 2452 } |
| 2817 | 2453 |
| 2818 | 2454 |
| 2819 Expression* Parser::ParseUnaryExpression(bool* ok) { | 2455 Expression* Parser::ParseUnaryExpression(bool* ok) { |
| 2820 // UnaryExpression :: | 2456 // UnaryExpression :: |
| 2821 // PostfixExpression | 2457 // PostfixExpression |
| 2822 // 'delete' UnaryExpression | 2458 // 'delete' UnaryExpression |
| 2823 // 'void' UnaryExpression | 2459 // 'void' UnaryExpression |
| 2824 // 'typeof' UnaryExpression | 2460 // 'typeof' UnaryExpression |
| 2825 // '++' UnaryExpression | 2461 // '++' UnaryExpression |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2842 case Token::ADD: | 2478 case Token::ADD: |
| 2843 return expression; | 2479 return expression; |
| 2844 case Token::SUB: | 2480 case Token::SUB: |
| 2845 return NewNumberLiteral(-value); | 2481 return NewNumberLiteral(-value); |
| 2846 case Token::BIT_NOT: | 2482 case Token::BIT_NOT: |
| 2847 return NewNumberLiteral(~DoubleToInt32(value)); | 2483 return NewNumberLiteral(~DoubleToInt32(value)); |
| 2848 default: break; | 2484 default: break; |
| 2849 } | 2485 } |
| 2850 } | 2486 } |
| 2851 | 2487 |
| 2852 return NEW(UnaryOperation(op, expression)); | 2488 return new UnaryOperation(op, expression); |
| 2853 | 2489 |
| 2854 } else if (Token::IsCountOp(op)) { | 2490 } else if (Token::IsCountOp(op)) { |
| 2855 op = Next(); | 2491 op = Next(); |
| 2856 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2492 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2857 // Signal a reference error if the expression is an invalid | 2493 // Signal a reference error if the expression is an invalid |
| 2858 // left-hand side expression. We could report this as a syntax | 2494 // left-hand side expression. We could report this as a syntax |
| 2859 // error here but for compatibility with JSC we choose to report the | 2495 // error here but for compatibility with JSC we choose to report the |
| 2860 // error at runtime. | 2496 // error at runtime. |
| 2861 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2497 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2862 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); | 2498 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); |
| 2863 expression = NewThrowReferenceError(type); | 2499 expression = NewThrowReferenceError(type); |
| 2864 } | 2500 } |
| 2865 int position = scanner().location().beg_pos; | 2501 int position = scanner().location().beg_pos; |
| 2866 IncrementOperation* increment = NEW(IncrementOperation(op, expression)); | 2502 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2867 return NEW(CountOperation(true /* prefix */, increment, position)); | 2503 return new CountOperation(true /* prefix */, increment, position); |
| 2868 | 2504 |
| 2869 } else { | 2505 } else { |
| 2870 return ParsePostfixExpression(ok); | 2506 return ParsePostfixExpression(ok); |
| 2871 } | 2507 } |
| 2872 } | 2508 } |
| 2873 | 2509 |
| 2874 | 2510 |
| 2875 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2511 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 2876 // PostfixExpression :: | 2512 // PostfixExpression :: |
| 2877 // LeftHandSideExpression ('++' | '--')? | 2513 // LeftHandSideExpression ('++' | '--')? |
| 2878 | 2514 |
| 2879 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 2515 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 2880 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { | 2516 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { |
| 2881 // Signal a reference error if the expression is an invalid | 2517 // Signal a reference error if the expression is an invalid |
| 2882 // left-hand side expression. We could report this as a syntax | 2518 // left-hand side expression. We could report this as a syntax |
| 2883 // error here but for compatibility with JSC we choose to report the | 2519 // error here but for compatibility with JSC we choose to report the |
| 2884 // error at runtime. | 2520 // error at runtime. |
| 2885 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2521 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2886 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); | 2522 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); |
| 2887 expression = NewThrowReferenceError(type); | 2523 expression = NewThrowReferenceError(type); |
| 2888 } | 2524 } |
| 2889 Token::Value next = Next(); | 2525 Token::Value next = Next(); |
| 2890 int position = scanner().location().beg_pos; | 2526 int position = scanner().location().beg_pos; |
| 2891 IncrementOperation* increment = NEW(IncrementOperation(next, expression)); | 2527 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2892 expression = NEW(CountOperation(false /* postfix */, increment, position)); | 2528 expression = new CountOperation(false /* postfix */, increment, position); |
| 2893 } | 2529 } |
| 2894 return expression; | 2530 return expression; |
| 2895 } | 2531 } |
| 2896 | 2532 |
| 2897 | 2533 |
| 2898 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 2534 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 2899 // LeftHandSideExpression :: | 2535 // LeftHandSideExpression :: |
| 2900 // (NewExpression | MemberExpression) ... | 2536 // (NewExpression | MemberExpression) ... |
| 2901 | 2537 |
| 2902 Expression* result; | 2538 Expression* result; |
| 2903 if (peek() == Token::NEW) { | 2539 if (peek() == Token::NEW) { |
| 2904 result = ParseNewExpression(CHECK_OK); | 2540 result = ParseNewExpression(CHECK_OK); |
| 2905 } else { | 2541 } else { |
| 2906 result = ParseMemberExpression(CHECK_OK); | 2542 result = ParseMemberExpression(CHECK_OK); |
| 2907 } | 2543 } |
| 2908 | 2544 |
| 2909 while (true) { | 2545 while (true) { |
| 2910 switch (peek()) { | 2546 switch (peek()) { |
| 2911 case Token::LBRACK: { | 2547 case Token::LBRACK: { |
| 2912 Consume(Token::LBRACK); | 2548 Consume(Token::LBRACK); |
| 2913 int pos = scanner().location().beg_pos; | 2549 int pos = scanner().location().beg_pos; |
| 2914 Expression* index = ParseExpression(true, CHECK_OK); | 2550 Expression* index = ParseExpression(true, CHECK_OK); |
| 2915 result = factory()->NewProperty(result, index, pos); | 2551 result = new Property(result, index, pos); |
| 2916 Expect(Token::RBRACK, CHECK_OK); | 2552 Expect(Token::RBRACK, CHECK_OK); |
| 2917 break; | 2553 break; |
| 2918 } | 2554 } |
| 2919 | 2555 |
| 2920 case Token::LPAREN: { | 2556 case Token::LPAREN: { |
| 2921 int pos = scanner().location().beg_pos; | 2557 int pos = scanner().location().beg_pos; |
| 2922 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 2558 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 2923 | 2559 |
| 2924 // Keep track of eval() calls since they disable all local variable | 2560 // Keep track of eval() calls since they disable all local variable |
| 2925 // optimizations. | 2561 // optimizations. |
| 2926 // The calls that need special treatment are the | 2562 // The calls that need special treatment are the |
| 2927 // direct (i.e. not aliased) eval calls. These calls are all of the | 2563 // direct (i.e. not aliased) eval calls. These calls are all of the |
| 2928 // form eval(...) with no explicit receiver object where eval is not | 2564 // form eval(...) with no explicit receiver object where eval is not |
| 2929 // declared in the current scope chain. These calls are marked as | 2565 // declared in the current scope chain. These calls are marked as |
| 2930 // potentially direct eval calls. Whether they are actually direct calls | 2566 // potentially direct eval calls. Whether they are actually direct calls |
| 2931 // to eval is determined at run time. | 2567 // to eval is determined at run time. |
| 2932 if (!is_pre_parsing_) { | 2568 VariableProxy* callee = result->AsVariableProxy(); |
| 2933 VariableProxy* callee = result->AsVariableProxy(); | 2569 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { |
| 2934 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { | 2570 Handle<String> name = callee->name(); |
| 2935 Handle<String> name = callee->name(); | 2571 Variable* var = top_scope_->Lookup(name); |
| 2936 Variable* var = top_scope_->Lookup(name); | 2572 if (var == NULL) { |
| 2937 if (var == NULL) { | 2573 top_scope_->RecordEvalCall(); |
| 2938 top_scope_->RecordEvalCall(); | |
| 2939 } | |
| 2940 } | 2574 } |
| 2941 } | 2575 } |
| 2942 result = factory()->NewCall(result, args, pos); | 2576 result = NewCall(result, args, pos); |
| 2943 break; | 2577 break; |
| 2944 } | 2578 } |
| 2945 | 2579 |
| 2946 case Token::PERIOD: { | 2580 case Token::PERIOD: { |
| 2947 Consume(Token::PERIOD); | 2581 Consume(Token::PERIOD); |
| 2948 int pos = scanner().location().beg_pos; | 2582 int pos = scanner().location().beg_pos; |
| 2949 Handle<String> name = ParseIdentifierName(CHECK_OK); | 2583 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 2950 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 2584 result = new Property(result, new Literal(name), pos); |
| 2951 if (fni_ != NULL) fni_->PushLiteralName(name); | 2585 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 2952 break; | 2586 break; |
| 2953 } | 2587 } |
| 2954 | 2588 |
| 2955 default: | 2589 default: |
| 2956 return result; | 2590 return result; |
| 2957 } | 2591 } |
| 2958 } | 2592 } |
| 2959 } | 2593 } |
| 2960 | 2594 |
| 2961 | 2595 |
| 2962 | |
| 2963 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { | 2596 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
| 2964 // NewExpression :: | 2597 // NewExpression :: |
| 2965 // ('new')+ MemberExpression | 2598 // ('new')+ MemberExpression |
| 2966 | 2599 |
| 2967 // The grammar for new expressions is pretty warped. The keyword | 2600 // The grammar for new expressions is pretty warped. The keyword |
| 2968 // 'new' can either be a part of the new expression (where it isn't | 2601 // 'new' can either be a part of the new expression (where it isn't |
| 2969 // followed by an argument list) or a part of the member expression, | 2602 // followed by an argument list) or a part of the member expression, |
| 2970 // where it must be followed by an argument list. To accommodate | 2603 // where it must be followed by an argument list. To accommodate |
| 2971 // this, we parse the 'new' keywords greedily and keep track of how | 2604 // this, we parse the 'new' keywords greedily and keep track of how |
| 2972 // many we have parsed. This information is then passed on to the | 2605 // many we have parsed. This information is then passed on to the |
| 2973 // member expression parser, which is only allowed to match argument | 2606 // member expression parser, which is only allowed to match argument |
| 2974 // lists as long as it has 'new' prefixes left | 2607 // lists as long as it has 'new' prefixes left |
| 2975 Expect(Token::NEW, CHECK_OK); | 2608 Expect(Token::NEW, CHECK_OK); |
| 2976 PositionStack::Element pos(stack, scanner().location().beg_pos); | 2609 PositionStack::Element pos(stack, scanner().location().beg_pos); |
| 2977 | 2610 |
| 2978 Expression* result; | 2611 Expression* result; |
| 2979 if (peek() == Token::NEW) { | 2612 if (peek() == Token::NEW) { |
| 2980 result = ParseNewPrefix(stack, CHECK_OK); | 2613 result = ParseNewPrefix(stack, CHECK_OK); |
| 2981 } else { | 2614 } else { |
| 2982 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); | 2615 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
| 2983 } | 2616 } |
| 2984 | 2617 |
| 2985 if (!stack->is_empty()) { | 2618 if (!stack->is_empty()) { |
| 2986 int last = stack->pop(); | 2619 int last = stack->pop(); |
| 2987 result = NEW(CallNew(result, new ZoneList<Expression*>(0), last)); | 2620 result = new CallNew(result, new ZoneList<Expression*>(0), last); |
| 2988 } | 2621 } |
| 2989 return result; | 2622 return result; |
| 2990 } | 2623 } |
| 2991 | 2624 |
| 2992 | 2625 |
| 2993 Expression* Parser::ParseNewExpression(bool* ok) { | 2626 Expression* Parser::ParseNewExpression(bool* ok) { |
| 2994 PositionStack stack(ok); | 2627 PositionStack stack(ok); |
| 2995 return ParseNewPrefix(&stack, ok); | 2628 return ParseNewPrefix(&stack, ok); |
| 2996 } | 2629 } |
| 2997 | 2630 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3019 } else { | 2652 } else { |
| 3020 result = ParsePrimaryExpression(CHECK_OK); | 2653 result = ParsePrimaryExpression(CHECK_OK); |
| 3021 } | 2654 } |
| 3022 | 2655 |
| 3023 while (true) { | 2656 while (true) { |
| 3024 switch (peek()) { | 2657 switch (peek()) { |
| 3025 case Token::LBRACK: { | 2658 case Token::LBRACK: { |
| 3026 Consume(Token::LBRACK); | 2659 Consume(Token::LBRACK); |
| 3027 int pos = scanner().location().beg_pos; | 2660 int pos = scanner().location().beg_pos; |
| 3028 Expression* index = ParseExpression(true, CHECK_OK); | 2661 Expression* index = ParseExpression(true, CHECK_OK); |
| 3029 result = factory()->NewProperty(result, index, pos); | 2662 result = new Property(result, index, pos); |
| 3030 Expect(Token::RBRACK, CHECK_OK); | 2663 Expect(Token::RBRACK, CHECK_OK); |
| 3031 break; | 2664 break; |
| 3032 } | 2665 } |
| 3033 case Token::PERIOD: { | 2666 case Token::PERIOD: { |
| 3034 Consume(Token::PERIOD); | 2667 Consume(Token::PERIOD); |
| 3035 int pos = scanner().location().beg_pos; | 2668 int pos = scanner().location().beg_pos; |
| 3036 Handle<String> name = ParseIdentifierName(CHECK_OK); | 2669 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3037 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 2670 result = new Property(result, new Literal(name), pos); |
| 3038 if (fni_ != NULL) fni_->PushLiteralName(name); | 2671 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3039 break; | 2672 break; |
| 3040 } | 2673 } |
| 3041 case Token::LPAREN: { | 2674 case Token::LPAREN: { |
| 3042 if ((stack == NULL) || stack->is_empty()) return result; | 2675 if ((stack == NULL) || stack->is_empty()) return result; |
| 3043 // Consume one of the new prefixes (already parsed). | 2676 // Consume one of the new prefixes (already parsed). |
| 3044 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 2677 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3045 int last = stack->pop(); | 2678 int last = stack->pop(); |
| 3046 result = NEW(CallNew(result, args, last)); | 2679 result = new CallNew(result, args, last); |
| 3047 break; | 2680 break; |
| 3048 } | 2681 } |
| 3049 default: | 2682 default: |
| 3050 return result; | 2683 return result; |
| 3051 } | 2684 } |
| 3052 } | 2685 } |
| 3053 } | 2686 } |
| 3054 | 2687 |
| 3055 | 2688 |
| 3056 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 2689 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 3057 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 2690 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 3058 // contexts this is used as a statement which invokes the debugger as i a | 2691 // contexts this is used as a statement which invokes the debugger as i a |
| 3059 // break point is present. | 2692 // break point is present. |
| 3060 // DebuggerStatement :: | 2693 // DebuggerStatement :: |
| 3061 // 'debugger' ';' | 2694 // 'debugger' ';' |
| 3062 | 2695 |
| 3063 Expect(Token::DEBUGGER, CHECK_OK); | 2696 Expect(Token::DEBUGGER, CHECK_OK); |
| 3064 ExpectSemicolon(CHECK_OK); | 2697 ExpectSemicolon(CHECK_OK); |
| 3065 return NEW(DebuggerStatement()); | 2698 return new DebuggerStatement(); |
| 3066 } | 2699 } |
| 3067 | 2700 |
| 3068 | 2701 |
| 3069 void Parser::ReportUnexpectedToken(Token::Value token) { | 2702 void Parser::ReportUnexpectedToken(Token::Value token) { |
| 3070 // We don't report stack overflows here, to avoid increasing the | 2703 // We don't report stack overflows here, to avoid increasing the |
| 3071 // stack depth even further. Instead we report it after parsing is | 2704 // stack depth even further. Instead we report it after parsing is |
| 3072 // over, in ParseProgram/ParseJson. | 2705 // over, in ParseProgram/ParseJson. |
| 3073 if (token == Token::ILLEGAL && scanner().stack_overflow()) | 2706 if (token == Token::ILLEGAL && scanner().stack_overflow()) |
| 3074 return; | 2707 return; |
| 3075 // Four of the tokens are treated specially | 2708 // Four of the tokens are treated specially |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3113 // String | 2746 // String |
| 3114 // ArrayLiteral | 2747 // ArrayLiteral |
| 3115 // ObjectLiteral | 2748 // ObjectLiteral |
| 3116 // RegExpLiteral | 2749 // RegExpLiteral |
| 3117 // '(' Expression ')' | 2750 // '(' Expression ')' |
| 3118 | 2751 |
| 3119 Expression* result = NULL; | 2752 Expression* result = NULL; |
| 3120 switch (peek()) { | 2753 switch (peek()) { |
| 3121 case Token::THIS: { | 2754 case Token::THIS: { |
| 3122 Consume(Token::THIS); | 2755 Consume(Token::THIS); |
| 3123 if (is_pre_parsing_) { | 2756 VariableProxy* recv = top_scope_->receiver(); |
| 3124 result = VariableProxySentinel::this_proxy(); | 2757 result = recv; |
| 3125 } else { | |
| 3126 VariableProxy* recv = top_scope_->receiver(); | |
| 3127 result = recv; | |
| 3128 } | |
| 3129 break; | 2758 break; |
| 3130 } | 2759 } |
| 3131 | 2760 |
| 3132 case Token::NULL_LITERAL: | 2761 case Token::NULL_LITERAL: |
| 3133 Consume(Token::NULL_LITERAL); | 2762 Consume(Token::NULL_LITERAL); |
| 3134 result = NEW(Literal(Factory::null_value())); | 2763 result = new Literal(Factory::null_value()); |
| 3135 break; | 2764 break; |
| 3136 | 2765 |
| 3137 case Token::TRUE_LITERAL: | 2766 case Token::TRUE_LITERAL: |
| 3138 Consume(Token::TRUE_LITERAL); | 2767 Consume(Token::TRUE_LITERAL); |
| 3139 result = NEW(Literal(Factory::true_value())); | 2768 result = new Literal(Factory::true_value()); |
| 3140 break; | 2769 break; |
| 3141 | 2770 |
| 3142 case Token::FALSE_LITERAL: | 2771 case Token::FALSE_LITERAL: |
| 3143 Consume(Token::FALSE_LITERAL); | 2772 Consume(Token::FALSE_LITERAL); |
| 3144 result = NEW(Literal(Factory::false_value())); | 2773 result = new Literal(Factory::false_value()); |
| 3145 break; | 2774 break; |
| 3146 | 2775 |
| 3147 case Token::IDENTIFIER: { | 2776 case Token::IDENTIFIER: { |
| 3148 Handle<String> name = ParseIdentifier(CHECK_OK); | 2777 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3149 if (fni_ != NULL) fni_->PushVariableName(name); | 2778 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3150 if (is_pre_parsing_) { | 2779 result = top_scope_->NewUnresolved(name, inside_with()); |
| 3151 result = VariableProxySentinel::identifier_proxy(); | |
| 3152 } else { | |
| 3153 result = top_scope_->NewUnresolved(name, inside_with()); | |
| 3154 } | |
| 3155 break; | 2780 break; |
| 3156 } | 2781 } |
| 3157 | 2782 |
| 3158 case Token::NUMBER: { | 2783 case Token::NUMBER: { |
| 3159 Consume(Token::NUMBER); | 2784 Consume(Token::NUMBER); |
| 3160 double value = | 2785 double value = |
| 3161 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 2786 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); |
| 3162 result = NewNumberLiteral(value); | 2787 result = NewNumberLiteral(value); |
| 3163 break; | 2788 break; |
| 3164 } | 2789 } |
| 3165 | 2790 |
| 3166 case Token::STRING: { | 2791 case Token::STRING: { |
| 3167 Consume(Token::STRING); | 2792 Consume(Token::STRING); |
| 3168 Handle<String> symbol = GetSymbol(CHECK_OK); | 2793 Handle<String> symbol = GetSymbol(CHECK_OK); |
| 3169 result = NEW(Literal(symbol)); | 2794 result = new Literal(symbol); |
| 3170 if (fni_ != NULL) fni_->PushLiteralName(symbol); | 2795 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 3171 break; | 2796 break; |
| 3172 } | 2797 } |
| 3173 | 2798 |
| 3174 case Token::ASSIGN_DIV: | 2799 case Token::ASSIGN_DIV: |
| 3175 result = ParseRegExpLiteral(true, CHECK_OK); | 2800 result = ParseRegExpLiteral(true, CHECK_OK); |
| 3176 break; | 2801 break; |
| 3177 | 2802 |
| 3178 case Token::DIV: | 2803 case Token::DIV: |
| 3179 result = ParseRegExpLiteral(false, CHECK_OK); | 2804 result = ParseRegExpLiteral(false, CHECK_OK); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3237 | 2862 |
| 3238 *is_simple = is_simple_acc; | 2863 *is_simple = is_simple_acc; |
| 3239 *depth = depth_acc; | 2864 *depth = depth_acc; |
| 3240 } | 2865 } |
| 3241 | 2866 |
| 3242 | 2867 |
| 3243 Expression* Parser::ParseArrayLiteral(bool* ok) { | 2868 Expression* Parser::ParseArrayLiteral(bool* ok) { |
| 3244 // ArrayLiteral :: | 2869 // ArrayLiteral :: |
| 3245 // '[' Expression? (',' Expression?)* ']' | 2870 // '[' Expression? (',' Expression?)* ']' |
| 3246 | 2871 |
| 3247 ZoneListWrapper<Expression> values = factory()->NewList<Expression>(4); | 2872 ZoneList<Expression*>* values = new ZoneList<Expression*>(4); |
| 3248 Expect(Token::LBRACK, CHECK_OK); | 2873 Expect(Token::LBRACK, CHECK_OK); |
| 3249 while (peek() != Token::RBRACK) { | 2874 while (peek() != Token::RBRACK) { |
| 3250 Expression* elem; | 2875 Expression* elem; |
| 3251 if (peek() == Token::COMMA) { | 2876 if (peek() == Token::COMMA) { |
| 3252 elem = GetLiteralTheHole(); | 2877 elem = GetLiteralTheHole(); |
| 3253 } else { | 2878 } else { |
| 3254 elem = ParseAssignmentExpression(true, CHECK_OK); | 2879 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3255 } | 2880 } |
| 3256 values.Add(elem); | 2881 values->Add(elem); |
| 3257 if (peek() != Token::RBRACK) { | 2882 if (peek() != Token::RBRACK) { |
| 3258 Expect(Token::COMMA, CHECK_OK); | 2883 Expect(Token::COMMA, CHECK_OK); |
| 3259 } | 2884 } |
| 3260 } | 2885 } |
| 3261 Expect(Token::RBRACK, CHECK_OK); | 2886 Expect(Token::RBRACK, CHECK_OK); |
| 3262 | 2887 |
| 3263 // Update the scope information before the pre-parsing bailout. | 2888 // Update the scope information before the pre-parsing bailout. |
| 3264 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 2889 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
| 3265 | 2890 |
| 3266 if (is_pre_parsing_) return NULL; | |
| 3267 | |
| 3268 // Allocate a fixed array with all the literals. | 2891 // Allocate a fixed array with all the literals. |
| 3269 Handle<FixedArray> literals = | 2892 Handle<FixedArray> literals = |
| 3270 Factory::NewFixedArray(values.length(), TENURED); | 2893 Factory::NewFixedArray(values->length(), TENURED); |
| 3271 | 2894 |
| 3272 // Fill in the literals. | 2895 // Fill in the literals. |
| 3273 bool is_simple = true; | 2896 bool is_simple = true; |
| 3274 int depth = 1; | 2897 int depth = 1; |
| 3275 for (int i = 0; i < values.length(); i++) { | 2898 for (int i = 0, n = values->length(); i < n; i++) { |
| 3276 MaterializedLiteral* m_literal = values.at(i)->AsMaterializedLiteral(); | 2899 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); |
| 3277 if (m_literal != NULL && m_literal->depth() + 1 > depth) { | 2900 if (m_literal != NULL && m_literal->depth() + 1 > depth) { |
| 3278 depth = m_literal->depth() + 1; | 2901 depth = m_literal->depth() + 1; |
| 3279 } | 2902 } |
| 3280 Handle<Object> boilerplate_value = GetBoilerplateValue(values.at(i)); | 2903 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); |
| 3281 if (boilerplate_value->IsUndefined()) { | 2904 if (boilerplate_value->IsUndefined()) { |
| 3282 literals->set_the_hole(i); | 2905 literals->set_the_hole(i); |
| 3283 is_simple = false; | 2906 is_simple = false; |
| 3284 } else { | 2907 } else { |
| 3285 literals->set(i, *boilerplate_value); | 2908 literals->set(i, *boilerplate_value); |
| 3286 } | 2909 } |
| 3287 } | 2910 } |
| 3288 | 2911 |
| 3289 // Simple and shallow arrays can be lazily copied, we transform the | 2912 // Simple and shallow arrays can be lazily copied, we transform the |
| 3290 // elements array to a copy-on-write array. | 2913 // elements array to a copy-on-write array. |
| 3291 if (is_simple && depth == 1 && values.length() > 0) { | 2914 if (is_simple && depth == 1 && values->length() > 0) { |
| 3292 literals->set_map(Heap::fixed_cow_array_map()); | 2915 literals->set_map(Heap::fixed_cow_array_map()); |
| 3293 } | 2916 } |
| 3294 | 2917 |
| 3295 return NEW(ArrayLiteral(literals, values.elements(), | 2918 return new ArrayLiteral(literals, values, |
| 3296 literal_index, is_simple, depth)); | 2919 literal_index, is_simple, depth); |
| 3297 } | 2920 } |
| 3298 | 2921 |
| 3299 | 2922 |
| 3300 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 2923 bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 3301 return property != NULL && | 2924 return property != NULL && |
| 3302 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 2925 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 3303 } | 2926 } |
| 3304 | 2927 |
| 3305 | 2928 |
| 3306 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 2929 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3433 Token::Value next = Next(); | 3056 Token::Value next = Next(); |
| 3434 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). | 3057 // TODO(820): Allow NUMBER and STRING as well (and handle array indices). |
| 3435 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { | 3058 if (next == Token::IDENTIFIER || Token::IsKeyword(next)) { |
| 3436 Handle<String> name = GetSymbol(CHECK_OK); | 3059 Handle<String> name = GetSymbol(CHECK_OK); |
| 3437 FunctionLiteral* value = | 3060 FunctionLiteral* value = |
| 3438 ParseFunctionLiteral(name, | 3061 ParseFunctionLiteral(name, |
| 3439 RelocInfo::kNoPosition, | 3062 RelocInfo::kNoPosition, |
| 3440 DECLARATION, | 3063 DECLARATION, |
| 3441 CHECK_OK); | 3064 CHECK_OK); |
| 3442 ObjectLiteral::Property* property = | 3065 ObjectLiteral::Property* property = |
| 3443 NEW(ObjectLiteral::Property(is_getter, value)); | 3066 new ObjectLiteral::Property(is_getter, value); |
| 3444 return property; | 3067 return property; |
| 3445 } else { | 3068 } else { |
| 3446 ReportUnexpectedToken(next); | 3069 ReportUnexpectedToken(next); |
| 3447 *ok = false; | 3070 *ok = false; |
| 3448 return NULL; | 3071 return NULL; |
| 3449 } | 3072 } |
| 3450 } | 3073 } |
| 3451 | 3074 |
| 3452 | 3075 |
| 3453 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3076 Expression* Parser::ParseObjectLiteral(bool* ok) { |
| 3454 // ObjectLiteral :: | 3077 // ObjectLiteral :: |
| 3455 // '{' ( | 3078 // '{' ( |
| 3456 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3079 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3457 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3080 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3458 // )*[','] '}' | 3081 // )*[','] '}' |
| 3459 | 3082 |
| 3460 ZoneListWrapper<ObjectLiteral::Property> properties = | 3083 ZoneList<ObjectLiteral::Property*>* properties = |
| 3461 factory()->NewList<ObjectLiteral::Property>(4); | 3084 new ZoneList<ObjectLiteral::Property*>(4); |
| 3462 int number_of_boilerplate_properties = 0; | 3085 int number_of_boilerplate_properties = 0; |
| 3463 | 3086 |
| 3464 Expect(Token::LBRACE, CHECK_OK); | 3087 Expect(Token::LBRACE, CHECK_OK); |
| 3465 while (peek() != Token::RBRACE) { | 3088 while (peek() != Token::RBRACE) { |
| 3466 if (fni_ != NULL) fni_->Enter(); | 3089 if (fni_ != NULL) fni_->Enter(); |
| 3467 | 3090 |
| 3468 Literal* key = NULL; | 3091 Literal* key = NULL; |
| 3469 Token::Value next = peek(); | 3092 Token::Value next = peek(); |
| 3470 switch (next) { | 3093 switch (next) { |
| 3471 case Token::IDENTIFIER: { | 3094 case Token::IDENTIFIER: { |
| 3472 bool is_getter = false; | 3095 bool is_getter = false; |
| 3473 bool is_setter = false; | 3096 bool is_setter = false; |
| 3474 Handle<String> id = | 3097 Handle<String> id = |
| 3475 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3098 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3476 if (fni_ != NULL) fni_->PushLiteralName(id); | 3099 if (fni_ != NULL) fni_->PushLiteralName(id); |
| 3477 | 3100 |
| 3478 if ((is_getter || is_setter) && peek() != Token::COLON) { | 3101 if ((is_getter || is_setter) && peek() != Token::COLON) { |
| 3479 ObjectLiteral::Property* property = | 3102 ObjectLiteral::Property* property = |
| 3480 ParseObjectLiteralGetSet(is_getter, CHECK_OK); | 3103 ParseObjectLiteralGetSet(is_getter, CHECK_OK); |
| 3481 if (IsBoilerplateProperty(property)) { | 3104 if (IsBoilerplateProperty(property)) { |
| 3482 number_of_boilerplate_properties++; | 3105 number_of_boilerplate_properties++; |
| 3483 } | 3106 } |
| 3484 properties.Add(property); | 3107 properties->Add(property); |
| 3485 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3108 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3486 | 3109 |
| 3487 if (fni_ != NULL) { | 3110 if (fni_ != NULL) { |
| 3488 fni_->Infer(); | 3111 fni_->Infer(); |
| 3489 fni_->Leave(); | 3112 fni_->Leave(); |
| 3490 } | 3113 } |
| 3491 continue; // restart the while | 3114 continue; // restart the while |
| 3492 } | 3115 } |
| 3493 // Failed to parse as get/set property, so it's just a property | 3116 // Failed to parse as get/set property, so it's just a property |
| 3494 // called "get" or "set". | 3117 // called "get" or "set". |
| 3495 key = NEW(Literal(id)); | 3118 key = new Literal(id); |
| 3496 break; | 3119 break; |
| 3497 } | 3120 } |
| 3498 case Token::STRING: { | 3121 case Token::STRING: { |
| 3499 Consume(Token::STRING); | 3122 Consume(Token::STRING); |
| 3500 Handle<String> string = GetSymbol(CHECK_OK); | 3123 Handle<String> string = GetSymbol(CHECK_OK); |
| 3501 if (fni_ != NULL) fni_->PushLiteralName(string); | 3124 if (fni_ != NULL) fni_->PushLiteralName(string); |
| 3502 uint32_t index; | 3125 uint32_t index; |
| 3503 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3126 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3504 key = NewNumberLiteral(index); | 3127 key = NewNumberLiteral(index); |
| 3505 break; | 3128 break; |
| 3506 } | 3129 } |
| 3507 key = NEW(Literal(string)); | 3130 key = new Literal(string); |
| 3508 break; | 3131 break; |
| 3509 } | 3132 } |
| 3510 case Token::NUMBER: { | 3133 case Token::NUMBER: { |
| 3511 Consume(Token::NUMBER); | 3134 Consume(Token::NUMBER); |
| 3512 double value = | 3135 double value = |
| 3513 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); | 3136 StringToDouble(scanner_.literal(), ALLOW_HEX | ALLOW_OCTALS); |
| 3514 key = NewNumberLiteral(value); | 3137 key = NewNumberLiteral(value); |
| 3515 break; | 3138 break; |
| 3516 } | 3139 } |
| 3517 default: | 3140 default: |
| 3518 if (Token::IsKeyword(next)) { | 3141 if (Token::IsKeyword(next)) { |
| 3519 Consume(next); | 3142 Consume(next); |
| 3520 Handle<String> string = GetSymbol(CHECK_OK); | 3143 Handle<String> string = GetSymbol(CHECK_OK); |
| 3521 key = NEW(Literal(string)); | 3144 key = new Literal(string); |
| 3522 } else { | 3145 } else { |
| 3523 // Unexpected token. | 3146 // Unexpected token. |
| 3524 Token::Value next = Next(); | 3147 Token::Value next = Next(); |
| 3525 ReportUnexpectedToken(next); | 3148 ReportUnexpectedToken(next); |
| 3526 *ok = false; | 3149 *ok = false; |
| 3527 return NULL; | 3150 return NULL; |
| 3528 } | 3151 } |
| 3529 } | 3152 } |
| 3530 | 3153 |
| 3531 Expect(Token::COLON, CHECK_OK); | 3154 Expect(Token::COLON, CHECK_OK); |
| 3532 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3155 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 3533 | 3156 |
| 3534 ObjectLiteral::Property* property = | 3157 ObjectLiteral::Property* property = |
| 3535 NEW(ObjectLiteral::Property(key, value)); | 3158 new ObjectLiteral::Property(key, value); |
| 3536 | 3159 |
| 3537 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3160 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 3538 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3161 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
| 3539 properties.Add(property); | 3162 properties->Add(property); |
| 3540 | 3163 |
| 3541 // TODO(1240767): Consider allowing trailing comma. | 3164 // TODO(1240767): Consider allowing trailing comma. |
| 3542 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3165 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3543 | 3166 |
| 3544 if (fni_ != NULL) { | 3167 if (fni_ != NULL) { |
| 3545 fni_->Infer(); | 3168 fni_->Infer(); |
| 3546 fni_->Leave(); | 3169 fni_->Leave(); |
| 3547 } | 3170 } |
| 3548 } | 3171 } |
| 3549 Expect(Token::RBRACE, CHECK_OK); | 3172 Expect(Token::RBRACE, CHECK_OK); |
| 3550 // Computation of literal_index must happen before pre parse bailout. | 3173 // Computation of literal_index must happen before pre parse bailout. |
| 3551 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3174 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
| 3552 if (is_pre_parsing_) return NULL; | |
| 3553 | 3175 |
| 3554 Handle<FixedArray> constant_properties = | 3176 Handle<FixedArray> constant_properties = |
| 3555 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); | 3177 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); |
| 3556 | 3178 |
| 3557 bool is_simple = true; | 3179 bool is_simple = true; |
| 3558 bool fast_elements = true; | 3180 bool fast_elements = true; |
| 3559 int depth = 1; | 3181 int depth = 1; |
| 3560 BuildObjectLiteralConstantProperties(properties.elements(), | 3182 BuildObjectLiteralConstantProperties(properties, |
| 3561 constant_properties, | 3183 constant_properties, |
| 3562 &is_simple, | 3184 &is_simple, |
| 3563 &fast_elements, | 3185 &fast_elements, |
| 3564 &depth); | 3186 &depth); |
| 3565 return new ObjectLiteral(constant_properties, | 3187 return new ObjectLiteral(constant_properties, |
| 3566 properties.elements(), | 3188 properties, |
| 3567 literal_index, | 3189 literal_index, |
| 3568 is_simple, | 3190 is_simple, |
| 3569 fast_elements, | 3191 fast_elements, |
| 3570 depth); | 3192 depth); |
| 3571 } | 3193 } |
| 3572 | 3194 |
| 3573 | 3195 |
| 3574 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { | 3196 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3575 if (!scanner_.ScanRegExpPattern(seen_equal)) { | 3197 if (!scanner_.ScanRegExpPattern(seen_equal)) { |
| 3576 Next(); | 3198 Next(); |
| 3577 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); | 3199 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3578 *ok = false; | 3200 *ok = false; |
| 3579 return NULL; | 3201 return NULL; |
| 3580 } | 3202 } |
| 3581 | 3203 |
| 3582 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); | 3204 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); |
| 3583 | 3205 |
| 3584 if (is_pre_parsing_) { | |
| 3585 // If we're preparsing we just do all the parsing stuff without | |
| 3586 // building anything. | |
| 3587 if (!scanner_.ScanRegExpFlags()) { | |
| 3588 Next(); | |
| 3589 ReportMessage("invalid_regexp_flags", Vector<const char*>::empty()); | |
| 3590 *ok = false; | |
| 3591 return NULL; | |
| 3592 } | |
| 3593 Next(); | |
| 3594 return NULL; | |
| 3595 } | |
| 3596 | |
| 3597 Handle<String> js_pattern = | 3206 Handle<String> js_pattern = |
| 3598 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3207 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); |
| 3599 scanner_.ScanRegExpFlags(); | 3208 scanner_.ScanRegExpFlags(); |
| 3600 Handle<String> js_flags = | 3209 Handle<String> js_flags = |
| 3601 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); | 3210 Factory::NewStringFromUtf8(scanner_.next_literal(), TENURED); |
| 3602 Next(); | 3211 Next(); |
| 3603 | 3212 |
| 3604 return new RegExpLiteral(js_pattern, js_flags, literal_index); | 3213 return new RegExpLiteral(js_pattern, js_flags, literal_index); |
| 3605 } | 3214 } |
| 3606 | 3215 |
| 3607 | 3216 |
| 3608 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3217 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3609 // Arguments :: | 3218 // Arguments :: |
| 3610 // '(' (AssignmentExpression)*[','] ')' | 3219 // '(' (AssignmentExpression)*[','] ')' |
| 3611 | 3220 |
| 3612 ZoneListWrapper<Expression> result = factory()->NewList<Expression>(4); | 3221 ZoneList<Expression*>* result = new ZoneList<Expression*>(4); |
| 3613 Expect(Token::LPAREN, CHECK_OK); | 3222 Expect(Token::LPAREN, CHECK_OK); |
| 3614 bool done = (peek() == Token::RPAREN); | 3223 bool done = (peek() == Token::RPAREN); |
| 3615 while (!done) { | 3224 while (!done) { |
| 3616 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | 3225 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); |
| 3617 result.Add(argument); | 3226 result->Add(argument); |
| 3618 done = (peek() == Token::RPAREN); | 3227 done = (peek() == Token::RPAREN); |
| 3619 if (!done) Expect(Token::COMMA, CHECK_OK); | 3228 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3620 } | 3229 } |
| 3621 Expect(Token::RPAREN, CHECK_OK); | 3230 Expect(Token::RPAREN, CHECK_OK); |
| 3622 return result.elements(); | 3231 return result; |
| 3623 } | 3232 } |
| 3624 | 3233 |
| 3625 | 3234 |
| 3626 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, | 3235 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, |
| 3627 int function_token_position, | 3236 int function_token_position, |
| 3628 FunctionLiteralType type, | 3237 FunctionLiteralType type, |
| 3629 bool* ok) { | 3238 bool* ok) { |
| 3630 // Function :: | 3239 // Function :: |
| 3631 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3240 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 3632 bool is_named = !var_name.is_null(); | 3241 bool is_named = !var_name.is_null(); |
| 3633 | 3242 |
| 3634 // The name associated with this function. If it's a function expression, | 3243 // The name associated with this function. If it's a function expression, |
| 3635 // this is the actual function name, otherwise this is the name of the | 3244 // this is the actual function name, otherwise this is the name of the |
| 3636 // variable declared and initialized with the function (expression). In | 3245 // variable declared and initialized with the function (expression). In |
| 3637 // that case, we don't have a function name (it's empty). | 3246 // that case, we don't have a function name (it's empty). |
| 3638 Handle<String> name = is_named ? var_name : factory()->EmptySymbol(); | 3247 Handle<String> name = is_named ? var_name : Factory::empty_symbol(); |
| 3639 // The function name, if any. | 3248 // The function name, if any. |
| 3640 Handle<String> function_name = factory()->EmptySymbol(); | 3249 Handle<String> function_name = Factory::empty_symbol(); |
| 3641 if (is_named && (type == EXPRESSION || type == NESTED)) { | 3250 if (is_named && (type == EXPRESSION || type == NESTED)) { |
| 3642 function_name = name; | 3251 function_name = name; |
| 3643 } | 3252 } |
| 3644 | 3253 |
| 3645 int num_parameters = 0; | 3254 int num_parameters = 0; |
| 3646 // Parse function body. | 3255 // Parse function body. |
| 3647 { Scope* scope = | 3256 { Scope* scope = |
| 3648 factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3257 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3649 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 3258 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 3650 scope); | 3259 scope); |
| 3651 TemporaryScope temp_scope(&this->temp_scope_); | 3260 TemporaryScope temp_scope(&this->temp_scope_); |
| 3652 top_scope_->SetScopeName(name); | 3261 top_scope_->SetScopeName(name); |
| 3653 | 3262 |
| 3654 // FormalParameterList :: | 3263 // FormalParameterList :: |
| 3655 // '(' (Identifier)*[','] ')' | 3264 // '(' (Identifier)*[','] ')' |
| 3656 Expect(Token::LPAREN, CHECK_OK); | 3265 Expect(Token::LPAREN, CHECK_OK); |
| 3657 int start_pos = scanner_.location().beg_pos; | 3266 int start_pos = scanner_.location().beg_pos; |
| 3658 bool done = (peek() == Token::RPAREN); | 3267 bool done = (peek() == Token::RPAREN); |
| 3659 while (!done) { | 3268 while (!done) { |
| 3660 Handle<String> param_name = ParseIdentifier(CHECK_OK); | 3269 Handle<String> param_name = ParseIdentifier(CHECK_OK); |
| 3661 if (!is_pre_parsing_) { | 3270 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, |
| 3662 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, | 3271 Variable::VAR)); |
| 3663 Variable::VAR)); | 3272 num_parameters++; |
| 3664 num_parameters++; | |
| 3665 } | |
| 3666 done = (peek() == Token::RPAREN); | 3273 done = (peek() == Token::RPAREN); |
| 3667 if (!done) Expect(Token::COMMA, CHECK_OK); | 3274 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3668 } | 3275 } |
| 3669 Expect(Token::RPAREN, CHECK_OK); | 3276 Expect(Token::RPAREN, CHECK_OK); |
| 3670 | 3277 |
| 3671 Expect(Token::LBRACE, CHECK_OK); | 3278 Expect(Token::LBRACE, CHECK_OK); |
| 3672 ZoneListWrapper<Statement> body = factory()->NewList<Statement>(8); | 3279 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); |
| 3673 | 3280 |
| 3674 // If we have a named function expression, we add a local variable | 3281 // If we have a named function expression, we add a local variable |
| 3675 // declaration to the body of the function with the name of the | 3282 // declaration to the body of the function with the name of the |
| 3676 // function and let it refer to the function itself (closure). | 3283 // function and let it refer to the function itself (closure). |
| 3677 // NOTE: We create a proxy and resolve it here so that in the | 3284 // NOTE: We create a proxy and resolve it here so that in the |
| 3678 // future we can change the AST to only refer to VariableProxies | 3285 // future we can change the AST to only refer to VariableProxies |
| 3679 // instead of Variables and Proxis as is the case now. | 3286 // instead of Variables and Proxis as is the case now. |
| 3680 if (!is_pre_parsing_ | 3287 if (!function_name.is_null() && function_name->length() > 0) { |
| 3681 && !function_name.is_null() | |
| 3682 && function_name->length() > 0) { | |
| 3683 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); | 3288 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); |
| 3684 VariableProxy* fproxy = | 3289 VariableProxy* fproxy = |
| 3685 top_scope_->NewUnresolved(function_name, inside_with()); | 3290 top_scope_->NewUnresolved(function_name, inside_with()); |
| 3686 fproxy->BindTo(fvar); | 3291 fproxy->BindTo(fvar); |
| 3687 body.Add(new ExpressionStatement( | 3292 body->Add(new ExpressionStatement( |
| 3688 new Assignment(Token::INIT_CONST, fproxy, | 3293 new Assignment(Token::INIT_CONST, fproxy, |
| 3689 NEW(ThisFunction()), | 3294 new ThisFunction(), |
| 3690 RelocInfo::kNoPosition))); | 3295 RelocInfo::kNoPosition))); |
| 3691 } | 3296 } |
| 3692 | 3297 |
| 3693 // Determine if the function will be lazily compiled. The mode can | 3298 // Determine if the function will be lazily compiled. The mode can |
| 3694 // only be PARSE_LAZILY if the --lazy flag is true. | 3299 // only be PARSE_LAZILY if the --lazy flag is true. |
| 3695 bool is_lazily_compiled = | 3300 bool is_lazily_compiled = |
| 3696 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); | 3301 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); |
| 3697 | 3302 |
| 3698 int function_block_pos = scanner_.location().beg_pos; | 3303 int function_block_pos = scanner_.location().beg_pos; |
| 3699 int materialized_literal_count; | 3304 int materialized_literal_count; |
| 3700 int expected_property_count; | 3305 int expected_property_count; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3712 ReportInvalidPreparseData(name, CHECK_OK); | 3317 ReportInvalidPreparseData(name, CHECK_OK); |
| 3713 } | 3318 } |
| 3714 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); | 3319 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
| 3715 scanner_.SeekForward(end_pos); | 3320 scanner_.SeekForward(end_pos); |
| 3716 materialized_literal_count = entry.literal_count(); | 3321 materialized_literal_count = entry.literal_count(); |
| 3717 expected_property_count = entry.property_count(); | 3322 expected_property_count = entry.property_count(); |
| 3718 only_simple_this_property_assignments = false; | 3323 only_simple_this_property_assignments = false; |
| 3719 this_property_assignments = Factory::empty_fixed_array(); | 3324 this_property_assignments = Factory::empty_fixed_array(); |
| 3720 Expect(Token::RBRACE, CHECK_OK); | 3325 Expect(Token::RBRACE, CHECK_OK); |
| 3721 } else { | 3326 } else { |
| 3722 FunctionEntry entry; | 3327 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 3723 if (is_lazily_compiled) entry = log()->LogFunction(function_block_pos); | 3328 |
| 3724 { | |
| 3725 ConditionalLogPauseScope pause_if(is_lazily_compiled, log()); | |
| 3726 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | |
| 3727 } | |
| 3728 materialized_literal_count = temp_scope.materialized_literal_count(); | 3329 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3729 expected_property_count = temp_scope.expected_property_count(); | 3330 expected_property_count = temp_scope.expected_property_count(); |
| 3730 only_simple_this_property_assignments = | 3331 only_simple_this_property_assignments = |
| 3731 temp_scope.only_simple_this_property_assignments(); | 3332 temp_scope.only_simple_this_property_assignments(); |
| 3732 this_property_assignments = temp_scope.this_property_assignments(); | 3333 this_property_assignments = temp_scope.this_property_assignments(); |
| 3733 | 3334 |
| 3734 Expect(Token::RBRACE, CHECK_OK); | 3335 Expect(Token::RBRACE, CHECK_OK); |
| 3735 end_pos = scanner_.location().end_pos; | 3336 end_pos = scanner_.location().end_pos; |
| 3736 if (entry.is_valid()) { | |
| 3737 ASSERT(is_lazily_compiled); | |
| 3738 ASSERT(is_pre_parsing_); | |
| 3739 entry.set_end_pos(end_pos); | |
| 3740 entry.set_literal_count(materialized_literal_count); | |
| 3741 entry.set_property_count(expected_property_count); | |
| 3742 } | |
| 3743 } | 3337 } |
| 3744 | 3338 |
| 3745 FunctionLiteral* function_literal = | 3339 FunctionLiteral* function_literal = |
| 3746 NEW(FunctionLiteral(name, | 3340 new FunctionLiteral(name, |
| 3747 top_scope_, | 3341 top_scope_, |
| 3748 body.elements(), | 3342 body, |
| 3749 materialized_literal_count, | 3343 materialized_literal_count, |
| 3750 expected_property_count, | 3344 expected_property_count, |
| 3751 only_simple_this_property_assignments, | 3345 only_simple_this_property_assignments, |
| 3752 this_property_assignments, | 3346 this_property_assignments, |
| 3753 num_parameters, | 3347 num_parameters, |
| 3754 start_pos, | 3348 start_pos, |
| 3755 end_pos, | 3349 end_pos, |
| 3756 function_name->length() > 0, | 3350 function_name->length() > 0, |
| 3757 temp_scope.ContainsLoops())); | 3351 temp_scope.ContainsLoops()); |
| 3758 if (!is_pre_parsing_) { | 3352 function_literal->set_function_token_position(function_token_position); |
| 3759 function_literal->set_function_token_position(function_token_position); | |
| 3760 } | |
| 3761 | 3353 |
| 3762 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3354 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3763 return function_literal; | 3355 return function_literal; |
| 3764 } | 3356 } |
| 3765 } | 3357 } |
| 3766 | 3358 |
| 3767 | 3359 |
| 3768 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3360 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3769 // CallRuntime :: | 3361 // CallRuntime :: |
| 3770 // '%' Identifier Arguments | 3362 // '%' Identifier Arguments |
| 3771 | 3363 |
| 3772 Expect(Token::MOD, CHECK_OK); | 3364 Expect(Token::MOD, CHECK_OK); |
| 3773 Handle<String> name = ParseIdentifier(CHECK_OK); | 3365 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 3774 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3366 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3775 if (is_pre_parsing_) return NULL; | |
| 3776 | 3367 |
| 3777 if (extension_ != NULL) { | 3368 if (extension_ != NULL) { |
| 3778 // The extension structures are only accessible while parsing the | 3369 // The extension structures are only accessible while parsing the |
| 3779 // very first time not when reparsing because of lazy compilation. | 3370 // very first time not when reparsing because of lazy compilation. |
| 3780 top_scope_->ForceEagerCompilation(); | 3371 top_scope_->ForceEagerCompilation(); |
| 3781 } | 3372 } |
| 3782 | 3373 |
| 3783 Runtime::Function* function = Runtime::FunctionForSymbol(name); | 3374 Runtime::Function* function = Runtime::FunctionForSymbol(name); |
| 3784 | 3375 |
| 3785 // Check for built-in IS_VAR macro. | 3376 // Check for built-in IS_VAR macro. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3801 // Check that the expected number of arguments are being passed. | 3392 // Check that the expected number of arguments are being passed. |
| 3802 if (function != NULL && | 3393 if (function != NULL && |
| 3803 function->nargs != -1 && | 3394 function->nargs != -1 && |
| 3804 function->nargs != args->length()) { | 3395 function->nargs != args->length()) { |
| 3805 ReportMessage("illegal_access", Vector<const char*>::empty()); | 3396 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 3806 *ok = false; | 3397 *ok = false; |
| 3807 return NULL; | 3398 return NULL; |
| 3808 } | 3399 } |
| 3809 | 3400 |
| 3810 // We have a valid intrinsics call or a call to a builtin. | 3401 // We have a valid intrinsics call or a call to a builtin. |
| 3811 return NEW(CallRuntime(name, function, args)); | 3402 return new CallRuntime(name, function, args); |
| 3812 } | 3403 } |
| 3813 | 3404 |
| 3814 | 3405 |
| 3815 void Parser::Consume(Token::Value token) { | 3406 void Parser::Consume(Token::Value token) { |
| 3816 Token::Value next = Next(); | 3407 Token::Value next = Next(); |
| 3817 USE(next); | 3408 USE(next); |
| 3818 USE(token); | 3409 USE(token); |
| 3819 ASSERT(next == token); | 3410 ASSERT(next == token); |
| 3820 } | 3411 } |
| 3821 | 3412 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3849 if (scanner_.has_line_terminator_before_next() || | 3440 if (scanner_.has_line_terminator_before_next() || |
| 3850 tok == Token::RBRACE || | 3441 tok == Token::RBRACE || |
| 3851 tok == Token::EOS) { | 3442 tok == Token::EOS) { |
| 3852 return; | 3443 return; |
| 3853 } | 3444 } |
| 3854 Expect(Token::SEMICOLON, ok); | 3445 Expect(Token::SEMICOLON, ok); |
| 3855 } | 3446 } |
| 3856 | 3447 |
| 3857 | 3448 |
| 3858 Literal* Parser::GetLiteralUndefined() { | 3449 Literal* Parser::GetLiteralUndefined() { |
| 3859 return NEW(Literal(Factory::undefined_value())); | 3450 return new Literal(Factory::undefined_value()); |
| 3860 } | 3451 } |
| 3861 | 3452 |
| 3862 | 3453 |
| 3863 Literal* Parser::GetLiteralTheHole() { | 3454 Literal* Parser::GetLiteralTheHole() { |
| 3864 return NEW(Literal(Factory::the_hole_value())); | 3455 return new Literal(Factory::the_hole_value()); |
| 3865 } | 3456 } |
| 3866 | 3457 |
| 3867 | 3458 |
| 3868 Literal* Parser::GetLiteralNumber(double value) { | 3459 Literal* Parser::GetLiteralNumber(double value) { |
| 3869 return NewNumberLiteral(value); | 3460 return NewNumberLiteral(value); |
| 3870 } | 3461 } |
| 3871 | 3462 |
| 3872 | 3463 |
| 3873 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3464 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3874 Expect(Token::IDENTIFIER, ok); | 3465 Expect(Token::IDENTIFIER, ok); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3957 // target stack has been used from the top of the target stack. Add | 3548 // target stack has been used from the top of the target stack. Add |
| 3958 // the break target to any TargetCollectors passed on the stack. | 3549 // the break target to any TargetCollectors passed on the stack. |
| 3959 for (Target* t = target_stack_; t != stop; t = t->previous()) { | 3550 for (Target* t = target_stack_; t != stop; t = t->previous()) { |
| 3960 TargetCollector* collector = t->node()->AsTargetCollector(); | 3551 TargetCollector* collector = t->node()->AsTargetCollector(); |
| 3961 if (collector != NULL) collector->AddTarget(target); | 3552 if (collector != NULL) collector->AddTarget(target); |
| 3962 } | 3553 } |
| 3963 } | 3554 } |
| 3964 | 3555 |
| 3965 | 3556 |
| 3966 Literal* Parser::NewNumberLiteral(double number) { | 3557 Literal* Parser::NewNumberLiteral(double number) { |
| 3967 return NEW(Literal(Factory::NewNumber(number, TENURED))); | 3558 return new Literal(Factory::NewNumber(number, TENURED)); |
| 3968 } | 3559 } |
| 3969 | 3560 |
| 3970 | 3561 |
| 3971 Expression* Parser::NewThrowReferenceError(Handle<String> type) { | 3562 Expression* Parser::NewThrowReferenceError(Handle<String> type) { |
| 3972 return NewThrowError(Factory::MakeReferenceError_symbol(), | 3563 return NewThrowError(Factory::MakeReferenceError_symbol(), |
| 3973 type, HandleVector<Object>(NULL, 0)); | 3564 type, HandleVector<Object>(NULL, 0)); |
| 3974 } | 3565 } |
| 3975 | 3566 |
| 3976 | 3567 |
| 3977 Expression* Parser::NewThrowSyntaxError(Handle<String> type, | 3568 Expression* Parser::NewThrowSyntaxError(Handle<String> type, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3989 Handle<Object> elements[] = { first, second }; | 3580 Handle<Object> elements[] = { first, second }; |
| 3990 Vector< Handle<Object> > arguments = | 3581 Vector< Handle<Object> > arguments = |
| 3991 HandleVector<Object>(elements, ARRAY_SIZE(elements)); | 3582 HandleVector<Object>(elements, ARRAY_SIZE(elements)); |
| 3992 return NewThrowError(Factory::MakeTypeError_symbol(), type, arguments); | 3583 return NewThrowError(Factory::MakeTypeError_symbol(), type, arguments); |
| 3993 } | 3584 } |
| 3994 | 3585 |
| 3995 | 3586 |
| 3996 Expression* Parser::NewThrowError(Handle<String> constructor, | 3587 Expression* Parser::NewThrowError(Handle<String> constructor, |
| 3997 Handle<String> type, | 3588 Handle<String> type, |
| 3998 Vector< Handle<Object> > arguments) { | 3589 Vector< Handle<Object> > arguments) { |
| 3999 if (is_pre_parsing_) return NULL; | |
| 4000 | |
| 4001 int argc = arguments.length(); | 3590 int argc = arguments.length(); |
| 4002 Handle<JSArray> array = Factory::NewJSArray(argc, TENURED); | 3591 Handle<JSArray> array = Factory::NewJSArray(argc, TENURED); |
| 4003 ASSERT(array->IsJSArray() && array->HasFastElements()); | 3592 ASSERT(array->IsJSArray() && array->HasFastElements()); |
| 4004 for (int i = 0; i < argc; i++) { | 3593 for (int i = 0; i < argc; i++) { |
| 4005 Handle<Object> element = arguments[i]; | 3594 Handle<Object> element = arguments[i]; |
| 4006 if (!element.is_null()) { | 3595 if (!element.is_null()) { |
| 4007 // We know this doesn't cause a GC here because we allocated the JSArray | 3596 // We know this doesn't cause a GC here because we allocated the JSArray |
| 4008 // large enough. | 3597 // large enough. |
| 4009 array->SetFastElement(i, *element)->ToObjectUnchecked(); | 3598 array->SetFastElement(i, *element)->ToObjectUnchecked(); |
| 4010 } | 3599 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4178 return Factory::NewJSArrayWithElements(fast_elements); | 3767 return Factory::NewJSArrayWithElements(fast_elements); |
| 4179 } | 3768 } |
| 4180 | 3769 |
| 4181 // ---------------------------------------------------------------------------- | 3770 // ---------------------------------------------------------------------------- |
| 4182 // Regular expressions | 3771 // Regular expressions |
| 4183 | 3772 |
| 4184 | 3773 |
| 4185 RegExpParser::RegExpParser(FlatStringReader* in, | 3774 RegExpParser::RegExpParser(FlatStringReader* in, |
| 4186 Handle<String>* error, | 3775 Handle<String>* error, |
| 4187 bool multiline) | 3776 bool multiline) |
| 4188 : current_(kEndMarker), | 3777 : error_(error), |
| 3778 captures_(NULL), |
| 3779 in_(in), |
| 3780 current_(kEndMarker), |
| 3781 next_pos_(0), |
| 3782 capture_count_(0), |
| 4189 has_more_(true), | 3783 has_more_(true), |
| 4190 multiline_(multiline), | 3784 multiline_(multiline), |
| 4191 next_pos_(0), | |
| 4192 in_(in), | |
| 4193 error_(error), | |
| 4194 simple_(false), | 3785 simple_(false), |
| 4195 contains_anchor_(false), | 3786 contains_anchor_(false), |
| 4196 captures_(NULL), | |
| 4197 is_scanned_for_captures_(false), | 3787 is_scanned_for_captures_(false), |
| 4198 capture_count_(0), | |
| 4199 failed_(false) { | 3788 failed_(false) { |
| 4200 Advance(1); | 3789 Advance(1); |
| 4201 } | 3790 } |
| 4202 | 3791 |
| 4203 | 3792 |
| 4204 uc32 RegExpParser::Next() { | 3793 uc32 RegExpParser::Next() { |
| 4205 if (has_next()) { | 3794 if (has_next()) { |
| 4206 return in()->Get(next_pos_); | 3795 return in()->Get(next_pos_); |
| 4207 } else { | 3796 } else { |
| 4208 return kEndMarker; | 3797 return kEndMarker; |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4996 const char* ScriptDataImpl::Data() { | 4585 const char* ScriptDataImpl::Data() { |
| 4997 return reinterpret_cast<const char*>(store_.start()); | 4586 return reinterpret_cast<const char*>(store_.start()); |
| 4998 } | 4587 } |
| 4999 | 4588 |
| 5000 | 4589 |
| 5001 bool ScriptDataImpl::HasError() { | 4590 bool ScriptDataImpl::HasError() { |
| 5002 return has_error(); | 4591 return has_error(); |
| 5003 } | 4592 } |
| 5004 | 4593 |
| 5005 | 4594 |
| 5006 // Preparse, but only collect data that is immediately useful, | |
| 5007 // even if the preparser data is only used once. | |
| 5008 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, | |
| 5009 unibrow::CharacterStream* stream, | |
| 5010 v8::Extension* extension) { | |
| 5011 Handle<Script> no_script; | |
| 5012 bool allow_natives_syntax = | |
| 5013 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | |
| 5014 PartialPreParser parser(no_script, allow_natives_syntax, extension); | |
| 5015 if (!parser.PreParseProgram(source, stream)) return NULL; | |
| 5016 // Extract the accumulated data from the recorder as a single | |
| 5017 // contiguous vector that we are responsible for disposing. | |
| 5018 Vector<unsigned> store = parser.recorder()->ExtractData(); | |
| 5019 return new ScriptDataImpl(store); | |
| 5020 } | |
| 5021 | |
| 5022 | |
| 5023 void ScriptDataImpl::Initialize() { | 4595 void ScriptDataImpl::Initialize() { |
| 5024 // Prepares state for use. | 4596 // Prepares state for use. |
| 5025 if (store_.length() >= kHeaderSize) { | 4597 if (store_.length() >= kHeaderSize) { |
| 5026 function_index_ = kHeaderSize; | 4598 function_index_ = kHeaderSize; |
| 5027 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; | 4599 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; |
| 5028 if (store_.length() > symbol_data_offset) { | 4600 if (store_.length() > symbol_data_offset) { |
| 5029 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); | 4601 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); |
| 5030 } else { | 4602 } else { |
| 5031 // Partial preparse causes no symbol information. | 4603 // Partial preparse causes no symbol information. |
| 5032 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); | 4604 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5056 if (data >= symbol_data_end_) return -1; | 4628 if (data >= symbol_data_end_) return -1; |
| 5057 input = *data; | 4629 input = *data; |
| 5058 result = (result << 7) | (input & 0x7f); | 4630 result = (result << 7) | (input & 0x7f); |
| 5059 data++; | 4631 data++; |
| 5060 } | 4632 } |
| 5061 *source = data; | 4633 *source = data; |
| 5062 return result; | 4634 return result; |
| 5063 } | 4635 } |
| 5064 | 4636 |
| 5065 | 4637 |
| 4638 // Preparse, but only collect data that is immediately useful, |
| 4639 // even if the preparser data is only used once. |
| 4640 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, |
| 4641 unibrow::CharacterStream* stream, |
| 4642 v8::Extension* extension) { |
| 4643 Handle<Script> no_script; |
| 4644 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4645 if (!allow_lazy) { |
| 4646 // Partial preparsing is only about lazily compiled functions. |
| 4647 // If we don't allow lazy compilation, the log data will be empty. |
| 4648 return NULL; |
| 4649 } |
| 4650 preparser::PreParser<Scanner, PartialParserRecorder> parser; |
| 4651 Scanner scanner; |
| 4652 scanner.Initialize(source, stream, JAVASCRIPT); |
| 4653 PartialParserRecorder recorder; |
| 4654 if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { |
| 4655 Top::StackOverflow(); |
| 4656 return NULL; |
| 4657 } |
| 4658 |
| 4659 // Extract the accumulated data from the recorder as a single |
| 4660 // contiguous vector that we are responsible for disposing. |
| 4661 Vector<unsigned> store = recorder.ExtractData(); |
| 4662 return new ScriptDataImpl(store); |
| 4663 } |
| 4664 |
| 4665 |
| 5066 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, | 4666 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, |
| 5067 unibrow::CharacterStream* stream, | 4667 unibrow::CharacterStream* stream, |
| 5068 v8::Extension* extension) { | 4668 v8::Extension* extension) { |
| 5069 Handle<Script> no_script; | 4669 Handle<Script> no_script; |
| 5070 bool allow_natives_syntax = | 4670 preparser::PreParser<Scanner, CompleteParserRecorder> parser; |
| 5071 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 4671 Scanner scanner; |
| 5072 CompletePreParser parser(no_script, allow_natives_syntax, extension); | 4672 scanner.Initialize(source, stream, JAVASCRIPT); |
| 5073 if (!parser.PreParseProgram(source, stream)) return NULL; | 4673 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4674 CompleteParserRecorder recorder; |
| 4675 if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { |
| 4676 Top::StackOverflow(); |
| 4677 return NULL; |
| 4678 } |
| 5074 // Extract the accumulated data from the recorder as a single | 4679 // Extract the accumulated data from the recorder as a single |
| 5075 // contiguous vector that we are responsible for disposing. | 4680 // contiguous vector that we are responsible for disposing. |
| 5076 Vector<unsigned> store = parser.recorder()->ExtractData(); | 4681 Vector<unsigned> store = recorder.ExtractData(); |
| 5077 return new ScriptDataImpl(store); | 4682 return new ScriptDataImpl(store); |
| 5078 } | 4683 } |
| 5079 | 4684 |
| 5080 | 4685 |
| 5081 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4686 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5082 bool multiline, | 4687 bool multiline, |
| 5083 RegExpCompileData* result) { | 4688 RegExpCompileData* result) { |
| 5084 ASSERT(result != NULL); | 4689 ASSERT(result != NULL); |
| 5085 RegExpParser parser(input, &result->error, multiline); | 4690 RegExpParser parser(input, &result->error, multiline); |
| 5086 RegExpTree* tree = parser.ParsePattern(); | 4691 RegExpTree* tree = parser.ParsePattern(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5098 } | 4703 } |
| 5099 return !parser.failed(); | 4704 return !parser.failed(); |
| 5100 } | 4705 } |
| 5101 | 4706 |
| 5102 | 4707 |
| 5103 bool ParserApi::Parse(CompilationInfo* info) { | 4708 bool ParserApi::Parse(CompilationInfo* info) { |
| 5104 ASSERT(info->function() == NULL); | 4709 ASSERT(info->function() == NULL); |
| 5105 FunctionLiteral* result = NULL; | 4710 FunctionLiteral* result = NULL; |
| 5106 Handle<Script> script = info->script(); | 4711 Handle<Script> script = info->script(); |
| 5107 if (info->is_lazy()) { | 4712 if (info->is_lazy()) { |
| 5108 AstBuildingParser parser(script, true, NULL, NULL); | 4713 Parser parser(script, true, NULL, NULL); |
| 5109 result = parser.ParseLazy(info->shared_info()); | 4714 result = parser.ParseLazy(info->shared_info()); |
| 5110 } else { | 4715 } else { |
| 5111 bool allow_natives_syntax = | 4716 bool allow_natives_syntax = |
| 5112 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 4717 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); |
| 5113 ScriptDataImpl* pre_data = info->pre_parse_data(); | 4718 ScriptDataImpl* pre_data = info->pre_parse_data(); |
| 5114 AstBuildingParser parser(script, allow_natives_syntax, info->extension(), | 4719 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); |
| 5115 pre_data); | |
| 5116 if (pre_data != NULL && pre_data->has_error()) { | 4720 if (pre_data != NULL && pre_data->has_error()) { |
| 5117 Scanner::Location loc = pre_data->MessageLocation(); | 4721 Scanner::Location loc = pre_data->MessageLocation(); |
| 5118 const char* message = pre_data->BuildMessage(); | 4722 const char* message = pre_data->BuildMessage(); |
| 5119 Vector<const char*> args = pre_data->BuildArgs(); | 4723 Vector<const char*> args = pre_data->BuildArgs(); |
| 5120 parser.ReportMessageAt(loc, message, args); | 4724 parser.ReportMessageAt(loc, message, args); |
| 5121 DeleteArray(message); | 4725 DeleteArray(message); |
| 5122 for (int i = 0; i < args.length(); i++) { | 4726 for (int i = 0; i < args.length(); i++) { |
| 5123 DeleteArray(args[i]); | 4727 DeleteArray(args[i]); |
| 5124 } | 4728 } |
| 5125 DeleteArray(args.start()); | 4729 DeleteArray(args.start()); |
| 5126 ASSERT(Top::has_pending_exception()); | 4730 ASSERT(Top::has_pending_exception()); |
| 5127 } else { | 4731 } else { |
| 5128 Handle<String> source = Handle<String>(String::cast(script->source())); | 4732 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5129 result = parser.ParseProgram(source, info->is_global()); | 4733 result = parser.ParseProgram(source, info->is_global()); |
| 5130 } | 4734 } |
| 5131 } | 4735 } |
| 5132 | 4736 |
| 5133 info->SetFunction(result); | 4737 info->SetFunction(result); |
| 5134 return (result != NULL); | 4738 return (result != NULL); |
| 5135 } | 4739 } |
| 5136 | 4740 |
| 5137 #undef NEW | |
| 5138 | |
| 5139 } } // namespace v8::internal | 4741 } } // namespace v8::internal |
| OLD | NEW |