1// Copyright 2011 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#include "v8.h" 29 30#include "api.h" 31#include "ast.h" 32#include "bootstrapper.h" 33#include "codegen.h" 34#include "compiler.h" 35#include "func-name-inferrer.h" 36#include "messages.h" 37#include "parser.h" 38#include "platform.h" 39#include "preparser.h" 40#include "runtime.h" 41#include "scopeinfo.h" 42#include "string-stream.h" 43 44#include "ast-inl.h" 45 46namespace v8 { 47namespace internal { 48 49// PositionStack is used for on-stack allocation of token positions for 50// new expressions. Please look at ParseNewExpression. 51 52class PositionStack { 53 public: 54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} 55 ~PositionStack() { ASSERT(!*ok_ || is_empty()); } 56 57 class Element { 58 public: 59 Element(PositionStack* stack, int value) { 60 previous_ = stack->top(); 61 value_ = value; 62 stack->set_top(this); 63 } 64 65 private: 66 Element* previous() { return previous_; } 67 int value() { return value_; } 68 friend class PositionStack; 69 Element* previous_; 70 int value_; 71 }; 72 73 bool is_empty() { return top_ == NULL; } 74 int pop() { 75 ASSERT(!is_empty()); 76 int result = top_->value(); 77 top_ = top_->previous(); 78 return result; 79 } 80 81 private: 82 Element* top() { return top_; } 83 void set_top(Element* value) { top_ = value; } 84 Element* top_; 85 bool* ok_; 86}; 87 88 89RegExpBuilder::RegExpBuilder() 90 : zone_(Isolate::Current()->zone()), 91 pending_empty_(false), 92 characters_(NULL), 93 terms_(), 94 alternatives_() 95#ifdef DEBUG 96 , last_added_(ADD_NONE) 97#endif 98 {} 99 100 101void RegExpBuilder::FlushCharacters() { 102 pending_empty_ = false; 103 if (characters_ != NULL) { 104 RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector()); 105 characters_ = NULL; 106 text_.Add(atom); 107 LAST(ADD_ATOM); 108 } 109} 110 111 112void RegExpBuilder::FlushText() { 113 FlushCharacters(); 114 int num_text = text_.length(); 115 if (num_text == 0) { 116 return; 117 } else if (num_text == 1) { 118 terms_.Add(text_.last()); 119 } else { 120 RegExpText* text = new(zone()) RegExpText(); 121 for (int i = 0; i < num_text; i++) 122 text_.Get(i)->AppendToText(text); 123 terms_.Add(text); 124 } 125 text_.Clear(); 126} 127 128 129void RegExpBuilder::AddCharacter(uc16 c) { 130 pending_empty_ = false; 131 if (characters_ == NULL) { 132 characters_ = new ZoneList<uc16>(4); 133 } 134 characters_->Add(c); 135 LAST(ADD_CHAR); 136} 137 138 139void RegExpBuilder::AddEmpty() { 140 pending_empty_ = true; 141} 142 143 144void RegExpBuilder::AddAtom(RegExpTree* term) { 145 if (term->IsEmpty()) { 146 AddEmpty(); 147 return; 148 } 149 if (term->IsTextElement()) { 150 FlushCharacters(); 151 text_.Add(term); 152 } else { 153 FlushText(); 154 terms_.Add(term); 155 } 156 LAST(ADD_ATOM); 157} 158 159 160void RegExpBuilder::AddAssertion(RegExpTree* assert) { 161 FlushText(); 162 terms_.Add(assert); 163 LAST(ADD_ASSERT); 164} 165 166 167void RegExpBuilder::NewAlternative() { 168 FlushTerms(); 169} 170 171 172void RegExpBuilder::FlushTerms() { 173 FlushText(); 174 int num_terms = terms_.length(); 175 RegExpTree* alternative; 176 if (num_terms == 0) { 177 alternative = RegExpEmpty::GetInstance(); 178 } else if (num_terms == 1) { 179 alternative = terms_.last(); 180 } else { 181 alternative = new(zone()) RegExpAlternative(terms_.GetList()); 182 } 183 alternatives_.Add(alternative); 184 terms_.Clear(); 185 LAST(ADD_NONE); 186} 187 188 189RegExpTree* RegExpBuilder::ToRegExp() { 190 FlushTerms(); 191 int num_alternatives = alternatives_.length(); 192 if (num_alternatives == 0) { 193 return RegExpEmpty::GetInstance(); 194 } 195 if (num_alternatives == 1) { 196 return alternatives_.last(); 197 } 198 return new(zone()) RegExpDisjunction(alternatives_.GetList()); 199} 200 201 202void RegExpBuilder::AddQuantifierToAtom(int min, 203 int max, 204 RegExpQuantifier::Type type) { 205 if (pending_empty_) { 206 pending_empty_ = false; 207 return; 208 } 209 RegExpTree* atom; 210 if (characters_ != NULL) { 211 ASSERT(last_added_ == ADD_CHAR); 212 // Last atom was character. 213 Vector<const uc16> char_vector = characters_->ToConstVector(); 214 int num_chars = char_vector.length(); 215 if (num_chars > 1) { 216 Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1); 217 text_.Add(new(zone()) RegExpAtom(prefix)); 218 char_vector = char_vector.SubVector(num_chars - 1, num_chars); 219 } 220 characters_ = NULL; 221 atom = new(zone()) RegExpAtom(char_vector); 222 FlushText(); 223 } else if (text_.length() > 0) { 224 ASSERT(last_added_ == ADD_ATOM); 225 atom = text_.RemoveLast(); 226 FlushText(); 227 } else if (terms_.length() > 0) { 228 ASSERT(last_added_ == ADD_ATOM); 229 atom = terms_.RemoveLast(); 230 if (atom->max_match() == 0) { 231 // Guaranteed to only match an empty string. 232 LAST(ADD_TERM); 233 if (min == 0) { 234 return; 235 } 236 terms_.Add(atom); 237 return; 238 } 239 } else { 240 // Only call immediately after adding an atom or character! 241 UNREACHABLE(); 242 return; 243 } 244 terms_.Add(new(zone()) RegExpQuantifier(min, max, type, atom)); 245 LAST(ADD_TERM); 246} 247 248 249Handle<String> Parser::LookupSymbol(int symbol_id) { 250 // Length of symbol cache is the number of identified symbols. 251 // If we are larger than that, or negative, it's not a cached symbol. 252 // This might also happen if there is no preparser symbol data, even 253 // if there is some preparser data. 254 if (static_cast<unsigned>(symbol_id) 255 >= static_cast<unsigned>(symbol_cache_.length())) { 256 if (scanner().is_literal_ascii()) { 257 return isolate()->factory()->LookupAsciiSymbol( 258 scanner().literal_ascii_string()); 259 } else { 260 return isolate()->factory()->LookupTwoByteSymbol( 261 scanner().literal_uc16_string()); 262 } 263 } 264 return LookupCachedSymbol(symbol_id); 265} 266 267 268Handle<String> Parser::LookupCachedSymbol(int symbol_id) { 269 // Make sure the cache is large enough to hold the symbol identifier. 270 if (symbol_cache_.length() <= symbol_id) { 271 // Increase length to index + 1. 272 symbol_cache_.AddBlock(Handle<String>::null(), 273 symbol_id + 1 - symbol_cache_.length()); 274 } 275 Handle<String> result = symbol_cache_.at(symbol_id); 276 if (result.is_null()) { 277 if (scanner().is_literal_ascii()) { 278 result = isolate()->factory()->LookupAsciiSymbol( 279 scanner().literal_ascii_string()); 280 } else { 281 result = isolate()->factory()->LookupTwoByteSymbol( 282 scanner().literal_uc16_string()); 283 } 284 symbol_cache_.at(symbol_id) = result; 285 return result; 286 } 287 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); 288 return result; 289} 290 291 292FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 293 // The current pre-data entry must be a FunctionEntry with the given 294 // start position. 295 if ((function_index_ + FunctionEntry::kSize <= store_.length()) 296 && (static_cast<int>(store_[function_index_]) == start)) { 297 int index = function_index_; 298 function_index_ += FunctionEntry::kSize; 299 return FunctionEntry(store_.SubVector(index, 300 index + FunctionEntry::kSize)); 301 } 302 return FunctionEntry(); 303} 304 305 306int ScriptDataImpl::GetSymbolIdentifier() { 307 return ReadNumber(&symbol_data_); 308} 309 310 311bool ScriptDataImpl::SanityCheck() { 312 // Check that the header data is valid and doesn't specify 313 // point to positions outside the store. 314 if (store_.length() < PreparseDataConstants::kHeaderSize) return false; 315 if (magic() != PreparseDataConstants::kMagicNumber) return false; 316 if (version() != PreparseDataConstants::kCurrentVersion) return false; 317 if (has_error()) { 318 // Extra sane sanity check for error message encoding. 319 if (store_.length() <= PreparseDataConstants::kHeaderSize 320 + PreparseDataConstants::kMessageTextPos) { 321 return false; 322 } 323 if (Read(PreparseDataConstants::kMessageStartPos) > 324 Read(PreparseDataConstants::kMessageEndPos)) { 325 return false; 326 } 327 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 328 int pos = PreparseDataConstants::kMessageTextPos; 329 for (unsigned int i = 0; i <= arg_count; i++) { 330 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) { 331 return false; 332 } 333 int length = static_cast<int>(Read(pos)); 334 if (length < 0) return false; 335 pos += 1 + length; 336 } 337 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) { 338 return false; 339 } 340 return true; 341 } 342 // Check that the space allocated for function entries is sane. 343 int functions_size = 344 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]); 345 if (functions_size < 0) return false; 346 if (functions_size % FunctionEntry::kSize != 0) return false; 347 // Check that the count of symbols is non-negative. 348 int symbol_count = 349 static_cast<int>(store_[PreparseDataConstants::kSymbolCountOffset]); 350 if (symbol_count < 0) return false; 351 // Check that the total size has room for header and function entries. 352 int minimum_size = 353 PreparseDataConstants::kHeaderSize + functions_size; 354 if (store_.length() < minimum_size) return false; 355 return true; 356} 357 358 359 360const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) { 361 int length = start[0]; 362 char* result = NewArray<char>(length + 1); 363 for (int i = 0; i < length; i++) { 364 result[i] = start[i + 1]; 365 } 366 result[length] = '\0'; 367 if (chars != NULL) *chars = length; 368 return result; 369} 370 371Scanner::Location ScriptDataImpl::MessageLocation() { 372 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); 373 int end_pos = Read(PreparseDataConstants::kMessageEndPos); 374 return Scanner::Location(beg_pos, end_pos); 375} 376 377 378const char* ScriptDataImpl::BuildMessage() { 379 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); 380 return ReadString(start, NULL); 381} 382 383 384Vector<const char*> ScriptDataImpl::BuildArgs() { 385 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); 386 const char** array = NewArray<const char*>(arg_count); 387 // Position after text found by skipping past length field and 388 // length field content words. 389 int pos = PreparseDataConstants::kMessageTextPos + 1 390 + Read(PreparseDataConstants::kMessageTextPos); 391 for (int i = 0; i < arg_count; i++) { 392 int count = 0; 393 array[i] = ReadString(ReadAddress(pos), &count); 394 pos += count + 1; 395 } 396 return Vector<const char*>(array, arg_count); 397} 398 399 400unsigned ScriptDataImpl::Read(int position) { 401 return store_[PreparseDataConstants::kHeaderSize + position]; 402} 403 404 405unsigned* ScriptDataImpl::ReadAddress(int position) { 406 return &store_[PreparseDataConstants::kHeaderSize + position]; 407} 408 409 410Scope* Parser::NewScope(Scope* parent, Scope::Type type, bool inside_with) { 411 Scope* result = new(zone()) Scope(parent, type); 412 result->Initialize(inside_with); 413 return result; 414} 415 416// ---------------------------------------------------------------------------- 417// Target is a support class to facilitate manipulation of the 418// Parser's target_stack_ (the stack of potential 'break' and 419// 'continue' statement targets). Upon construction, a new target is 420// added; it is removed upon destruction. 421 422class Target BASE_EMBEDDED { 423 public: 424 Target(Target** variable, AstNode* node) 425 : variable_(variable), node_(node), previous_(*variable) { 426 *variable = this; 427 } 428 429 ~Target() { 430 *variable_ = previous_; 431 } 432 433 Target* previous() { return previous_; } 434 AstNode* node() { return node_; } 435 436 private: 437 Target** variable_; 438 AstNode* node_; 439 Target* previous_; 440}; 441 442 443class TargetScope BASE_EMBEDDED { 444 public: 445 explicit TargetScope(Target** variable) 446 : variable_(variable), previous_(*variable) { 447 *variable = NULL; 448 } 449 450 ~TargetScope() { 451 *variable_ = previous_; 452 } 453 454 private: 455 Target** variable_; 456 Target* previous_; 457}; 458 459 460// ---------------------------------------------------------------------------- 461// LexicalScope is a support class to facilitate manipulation of the 462// Parser's scope stack. The constructor sets the parser's top scope 463// to the incoming scope, and the destructor resets it. 464// 465// Additionally, it stores transient information used during parsing. 466// These scopes are not kept around after parsing or referenced by syntax 467// trees so they can be stack-allocated and hence used by the pre-parser. 468 469class LexicalScope BASE_EMBEDDED { 470 public: 471 LexicalScope(Parser* parser, Scope* scope, Isolate* isolate); 472 ~LexicalScope(); 473 474 int NextMaterializedLiteralIndex() { 475 int next_index = 476 materialized_literal_count_ + JSFunction::kLiteralsPrefixSize; 477 materialized_literal_count_++; 478 return next_index; 479 } 480 int materialized_literal_count() { return materialized_literal_count_; } 481 482 void SetThisPropertyAssignmentInfo( 483 bool only_simple_this_property_assignments, 484 Handle<FixedArray> this_property_assignments) { 485 only_simple_this_property_assignments_ = 486 only_simple_this_property_assignments; 487 this_property_assignments_ = this_property_assignments; 488 } 489 bool only_simple_this_property_assignments() { 490 return only_simple_this_property_assignments_; 491 } 492 Handle<FixedArray> this_property_assignments() { 493 return this_property_assignments_; 494 } 495 496 void AddProperty() { expected_property_count_++; } 497 int expected_property_count() { return expected_property_count_; } 498 499 private: 500 // Captures the number of literals that need materialization in the 501 // function. Includes regexp literals, and boilerplate for object 502 // and array literals. 503 int materialized_literal_count_; 504 505 // Properties count estimation. 506 int expected_property_count_; 507 508 // Keeps track of assignments to properties of this. Used for 509 // optimizing constructors. 510 bool only_simple_this_property_assignments_; 511 Handle<FixedArray> this_property_assignments_; 512 513 // Bookkeeping 514 Parser* parser_; 515 // Previous values 516 LexicalScope* lexical_scope_parent_; 517 Scope* previous_scope_; 518 int previous_with_nesting_level_; 519 unsigned previous_ast_node_id_; 520}; 521 522 523LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate) 524 : materialized_literal_count_(0), 525 expected_property_count_(0), 526 only_simple_this_property_assignments_(false), 527 this_property_assignments_(isolate->factory()->empty_fixed_array()), 528 parser_(parser), 529 lexical_scope_parent_(parser->lexical_scope_), 530 previous_scope_(parser->top_scope_), 531 previous_with_nesting_level_(parser->with_nesting_level_), 532 previous_ast_node_id_(isolate->ast_node_id()) { 533 parser->top_scope_ = scope; 534 parser->lexical_scope_ = this; 535 parser->with_nesting_level_ = 0; 536 isolate->set_ast_node_id(AstNode::kFunctionEntryId + 1); 537} 538 539 540LexicalScope::~LexicalScope() { 541 parser_->top_scope_->Leave(); 542 parser_->top_scope_ = previous_scope_; 543 parser_->lexical_scope_ = lexical_scope_parent_; 544 parser_->with_nesting_level_ = previous_with_nesting_level_; 545 parser_->isolate()->set_ast_node_id(previous_ast_node_id_); 546} 547 548 549// ---------------------------------------------------------------------------- 550// The CHECK_OK macro is a convenient macro to enforce error 551// handling for functions that may fail (by returning !*ok). 552// 553// CAUTION: This macro appends extra statements after a call, 554// thus it must never be used where only a single statement 555// is correct (e.g. an if statement branch w/o braces)! 556 557#define CHECK_OK ok); \ 558 if (!*ok) return NULL; \ 559 ((void)0 560#define DUMMY ) // to make indentation work 561#undef DUMMY 562 563#define CHECK_FAILED /**/); \ 564 if (failed_) return NULL; \ 565 ((void)0 566#define DUMMY ) // to make indentation work 567#undef DUMMY 568 569// ---------------------------------------------------------------------------- 570// Implementation of Parser 571 572Parser::Parser(Handle<Script> script, 573 bool allow_natives_syntax, 574 v8::Extension* extension, 575 ScriptDataImpl* pre_data) 576 : isolate_(script->GetIsolate()), 577 symbol_cache_(pre_data ? pre_data->symbol_count() : 0), 578 script_(script), 579 scanner_(isolate_->unicode_cache()), 580 top_scope_(NULL), 581 with_nesting_level_(0), 582 lexical_scope_(NULL), 583 target_stack_(NULL), 584 allow_natives_syntax_(allow_natives_syntax), 585 extension_(extension), 586 pre_data_(pre_data), 587 fni_(NULL), 588 stack_overflow_(false), 589 parenthesized_function_(false) { 590 AstNode::ResetIds(); 591} 592 593 594FunctionLiteral* Parser::ParseProgram(Handle<String> source, 595 bool in_global_context, 596 StrictModeFlag strict_mode) { 597 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 598 599 HistogramTimerScope timer(isolate()->counters()->parse()); 600 isolate()->counters()->total_parse_size()->Increment(source->length()); 601 fni_ = new(zone()) FuncNameInferrer(); 602 603 // Initialize parser state. 604 source->TryFlatten(); 605 if (source->IsExternalTwoByteString()) { 606 // Notice that the stream is destroyed at the end of the branch block. 607 // The last line of the blocks can't be moved outside, even though they're 608 // identical calls. 609 ExternalTwoByteStringUC16CharacterStream stream( 610 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 611 scanner_.Initialize(&stream); 612 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 613 } else { 614 GenericStringUC16CharacterStream stream(source, 0, source->length()); 615 scanner_.Initialize(&stream); 616 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); 617 } 618} 619 620 621FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 622 bool in_global_context, 623 StrictModeFlag strict_mode, 624 ZoneScope* zone_scope) { 625 ASSERT(target_stack_ == NULL); 626 if (pre_data_ != NULL) pre_data_->Initialize(); 627 628 // Compute the parsing mode. 629 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 630 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 631 632 Scope::Type type = 633 in_global_context 634 ? Scope::GLOBAL_SCOPE 635 : Scope::EVAL_SCOPE; 636 Handle<String> no_name = isolate()->factory()->empty_symbol(); 637 638 FunctionLiteral* result = NULL; 639 { Scope* scope = NewScope(top_scope_, type, inside_with()); 640 LexicalScope lexical_scope(this, scope, isolate()); 641 if (strict_mode == kStrictMode) { 642 top_scope_->EnableStrictMode(); 643 } 644 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); 645 bool ok = true; 646 int beg_loc = scanner().location().beg_pos; 647 ParseSourceElements(body, Token::EOS, &ok); 648 if (ok && top_scope_->is_strict_mode()) { 649 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); 650 } 651 if (ok) { 652 result = new(zone()) FunctionLiteral( 653 no_name, 654 top_scope_, 655 body, 656 lexical_scope.materialized_literal_count(), 657 lexical_scope.expected_property_count(), 658 lexical_scope.only_simple_this_property_assignments(), 659 lexical_scope.this_property_assignments(), 660 0, 661 0, 662 source->length(), 663 false); 664 } else if (stack_overflow_) { 665 isolate()->StackOverflow(); 666 } 667 } 668 669 // Make sure the target stack is empty. 670 ASSERT(target_stack_ == NULL); 671 672 // If there was a syntax error we have to get rid of the AST 673 // and it is not safe to do so before the scope has been deleted. 674 if (result == NULL) zone_scope->DeleteOnExit(); 675 return result; 676} 677 678FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { 679 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 680 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); 681 Handle<String> source(String::cast(script_->source())); 682 isolate()->counters()->total_parse_size()->Increment(source->length()); 683 684 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 685 // Initialize parser state. 686 source->TryFlatten(); 687 if (source->IsExternalTwoByteString()) { 688 ExternalTwoByteStringUC16CharacterStream stream( 689 Handle<ExternalTwoByteString>::cast(source), 690 shared_info->start_position(), 691 shared_info->end_position()); 692 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 693 return result; 694 } else { 695 GenericStringUC16CharacterStream stream(source, 696 shared_info->start_position(), 697 shared_info->end_position()); 698 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 699 return result; 700 } 701} 702 703 704FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, 705 UC16CharacterStream* source, 706 ZoneScope* zone_scope) { 707 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 708 scanner_.Initialize(source); 709 ASSERT(target_stack_ == NULL); 710 711 Handle<String> name(String::cast(shared_info->name())); 712 fni_ = new(zone()) FuncNameInferrer(); 713 fni_->PushEnclosingName(name); 714 715 mode_ = PARSE_EAGERLY; 716 717 // Place holder for the result. 718 FunctionLiteral* result = NULL; 719 720 { 721 // Parse the function literal. 722 Handle<String> no_name = isolate()->factory()->empty_symbol(); 723 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); 724 if (!info->closure().is_null()) { 725 scope = Scope::DeserializeScopeChain(info, scope); 726 } 727 LexicalScope lexical_scope(this, scope, isolate()); 728 729 if (shared_info->strict_mode()) { 730 top_scope_->EnableStrictMode(); 731 } 732 733 FunctionLiteralType type = 734 shared_info->is_expression() ? EXPRESSION : DECLARATION; 735 bool ok = true; 736 result = ParseFunctionLiteral(name, 737 false, // Strict mode name already checked. 738 RelocInfo::kNoPosition, type, &ok); 739 // Make sure the results agree. 740 ASSERT(ok == (result != NULL)); 741 } 742 743 // Make sure the target stack is empty. 744 ASSERT(target_stack_ == NULL); 745 746 // If there was a stack overflow we have to get rid of AST and it is 747 // not safe to do before scope has been deleted. 748 if (result == NULL) { 749 zone_scope->DeleteOnExit(); 750 if (stack_overflow_) isolate()->StackOverflow(); 751 } else { 752 Handle<String> inferred_name(shared_info->inferred_name()); 753 result->set_inferred_name(inferred_name); 754 } 755 return result; 756} 757 758 759Handle<String> Parser::GetSymbol(bool* ok) { 760 int symbol_id = -1; 761 if (pre_data() != NULL) { 762 symbol_id = pre_data()->GetSymbolIdentifier(); 763 } 764 return LookupSymbol(symbol_id); 765} 766 767 768void Parser::ReportMessage(const char* type, Vector<const char*> args) { 769 Scanner::Location source_location = scanner().location(); 770 ReportMessageAt(source_location, type, args); 771} 772 773 774void Parser::ReportMessageAt(Scanner::Location source_location, 775 const char* type, 776 Vector<const char*> args) { 777 MessageLocation location(script_, 778 source_location.beg_pos, 779 source_location.end_pos); 780 Factory* factory = isolate()->factory(); 781 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 782 for (int i = 0; i < args.length(); i++) { 783 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); 784 elements->set(i, *arg_string); 785 } 786 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 787 Handle<Object> result = factory->NewSyntaxError(type, array); 788 isolate()->Throw(*result, &location); 789} 790 791 792void Parser::ReportMessageAt(Scanner::Location source_location, 793 const char* type, 794 Vector<Handle<String> > args) { 795 MessageLocation location(script_, 796 source_location.beg_pos, 797 source_location.end_pos); 798 Factory* factory = isolate()->factory(); 799 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); 800 for (int i = 0; i < args.length(); i++) { 801 elements->set(i, *args[i]); 802 } 803 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); 804 Handle<Object> result = factory->NewSyntaxError(type, array); 805 isolate()->Throw(*result, &location); 806} 807 808 809// Base class containing common code for the different finder classes used by 810// the parser. 811class ParserFinder { 812 protected: 813 ParserFinder() {} 814 static Assignment* AsAssignment(Statement* stat) { 815 if (stat == NULL) return NULL; 816 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); 817 if (exp_stat == NULL) return NULL; 818 return exp_stat->expression()->AsAssignment(); 819 } 820}; 821 822 823// An InitializationBlockFinder finds and marks sequences of statements of the 824// form expr.a = ...; expr.b = ...; etc. 825class InitializationBlockFinder : public ParserFinder { 826 public: 827 InitializationBlockFinder() 828 : first_in_block_(NULL), last_in_block_(NULL), block_size_(0) {} 829 830 ~InitializationBlockFinder() { 831 if (InBlock()) EndBlock(); 832 } 833 834 void Update(Statement* stat) { 835 Assignment* assignment = AsAssignment(stat); 836 if (InBlock()) { 837 if (BlockContinues(assignment)) { 838 UpdateBlock(assignment); 839 } else { 840 EndBlock(); 841 } 842 } 843 if (!InBlock() && (assignment != NULL) && 844 (assignment->op() == Token::ASSIGN)) { 845 StartBlock(assignment); 846 } 847 } 848 849 private: 850 // The minimum number of contiguous assignment that will 851 // be treated as an initialization block. Benchmarks show that 852 // the overhead exceeds the savings below this limit. 853 static const int kMinInitializationBlock = 3; 854 855 // Returns true if the expressions appear to denote the same object. 856 // In the context of initialization blocks, we only consider expressions 857 // of the form 'expr.x' or expr["x"]. 858 static bool SameObject(Expression* e1, Expression* e2) { 859 VariableProxy* v1 = e1->AsVariableProxy(); 860 VariableProxy* v2 = e2->AsVariableProxy(); 861 if (v1 != NULL && v2 != NULL) { 862 return v1->name()->Equals(*v2->name()); 863 } 864 Property* p1 = e1->AsProperty(); 865 Property* p2 = e2->AsProperty(); 866 if ((p1 == NULL) || (p2 == NULL)) return false; 867 Literal* key1 = p1->key()->AsLiteral(); 868 Literal* key2 = p2->key()->AsLiteral(); 869 if ((key1 == NULL) || (key2 == NULL)) return false; 870 if (!key1->handle()->IsString() || !key2->handle()->IsString()) { 871 return false; 872 } 873 String* name1 = String::cast(*key1->handle()); 874 String* name2 = String::cast(*key2->handle()); 875 if (!name1->Equals(name2)) return false; 876 return SameObject(p1->obj(), p2->obj()); 877 } 878 879 // Returns true if the expressions appear to denote different properties 880 // of the same object. 881 static bool PropertyOfSameObject(Expression* e1, Expression* e2) { 882 Property* p1 = e1->AsProperty(); 883 Property* p2 = e2->AsProperty(); 884 if ((p1 == NULL) || (p2 == NULL)) return false; 885 return SameObject(p1->obj(), p2->obj()); 886 } 887 888 bool BlockContinues(Assignment* assignment) { 889 if ((assignment == NULL) || (first_in_block_ == NULL)) return false; 890 if (assignment->op() != Token::ASSIGN) return false; 891 return PropertyOfSameObject(first_in_block_->target(), 892 assignment->target()); 893 } 894 895 void StartBlock(Assignment* assignment) { 896 first_in_block_ = assignment; 897 last_in_block_ = assignment; 898 block_size_ = 1; 899 } 900 901 void UpdateBlock(Assignment* assignment) { 902 last_in_block_ = assignment; 903 ++block_size_; 904 } 905 906 void EndBlock() { 907 if (block_size_ >= kMinInitializationBlock) { 908 first_in_block_->mark_block_start(); 909 last_in_block_->mark_block_end(); 910 } 911 last_in_block_ = first_in_block_ = NULL; 912 block_size_ = 0; 913 } 914 915 bool InBlock() { return first_in_block_ != NULL; } 916 917 Assignment* first_in_block_; 918 Assignment* last_in_block_; 919 int block_size_; 920 921 DISALLOW_COPY_AND_ASSIGN(InitializationBlockFinder); 922}; 923 924 925// A ThisNamedPropertyAssigmentFinder finds and marks statements of the form 926// this.x = ...;, where x is a named property. It also determines whether a 927// function contains only assignments of this type. 928class ThisNamedPropertyAssigmentFinder : public ParserFinder { 929 public: 930 explicit ThisNamedPropertyAssigmentFinder(Isolate* isolate) 931 : isolate_(isolate), 932 only_simple_this_property_assignments_(true), 933 names_(NULL), 934 assigned_arguments_(NULL), 935 assigned_constants_(NULL) {} 936 937 void Update(Scope* scope, Statement* stat) { 938 // Bail out if function already has property assignment that are 939 // not simple this property assignments. 940 if (!only_simple_this_property_assignments_) { 941 return; 942 } 943 944 // Check whether this statement is of the form this.x = ...; 945 Assignment* assignment = AsAssignment(stat); 946 if (IsThisPropertyAssignment(assignment)) { 947 HandleThisPropertyAssignment(scope, assignment); 948 } else { 949 only_simple_this_property_assignments_ = false; 950 } 951 } 952 953 // Returns whether only statements of the form this.x = y; where y is either a 954 // constant or a function argument was encountered. 955 bool only_simple_this_property_assignments() { 956 return only_simple_this_property_assignments_; 957 } 958 959 // Returns a fixed array containing three elements for each assignment of the 960 // form this.x = y; 961 Handle<FixedArray> GetThisPropertyAssignments() { 962 if (names_ == NULL) { 963 return isolate_->factory()->empty_fixed_array(); 964 } 965 ASSERT(names_ != NULL); 966 ASSERT(assigned_arguments_ != NULL); 967 ASSERT_EQ(names_->length(), assigned_arguments_->length()); 968 ASSERT_EQ(names_->length(), assigned_constants_->length()); 969 Handle<FixedArray> assignments = 970 isolate_->factory()->NewFixedArray(names_->length() * 3); 971 for (int i = 0; i < names_->length(); i++) { 972 assignments->set(i * 3, *names_->at(i)); 973 assignments->set(i * 3 + 1, Smi::FromInt(assigned_arguments_->at(i))); 974 assignments->set(i * 3 + 2, *assigned_constants_->at(i)); 975 } 976 return assignments; 977 } 978 979 private: 980 bool IsThisPropertyAssignment(Assignment* assignment) { 981 if (assignment != NULL) { 982 Property* property = assignment->target()->AsProperty(); 983 return assignment->op() == Token::ASSIGN 984 && property != NULL 985 && property->obj()->AsVariableProxy() != NULL 986 && property->obj()->AsVariableProxy()->is_this(); 987 } 988 return false; 989 } 990 991 void HandleThisPropertyAssignment(Scope* scope, Assignment* assignment) { 992 // Check that the property assigned to is a named property, which is not 993 // __proto__. 994 Property* property = assignment->target()->AsProperty(); 995 ASSERT(property != NULL); 996 Literal* literal = property->key()->AsLiteral(); 997 uint32_t dummy; 998 if (literal != NULL && 999 literal->handle()->IsString() && 1000 !String::cast(*(literal->handle()))->Equals( 1001 isolate_->heap()->Proto_symbol()) && 1002 !String::cast(*(literal->handle()))->AsArrayIndex(&dummy)) { 1003 Handle<String> key = Handle<String>::cast(literal->handle()); 1004 1005 // Check whether the value assigned is either a constant or matches the 1006 // name of one of the arguments to the function. 1007 if (assignment->value()->AsLiteral() != NULL) { 1008 // Constant assigned. 1009 Literal* literal = assignment->value()->AsLiteral(); 1010 AssignmentFromConstant(key, literal->handle()); 1011 return; 1012 } else if (assignment->value()->AsVariableProxy() != NULL) { 1013 // Variable assigned. 1014 Handle<String> name = 1015 assignment->value()->AsVariableProxy()->name(); 1016 // Check whether the variable assigned matches an argument name. 1017 for (int i = 0; i < scope->num_parameters(); i++) { 1018 if (*scope->parameter(i)->name() == *name) { 1019 // Assigned from function argument. 1020 AssignmentFromParameter(key, i); 1021 return; 1022 } 1023 } 1024 } 1025 } 1026 // It is not a simple "this.x = value;" assignment with a constant 1027 // or parameter value. 1028 AssignmentFromSomethingElse(); 1029 } 1030 1031 void AssignmentFromParameter(Handle<String> name, int index) { 1032 EnsureAllocation(); 1033 names_->Add(name); 1034 assigned_arguments_->Add(index); 1035 assigned_constants_->Add(isolate_->factory()->undefined_value()); 1036 } 1037 1038 void AssignmentFromConstant(Handle<String> name, Handle<Object> value) { 1039 EnsureAllocation(); 1040 names_->Add(name); 1041 assigned_arguments_->Add(-1); 1042 assigned_constants_->Add(value); 1043 } 1044 1045 void AssignmentFromSomethingElse() { 1046 // The this assignment is not a simple one. 1047 only_simple_this_property_assignments_ = false; 1048 } 1049 1050 void EnsureAllocation() { 1051 if (names_ == NULL) { 1052 ASSERT(assigned_arguments_ == NULL); 1053 ASSERT(assigned_constants_ == NULL); 1054 names_ = new ZoneStringList(4); 1055 assigned_arguments_ = new ZoneList<int>(4); 1056 assigned_constants_ = new ZoneObjectList(4); 1057 } 1058 } 1059 1060 Isolate* isolate_; 1061 bool only_simple_this_property_assignments_; 1062 ZoneStringList* names_; 1063 ZoneList<int>* assigned_arguments_; 1064 ZoneObjectList* assigned_constants_; 1065}; 1066 1067 1068void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, 1069 int end_token, 1070 bool* ok) { 1071 // SourceElements :: 1072 // (Statement)* <end_token> 1073 1074 // Allocate a target stack to use for this set of source 1075 // elements. This way, all scripts and functions get their own 1076 // target stack thus avoiding illegal breaks and continues across 1077 // functions. 1078 TargetScope scope(&this->target_stack_); 1079 1080 ASSERT(processor != NULL); 1081 InitializationBlockFinder block_finder; 1082 ThisNamedPropertyAssigmentFinder this_property_assignment_finder(isolate()); 1083 bool directive_prologue = true; // Parsing directive prologue. 1084 1085 while (peek() != end_token) { 1086 if (directive_prologue && peek() != Token::STRING) { 1087 directive_prologue = false; 1088 } 1089 1090 Scanner::Location token_loc = scanner().peek_location(); 1091 1092 Statement* stat; 1093 if (peek() == Token::FUNCTION) { 1094 // FunctionDeclaration is only allowed in the context of SourceElements 1095 // (Ecma 262 5th Edition, clause 14): 1096 // SourceElement: 1097 // Statement 1098 // FunctionDeclaration 1099 // Common language extension is to allow function declaration in place 1100 // of any statement. This language extension is disabled in strict mode. 1101 stat = ParseFunctionDeclaration(CHECK_OK); 1102 } else { 1103 stat = ParseStatement(NULL, CHECK_OK); 1104 } 1105 1106 if (stat == NULL || stat->IsEmpty()) { 1107 directive_prologue = false; // End of directive prologue. 1108 continue; 1109 } 1110 1111 if (directive_prologue) { 1112 // A shot at a directive. 1113 ExpressionStatement *e_stat; 1114 Literal *literal; 1115 // Still processing directive prologue? 1116 if ((e_stat = stat->AsExpressionStatement()) != NULL && 1117 (literal = e_stat->expression()->AsLiteral()) != NULL && 1118 literal->handle()->IsString()) { 1119 Handle<String> directive = Handle<String>::cast(literal->handle()); 1120 1121 // Check "use strict" directive (ES5 14.1). 1122 if (!top_scope_->is_strict_mode() && 1123 directive->Equals(isolate()->heap()->use_strict()) && 1124 token_loc.end_pos - token_loc.beg_pos == 1125 isolate()->heap()->use_strict()->length() + 2) { 1126 top_scope_->EnableStrictMode(); 1127 // "use strict" is the only directive for now. 1128 directive_prologue = false; 1129 } 1130 } else { 1131 // End of the directive prologue. 1132 directive_prologue = false; 1133 } 1134 } 1135 1136 // We find and mark the initialization blocks on top level code only. 1137 // This is because the optimization prevents reuse of the map transitions, 1138 // so it should be used only for code that will only be run once. 1139 if (top_scope_->is_global_scope()) { 1140 block_finder.Update(stat); 1141 } 1142 // Find and mark all assignments to named properties in this (this.x =) 1143 if (top_scope_->is_function_scope()) { 1144 this_property_assignment_finder.Update(top_scope_, stat); 1145 } 1146 processor->Add(stat); 1147 } 1148 1149 // Propagate the collected information on this property assignments. 1150 if (top_scope_->is_function_scope()) { 1151 bool only_simple_this_property_assignments = 1152 this_property_assignment_finder.only_simple_this_property_assignments() 1153 && top_scope_->declarations()->length() == 0; 1154 if (only_simple_this_property_assignments) { 1155 lexical_scope_->SetThisPropertyAssignmentInfo( 1156 only_simple_this_property_assignments, 1157 this_property_assignment_finder.GetThisPropertyAssignments()); 1158 } 1159 } 1160 return 0; 1161} 1162 1163 1164Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) { 1165 // Statement :: 1166 // Block 1167 // VariableStatement 1168 // EmptyStatement 1169 // ExpressionStatement 1170 // IfStatement 1171 // IterationStatement 1172 // ContinueStatement 1173 // BreakStatement 1174 // ReturnStatement 1175 // WithStatement 1176 // LabelledStatement 1177 // SwitchStatement 1178 // ThrowStatement 1179 // TryStatement 1180 // DebuggerStatement 1181 1182 // Note: Since labels can only be used by 'break' and 'continue' 1183 // statements, which themselves are only valid within blocks, 1184 // iterations or 'switch' statements (i.e., BreakableStatements), 1185 // labels can be simply ignored in all other cases; except for 1186 // trivial labeled break statements 'label: break label' which is 1187 // parsed into an empty statement. 1188 1189 // Keep the source position of the statement 1190 int statement_pos = scanner().peek_location().beg_pos; 1191 Statement* stmt = NULL; 1192 switch (peek()) { 1193 case Token::LBRACE: 1194 return ParseBlock(labels, ok); 1195 1196 case Token::CONST: // fall through 1197 case Token::VAR: 1198 stmt = ParseVariableStatement(ok); 1199 break; 1200 1201 case Token::SEMICOLON: 1202 Next(); 1203 return EmptyStatement(); 1204 1205 case Token::IF: 1206 stmt = ParseIfStatement(labels, ok); 1207 break; 1208 1209 case Token::DO: 1210 stmt = ParseDoWhileStatement(labels, ok); 1211 break; 1212 1213 case Token::WHILE: 1214 stmt = ParseWhileStatement(labels, ok); 1215 break; 1216 1217 case Token::FOR: 1218 stmt = ParseForStatement(labels, ok); 1219 break; 1220 1221 case Token::CONTINUE: 1222 stmt = ParseContinueStatement(ok); 1223 break; 1224 1225 case Token::BREAK: 1226 stmt = ParseBreakStatement(labels, ok); 1227 break; 1228 1229 case Token::RETURN: 1230 stmt = ParseReturnStatement(ok); 1231 break; 1232 1233 case Token::WITH: 1234 stmt = ParseWithStatement(labels, ok); 1235 break; 1236 1237 case Token::SWITCH: 1238 stmt = ParseSwitchStatement(labels, ok); 1239 break; 1240 1241 case Token::THROW: 1242 stmt = ParseThrowStatement(ok); 1243 break; 1244 1245 case Token::TRY: { 1246 // NOTE: It is somewhat complicated to have labels on 1247 // try-statements. When breaking out of a try-finally statement, 1248 // one must take great care not to treat it as a 1249 // fall-through. It is much easier just to wrap the entire 1250 // try-statement in a statement block and put the labels there 1251 Block* result = new(zone()) Block(labels, 1, false); 1252 Target target(&this->target_stack_, result); 1253 TryStatement* statement = ParseTryStatement(CHECK_OK); 1254 if (statement) { 1255 statement->set_statement_pos(statement_pos); 1256 } 1257 if (result) result->AddStatement(statement); 1258 return result; 1259 } 1260 1261 case Token::FUNCTION: { 1262 // In strict mode, FunctionDeclaration is only allowed in the context 1263 // of SourceElements. 1264 if (top_scope_->is_strict_mode()) { 1265 ReportMessageAt(scanner().peek_location(), "strict_function", 1266 Vector<const char*>::empty()); 1267 *ok = false; 1268 return NULL; 1269 } 1270 return ParseFunctionDeclaration(ok); 1271 } 1272 1273 case Token::NATIVE: 1274 return ParseNativeDeclaration(ok); 1275 1276 case Token::DEBUGGER: 1277 stmt = ParseDebuggerStatement(ok); 1278 break; 1279 1280 default: 1281 stmt = ParseExpressionOrLabelledStatement(labels, ok); 1282 } 1283 1284 // Store the source position of the statement 1285 if (stmt != NULL) stmt->set_statement_pos(statement_pos); 1286 return stmt; 1287} 1288 1289 1290VariableProxy* Parser::Declare(Handle<String> name, 1291 Variable::Mode mode, 1292 FunctionLiteral* fun, 1293 bool resolve, 1294 bool* ok) { 1295 Variable* var = NULL; 1296 // If we are inside a function, a declaration of a variable 1297 // is a truly local variable, and the scope of the variable 1298 // is always the function scope. 1299 1300 // If a function scope exists, then we can statically declare this 1301 // variable and also set its mode. In any case, a Declaration node 1302 // will be added to the scope so that the declaration can be added 1303 // to the corresponding activation frame at runtime if necessary. 1304 // For instance declarations inside an eval scope need to be added 1305 // to the calling function context. 1306 if (top_scope_->is_function_scope()) { 1307 // Declare the variable in the function scope. 1308 var = top_scope_->LocalLookup(name); 1309 if (var == NULL) { 1310 // Declare the name. 1311 var = top_scope_->DeclareLocal(name, mode, Scope::VAR_OR_CONST); 1312 } else { 1313 // The name was declared before; check for conflicting 1314 // re-declarations. If the previous declaration was a const or the 1315 // current declaration is a const then we have a conflict. There is 1316 // similar code in runtime.cc in the Declare functions. 1317 if ((mode == Variable::CONST) || (var->mode() == Variable::CONST)) { 1318 // We only have vars and consts in declarations. 1319 ASSERT(var->mode() == Variable::VAR || 1320 var->mode() == Variable::CONST); 1321 const char* type = (var->mode() == Variable::VAR) ? "var" : "const"; 1322 Handle<String> type_string = 1323 isolate()->factory()->NewStringFromUtf8(CStrVector(type), TENURED); 1324 Expression* expression = 1325 NewThrowTypeError(isolate()->factory()->redeclaration_symbol(), 1326 type_string, name); 1327 top_scope_->SetIllegalRedeclaration(expression); 1328 } 1329 } 1330 } 1331 1332 // We add a declaration node for every declaration. The compiler 1333 // will only generate code if necessary. In particular, declarations 1334 // for inner local variables that do not represent functions won't 1335 // result in any generated code. 1336 // 1337 // Note that we always add an unresolved proxy even if it's not 1338 // used, simply because we don't know in this method (w/o extra 1339 // parameters) if the proxy is needed or not. The proxy will be 1340 // bound during variable resolution time unless it was pre-bound 1341 // below. 1342 // 1343 // WARNING: This will lead to multiple declaration nodes for the 1344 // same variable if it is declared several times. This is not a 1345 // semantic issue as long as we keep the source order, but it may be 1346 // a performance issue since it may lead to repeated 1347 // Runtime::DeclareContextSlot() calls. 1348 VariableProxy* proxy = top_scope_->NewUnresolved(name, inside_with()); 1349 top_scope_->AddDeclaration(new(zone()) Declaration(proxy, mode, fun)); 1350 1351 // For global const variables we bind the proxy to a variable. 1352 if (mode == Variable::CONST && top_scope_->is_global_scope()) { 1353 ASSERT(resolve); // should be set by all callers 1354 Variable::Kind kind = Variable::NORMAL; 1355 var = new(zone()) Variable(top_scope_, name, Variable::CONST, true, kind); 1356 } 1357 1358 // If requested and we have a local variable, bind the proxy to the variable 1359 // at parse-time. This is used for functions (and consts) declared inside 1360 // statements: the corresponding function (or const) variable must be in the 1361 // function scope and not a statement-local scope, e.g. as provided with a 1362 // 'with' statement: 1363 // 1364 // with (obj) { 1365 // function f() {} 1366 // } 1367 // 1368 // which is translated into: 1369 // 1370 // with (obj) { 1371 // // in this case this is not: 'var f; f = function () {};' 1372 // var f = function () {}; 1373 // } 1374 // 1375 // Note that if 'f' is accessed from inside the 'with' statement, it 1376 // will be allocated in the context (because we must be able to look 1377 // it up dynamically) but it will also be accessed statically, i.e., 1378 // with a context slot index and a context chain length for this 1379 // initialization code. Thus, inside the 'with' statement, we need 1380 // both access to the static and the dynamic context chain; the 1381 // runtime needs to provide both. 1382 if (resolve && var != NULL) proxy->BindTo(var); 1383 1384 return proxy; 1385} 1386 1387 1388// Language extension which is only enabled for source files loaded 1389// through the API's extension mechanism. A native function 1390// declaration is resolved by looking up the function through a 1391// callback provided by the extension. 1392Statement* Parser::ParseNativeDeclaration(bool* ok) { 1393 if (extension_ == NULL) { 1394 ReportUnexpectedToken(Token::NATIVE); 1395 *ok = false; 1396 return NULL; 1397 } 1398 1399 Expect(Token::NATIVE, CHECK_OK); 1400 Expect(Token::FUNCTION, CHECK_OK); 1401 Handle<String> name = ParseIdentifier(CHECK_OK); 1402 Expect(Token::LPAREN, CHECK_OK); 1403 bool done = (peek() == Token::RPAREN); 1404 while (!done) { 1405 ParseIdentifier(CHECK_OK); 1406 done = (peek() == Token::RPAREN); 1407 if (!done) { 1408 Expect(Token::COMMA, CHECK_OK); 1409 } 1410 } 1411 Expect(Token::RPAREN, CHECK_OK); 1412 Expect(Token::SEMICOLON, CHECK_OK); 1413 1414 // Make sure that the function containing the native declaration 1415 // isn't lazily compiled. The extension structures are only 1416 // accessible while parsing the first time not when reparsing 1417 // because of lazy compilation. 1418 top_scope_->ForceEagerCompilation(); 1419 1420 // Compute the function template for the native function. 1421 v8::Handle<v8::FunctionTemplate> fun_template = 1422 extension_->GetNativeFunction(v8::Utils::ToLocal(name)); 1423 ASSERT(!fun_template.IsEmpty()); 1424 1425 // Instantiate the function and create a shared function info from it. 1426 Handle<JSFunction> fun = Utils::OpenHandle(*fun_template->GetFunction()); 1427 const int literals = fun->NumberOfLiterals(); 1428 Handle<Code> code = Handle<Code>(fun->shared()->code()); 1429 Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub()); 1430 Handle<SharedFunctionInfo> shared = 1431 isolate()->factory()->NewSharedFunctionInfo(name, literals, code, 1432 Handle<SerializedScopeInfo>(fun->shared()->scope_info())); 1433 shared->set_construct_stub(*construct_stub); 1434 1435 // Copy the function data to the shared function info. 1436 shared->set_function_data(fun->shared()->function_data()); 1437 int parameters = fun->shared()->formal_parameter_count(); 1438 shared->set_formal_parameter_count(parameters); 1439 1440 // TODO(1240846): It's weird that native function declarations are 1441 // introduced dynamically when we meet their declarations, whereas 1442 // other functions are setup when entering the surrounding scope. 1443 SharedFunctionInfoLiteral* lit = 1444 new(zone()) SharedFunctionInfoLiteral(shared); 1445 VariableProxy* var = Declare(name, Variable::VAR, NULL, true, CHECK_OK); 1446 return new(zone()) ExpressionStatement(new(zone()) Assignment( 1447 Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); 1448} 1449 1450 1451Statement* Parser::ParseFunctionDeclaration(bool* ok) { 1452 // FunctionDeclaration :: 1453 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1454 Expect(Token::FUNCTION, CHECK_OK); 1455 int function_token_position = scanner().location().beg_pos; 1456 bool is_reserved = false; 1457 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); 1458 FunctionLiteral* fun = ParseFunctionLiteral(name, 1459 is_reserved, 1460 function_token_position, 1461 DECLARATION, 1462 CHECK_OK); 1463 // Even if we're not at the top-level of the global or a function 1464 // scope, we treat is as such and introduce the function with it's 1465 // initial value upon entering the corresponding scope. 1466 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1467 return EmptyStatement(); 1468} 1469 1470 1471Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { 1472 // Block :: 1473 // '{' Statement* '}' 1474 1475 // Note that a Block does not introduce a new execution scope! 1476 // (ECMA-262, 3rd, 12.2) 1477 // 1478 // Construct block expecting 16 statements. 1479 Block* result = new(zone()) Block(labels, 16, false); 1480 Target target(&this->target_stack_, result); 1481 Expect(Token::LBRACE, CHECK_OK); 1482 while (peek() != Token::RBRACE) { 1483 Statement* stat = ParseStatement(NULL, CHECK_OK); 1484 if (stat && !stat->IsEmpty()) result->AddStatement(stat); 1485 } 1486 Expect(Token::RBRACE, CHECK_OK); 1487 return result; 1488} 1489 1490 1491Block* Parser::ParseVariableStatement(bool* ok) { 1492 // VariableStatement :: 1493 // VariableDeclarations ';' 1494 1495 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature 1496 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); 1497 ExpectSemicolon(CHECK_OK); 1498 return result; 1499} 1500 1501 1502bool Parser::IsEvalOrArguments(Handle<String> string) { 1503 return string.is_identical_to(isolate()->factory()->eval_symbol()) || 1504 string.is_identical_to(isolate()->factory()->arguments_symbol()); 1505} 1506 1507 1508// If the variable declaration declares exactly one non-const 1509// variable, then *var is set to that variable. In all other cases, 1510// *var is untouched; in particular, it is the caller's responsibility 1511// to initialize it properly. This mechanism is used for the parsing 1512// of 'for-in' loops. 1513Block* Parser::ParseVariableDeclarations(bool accept_IN, 1514 Expression** var, 1515 bool* ok) { 1516 // VariableDeclarations :: 1517 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 1518 1519 Variable::Mode mode = Variable::VAR; 1520 bool is_const = false; 1521 if (peek() == Token::VAR) { 1522 Consume(Token::VAR); 1523 } else if (peek() == Token::CONST) { 1524 Consume(Token::CONST); 1525 if (top_scope_->is_strict_mode()) { 1526 ReportMessage("strict_const", Vector<const char*>::empty()); 1527 *ok = false; 1528 return NULL; 1529 } 1530 mode = Variable::CONST; 1531 is_const = true; 1532 } else { 1533 UNREACHABLE(); // by current callers 1534 } 1535 1536 // The scope of a variable/const declared anywhere inside a function 1537 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1538 // transform a source-level variable/const declaration into a (Function) 1539 // Scope declaration, and rewrite the source-level initialization into an 1540 // assignment statement. We use a block to collect multiple assignments. 1541 // 1542 // We mark the block as initializer block because we don't want the 1543 // rewriter to add a '.result' assignment to such a block (to get compliant 1544 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1545 // reasons when pretty-printing. Also, unless an assignment (initialization) 1546 // is inside an initializer block, it is ignored. 1547 // 1548 // Create new block with one expected declaration. 1549 Block* block = new(zone()) Block(NULL, 1, true); 1550 VariableProxy* last_var = NULL; // the last variable declared 1551 int nvars = 0; // the number of variables declared 1552 do { 1553 if (fni_ != NULL) fni_->Enter(); 1554 1555 // Parse variable name. 1556 if (nvars > 0) Consume(Token::COMMA); 1557 Handle<String> name = ParseIdentifier(CHECK_OK); 1558 if (fni_ != NULL) fni_->PushVariableName(name); 1559 1560 // Strict mode variables may not be named eval or arguments 1561 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 1562 ReportMessage("strict_var_name", Vector<const char*>::empty()); 1563 *ok = false; 1564 return NULL; 1565 } 1566 1567 // Declare variable. 1568 // Note that we *always* must treat the initial value via a separate init 1569 // assignment for variables and constants because the value must be assigned 1570 // when the variable is encountered in the source. But the variable/constant 1571 // is declared (and set to 'undefined') upon entering the function within 1572 // which the variable or constant is declared. Only function variables have 1573 // an initial value in the declaration (because they are initialized upon 1574 // entering the function). 1575 // 1576 // If we have a const declaration, in an inner scope, the proxy is always 1577 // bound to the declared variable (independent of possibly surrounding with 1578 // statements). 1579 last_var = Declare(name, mode, NULL, 1580 is_const /* always bound for CONST! */, 1581 CHECK_OK); 1582 nvars++; 1583 if (top_scope_->num_var_or_const() > kMaxNumFunctionLocals) { 1584 ReportMessageAt(scanner().location(), "too_many_variables", 1585 Vector<const char*>::empty()); 1586 *ok = false; 1587 return NULL; 1588 } 1589 1590 // Parse initialization expression if present and/or needed. A 1591 // declaration of the form: 1592 // 1593 // var v = x; 1594 // 1595 // is syntactic sugar for: 1596 // 1597 // var v; v = x; 1598 // 1599 // In particular, we need to re-lookup 'v' as it may be a 1600 // different 'v' than the 'v' in the declaration (if we are inside 1601 // a 'with' statement that makes a object property with name 'v' 1602 // visible). 1603 // 1604 // However, note that const declarations are different! A const 1605 // declaration of the form: 1606 // 1607 // const c = x; 1608 // 1609 // is *not* syntactic sugar for: 1610 // 1611 // const c; c = x; 1612 // 1613 // The "variable" c initialized to x is the same as the declared 1614 // one - there is no re-lookup (see the last parameter of the 1615 // Declare() call above). 1616 1617 Expression* value = NULL; 1618 int position = -1; 1619 if (peek() == Token::ASSIGN) { 1620 Expect(Token::ASSIGN, CHECK_OK); 1621 position = scanner().location().beg_pos; 1622 value = ParseAssignmentExpression(accept_IN, CHECK_OK); 1623 // Don't infer if it is "a = function(){...}();"-like expression. 1624 if (fni_ != NULL && value->AsCall() == NULL) fni_->Infer(); 1625 } 1626 1627 // Make sure that 'const c' actually initializes 'c' to undefined 1628 // even though it seems like a stupid thing to do. 1629 if (value == NULL && is_const) { 1630 value = GetLiteralUndefined(); 1631 } 1632 1633 // Global variable declarations must be compiled in a specific 1634 // way. When the script containing the global variable declaration 1635 // is entered, the global variable must be declared, so that if it 1636 // doesn't exist (not even in a prototype of the global object) it 1637 // gets created with an initial undefined value. This is handled 1638 // by the declarations part of the function representing the 1639 // top-level global code; see Runtime::DeclareGlobalVariable. If 1640 // it already exists (in the object or in a prototype), it is 1641 // *not* touched until the variable declaration statement is 1642 // executed. 1643 // 1644 // Executing the variable declaration statement will always 1645 // guarantee to give the global object a "local" variable; a 1646 // variable defined in the global object and not in any 1647 // prototype. This way, global variable declarations can shadow 1648 // properties in the prototype chain, but only after the variable 1649 // declaration statement has been executed. This is important in 1650 // browsers where the global object (window) has lots of 1651 // properties defined in prototype objects. 1652 1653 if (top_scope_->is_global_scope()) { 1654 // Compute the arguments for the runtime call. 1655 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3); 1656 // We have at least 1 parameter. 1657 arguments->Add(new(zone()) Literal(name)); 1658 CallRuntime* initialize; 1659 1660 if (is_const) { 1661 arguments->Add(value); 1662 value = NULL; // zap the value to avoid the unnecessary assignment 1663 1664 // Construct the call to Runtime_InitializeConstGlobal 1665 // and add it to the initialization statement block. 1666 // Note that the function does different things depending on 1667 // the number of arguments (1 or 2). 1668 initialize = 1669 new(zone()) CallRuntime( 1670 isolate()->factory()->InitializeConstGlobal_symbol(), 1671 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), 1672 arguments); 1673 } else { 1674 // Add strict mode. 1675 // We may want to pass singleton to avoid Literal allocations. 1676 arguments->Add(NewNumberLiteral( 1677 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); 1678 1679 // Be careful not to assign a value to the global variable if 1680 // we're in a with. The initialization value should not 1681 // necessarily be stored in the global object in that case, 1682 // which is why we need to generate a separate assignment node. 1683 if (value != NULL && !inside_with()) { 1684 arguments->Add(value); 1685 value = NULL; // zap the value to avoid the unnecessary assignment 1686 } 1687 1688 // Construct the call to Runtime_InitializeVarGlobal 1689 // and add it to the initialization statement block. 1690 // Note that the function does different things depending on 1691 // the number of arguments (2 or 3). 1692 initialize = 1693 new(zone()) CallRuntime( 1694 isolate()->factory()->InitializeVarGlobal_symbol(), 1695 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), 1696 arguments); 1697 } 1698 1699 block->AddStatement(new(zone()) ExpressionStatement(initialize)); 1700 } 1701 1702 // Add an assignment node to the initialization statement block if 1703 // we still have a pending initialization value. We must distinguish 1704 // between variables and constants: Variable initializations are simply 1705 // assignments (with all the consequences if they are inside a 'with' 1706 // statement - they may change a 'with' object property). Constant 1707 // initializations always assign to the declared constant which is 1708 // always at the function scope level. This is only relevant for 1709 // dynamically looked-up variables and constants (the start context 1710 // for constant lookups is always the function context, while it is 1711 // the top context for variables). Sigh... 1712 if (value != NULL) { 1713 Token::Value op = (is_const ? Token::INIT_CONST : Token::INIT_VAR); 1714 Assignment* assignment = 1715 new(zone()) Assignment(op, last_var, value, position); 1716 if (block) { 1717 block->AddStatement(new(zone()) ExpressionStatement(assignment)); 1718 } 1719 } 1720 1721 if (fni_ != NULL) fni_->Leave(); 1722 } while (peek() == Token::COMMA); 1723 1724 if (!is_const && nvars == 1) { 1725 // We have a single, non-const variable. 1726 ASSERT(last_var != NULL); 1727 *var = last_var; 1728 } 1729 1730 return block; 1731} 1732 1733 1734static bool ContainsLabel(ZoneStringList* labels, Handle<String> label) { 1735 ASSERT(!label.is_null()); 1736 if (labels != NULL) 1737 for (int i = labels->length(); i-- > 0; ) 1738 if (labels->at(i).is_identical_to(label)) 1739 return true; 1740 1741 return false; 1742} 1743 1744 1745Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 1746 bool* ok) { 1747 // ExpressionStatement | LabelledStatement :: 1748 // Expression ';' 1749 // Identifier ':' Statement 1750 bool starts_with_idenfifier = peek_any_identifier(); 1751 Expression* expr = ParseExpression(true, CHECK_OK); 1752 if (peek() == Token::COLON && starts_with_idenfifier && expr && 1753 expr->AsVariableProxy() != NULL && 1754 !expr->AsVariableProxy()->is_this()) { 1755 // Expression is a single identifier, and not, e.g., a parenthesized 1756 // identifier. 1757 VariableProxy* var = expr->AsVariableProxy(); 1758 Handle<String> label = var->name(); 1759 // TODO(1240780): We don't check for redeclaration of labels 1760 // during preparsing since keeping track of the set of active 1761 // labels requires nontrivial changes to the way scopes are 1762 // structured. However, these are probably changes we want to 1763 // make later anyway so we should go back and fix this then. 1764 if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) { 1765 SmartPointer<char> c_string = label->ToCString(DISALLOW_NULLS); 1766 const char* elms[2] = { "Label", *c_string }; 1767 Vector<const char*> args(elms, 2); 1768 ReportMessage("redeclaration", args); 1769 *ok = false; 1770 return NULL; 1771 } 1772 if (labels == NULL) labels = new ZoneStringList(4); 1773 labels->Add(label); 1774 // Remove the "ghost" variable that turned out to be a label 1775 // from the top scope. This way, we don't try to resolve it 1776 // during the scope processing. 1777 top_scope_->RemoveUnresolved(var); 1778 Expect(Token::COLON, CHECK_OK); 1779 return ParseStatement(labels, ok); 1780 } 1781 1782 // Parsed expression statement. 1783 ExpectSemicolon(CHECK_OK); 1784 return new(zone()) ExpressionStatement(expr); 1785} 1786 1787 1788IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { 1789 // IfStatement :: 1790 // 'if' '(' Expression ')' Statement ('else' Statement)? 1791 1792 Expect(Token::IF, CHECK_OK); 1793 Expect(Token::LPAREN, CHECK_OK); 1794 Expression* condition = ParseExpression(true, CHECK_OK); 1795 Expect(Token::RPAREN, CHECK_OK); 1796 Statement* then_statement = ParseStatement(labels, CHECK_OK); 1797 Statement* else_statement = NULL; 1798 if (peek() == Token::ELSE) { 1799 Next(); 1800 else_statement = ParseStatement(labels, CHECK_OK); 1801 } else { 1802 else_statement = EmptyStatement(); 1803 } 1804 return new(zone()) IfStatement(condition, then_statement, else_statement); 1805} 1806 1807 1808Statement* Parser::ParseContinueStatement(bool* ok) { 1809 // ContinueStatement :: 1810 // 'continue' Identifier? ';' 1811 1812 Expect(Token::CONTINUE, CHECK_OK); 1813 Handle<String> label = Handle<String>::null(); 1814 Token::Value tok = peek(); 1815 if (!scanner().has_line_terminator_before_next() && 1816 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1817 label = ParseIdentifier(CHECK_OK); 1818 } 1819 IterationStatement* target = NULL; 1820 target = LookupContinueTarget(label, CHECK_OK); 1821 if (target == NULL) { 1822 // Illegal continue statement. 1823 const char* message = "illegal_continue"; 1824 Vector<Handle<String> > args; 1825 if (!label.is_null()) { 1826 message = "unknown_label"; 1827 args = Vector<Handle<String> >(&label, 1); 1828 } 1829 ReportMessageAt(scanner().location(), message, args); 1830 *ok = false; 1831 return NULL; 1832 } 1833 ExpectSemicolon(CHECK_OK); 1834 return new(zone()) ContinueStatement(target); 1835} 1836 1837 1838Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 1839 // BreakStatement :: 1840 // 'break' Identifier? ';' 1841 1842 Expect(Token::BREAK, CHECK_OK); 1843 Handle<String> label; 1844 Token::Value tok = peek(); 1845 if (!scanner().has_line_terminator_before_next() && 1846 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1847 label = ParseIdentifier(CHECK_OK); 1848 } 1849 // Parse labeled break statements that target themselves into 1850 // empty statements, e.g. 'l1: l2: l3: break l2;' 1851 if (!label.is_null() && ContainsLabel(labels, label)) { 1852 return EmptyStatement(); 1853 } 1854 BreakableStatement* target = NULL; 1855 target = LookupBreakTarget(label, CHECK_OK); 1856 if (target == NULL) { 1857 // Illegal break statement. 1858 const char* message = "illegal_break"; 1859 Vector<Handle<String> > args; 1860 if (!label.is_null()) { 1861 message = "unknown_label"; 1862 args = Vector<Handle<String> >(&label, 1); 1863 } 1864 ReportMessageAt(scanner().location(), message, args); 1865 *ok = false; 1866 return NULL; 1867 } 1868 ExpectSemicolon(CHECK_OK); 1869 return new(zone()) BreakStatement(target); 1870} 1871 1872 1873Statement* Parser::ParseReturnStatement(bool* ok) { 1874 // ReturnStatement :: 1875 // 'return' Expression? ';' 1876 1877 // Consume the return token. It is necessary to do the before 1878 // reporting any errors on it, because of the way errors are 1879 // reported (underlining). 1880 Expect(Token::RETURN, CHECK_OK); 1881 1882 // An ECMAScript program is considered syntactically incorrect if it 1883 // contains a return statement that is not within the body of a 1884 // function. See ECMA-262, section 12.9, page 67. 1885 // 1886 // To be consistent with KJS we report the syntax error at runtime. 1887 if (!top_scope_->is_function_scope()) { 1888 Handle<String> type = isolate()->factory()->illegal_return_symbol(); 1889 Expression* throw_error = NewThrowSyntaxError(type, Handle<Object>::null()); 1890 return new(zone()) ExpressionStatement(throw_error); 1891 } 1892 1893 Token::Value tok = peek(); 1894 if (scanner().has_line_terminator_before_next() || 1895 tok == Token::SEMICOLON || 1896 tok == Token::RBRACE || 1897 tok == Token::EOS) { 1898 ExpectSemicolon(CHECK_OK); 1899 return new(zone()) ReturnStatement(GetLiteralUndefined()); 1900 } 1901 1902 Expression* expr = ParseExpression(true, CHECK_OK); 1903 ExpectSemicolon(CHECK_OK); 1904 return new(zone()) ReturnStatement(expr); 1905} 1906 1907 1908Block* Parser::WithHelper(Expression* obj, 1909 ZoneStringList* labels, 1910 bool is_catch_block, 1911 bool* ok) { 1912 // Parse the statement and collect escaping labels. 1913 ZoneList<Label*>* target_list = new ZoneList<Label*>(0); 1914 TargetCollector collector(target_list); 1915 Statement* stat; 1916 { Target target(&this->target_stack_, &collector); 1917 with_nesting_level_++; 1918 top_scope_->RecordWithStatement(); 1919 stat = ParseStatement(labels, CHECK_OK); 1920 with_nesting_level_--; 1921 } 1922 // Create resulting block with two statements. 1923 // 1: Evaluate the with expression. 1924 // 2: The try-finally block evaluating the body. 1925 Block* result = new(zone()) Block(NULL, 2, false); 1926 1927 if (result != NULL) { 1928 result->AddStatement(new(zone()) WithEnterStatement(obj, is_catch_block)); 1929 1930 // Create body block. 1931 Block* body = new(zone()) Block(NULL, 1, false); 1932 body->AddStatement(stat); 1933 1934 // Create exit block. 1935 Block* exit = new(zone()) Block(NULL, 1, false); 1936 exit->AddStatement(new(zone()) WithExitStatement()); 1937 1938 // Return a try-finally statement. 1939 TryFinallyStatement* wrapper = new(zone()) TryFinallyStatement(body, exit); 1940 wrapper->set_escaping_targets(collector.targets()); 1941 result->AddStatement(wrapper); 1942 } 1943 return result; 1944} 1945 1946 1947Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 1948 // WithStatement :: 1949 // 'with' '(' Expression ')' Statement 1950 1951 Expect(Token::WITH, CHECK_OK); 1952 1953 if (top_scope_->is_strict_mode()) { 1954 ReportMessage("strict_mode_with", Vector<const char*>::empty()); 1955 *ok = false; 1956 return NULL; 1957 } 1958 1959 Expect(Token::LPAREN, CHECK_OK); 1960 Expression* expr = ParseExpression(true, CHECK_OK); 1961 Expect(Token::RPAREN, CHECK_OK); 1962 1963 return WithHelper(expr, labels, false, CHECK_OK); 1964} 1965 1966 1967CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 1968 // CaseClause :: 1969 // 'case' Expression ':' Statement* 1970 // 'default' ':' Statement* 1971 1972 Expression* label = NULL; // NULL expression indicates default case 1973 if (peek() == Token::CASE) { 1974 Expect(Token::CASE, CHECK_OK); 1975 label = ParseExpression(true, CHECK_OK); 1976 } else { 1977 Expect(Token::DEFAULT, CHECK_OK); 1978 if (*default_seen_ptr) { 1979 ReportMessage("multiple_defaults_in_switch", 1980 Vector<const char*>::empty()); 1981 *ok = false; 1982 return NULL; 1983 } 1984 *default_seen_ptr = true; 1985 } 1986 Expect(Token::COLON, CHECK_OK); 1987 int pos = scanner().location().beg_pos; 1988 ZoneList<Statement*>* statements = new ZoneList<Statement*>(5); 1989 while (peek() != Token::CASE && 1990 peek() != Token::DEFAULT && 1991 peek() != Token::RBRACE) { 1992 Statement* stat = ParseStatement(NULL, CHECK_OK); 1993 statements->Add(stat); 1994 } 1995 1996 return new(zone()) CaseClause(label, statements, pos); 1997} 1998 1999 2000SwitchStatement* Parser::ParseSwitchStatement(ZoneStringList* labels, 2001 bool* ok) { 2002 // SwitchStatement :: 2003 // 'switch' '(' Expression ')' '{' CaseClause* '}' 2004 2005 SwitchStatement* statement = new(zone()) SwitchStatement(labels); 2006 Target target(&this->target_stack_, statement); 2007 2008 Expect(Token::SWITCH, CHECK_OK); 2009 Expect(Token::LPAREN, CHECK_OK); 2010 Expression* tag = ParseExpression(true, CHECK_OK); 2011 Expect(Token::RPAREN, CHECK_OK); 2012 2013 bool default_seen = false; 2014 ZoneList<CaseClause*>* cases = new ZoneList<CaseClause*>(4); 2015 Expect(Token::LBRACE, CHECK_OK); 2016 while (peek() != Token::RBRACE) { 2017 CaseClause* clause = ParseCaseClause(&default_seen, CHECK_OK); 2018 cases->Add(clause); 2019 } 2020 Expect(Token::RBRACE, CHECK_OK); 2021 2022 if (statement) statement->Initialize(tag, cases); 2023 return statement; 2024} 2025 2026 2027Statement* Parser::ParseThrowStatement(bool* ok) { 2028 // ThrowStatement :: 2029 // 'throw' Expression ';' 2030 2031 Expect(Token::THROW, CHECK_OK); 2032 int pos = scanner().location().beg_pos; 2033 if (scanner().has_line_terminator_before_next()) { 2034 ReportMessage("newline_after_throw", Vector<const char*>::empty()); 2035 *ok = false; 2036 return NULL; 2037 } 2038 Expression* exception = ParseExpression(true, CHECK_OK); 2039 ExpectSemicolon(CHECK_OK); 2040 2041 return new(zone()) ExpressionStatement(new(zone()) Throw(exception, pos)); 2042} 2043 2044 2045TryStatement* Parser::ParseTryStatement(bool* ok) { 2046 // TryStatement :: 2047 // 'try' Block Catch 2048 // 'try' Block Finally 2049 // 'try' Block Catch Finally 2050 // 2051 // Catch :: 2052 // 'catch' '(' Identifier ')' Block 2053 // 2054 // Finally :: 2055 // 'finally' Block 2056 2057 Expect(Token::TRY, CHECK_OK); 2058 2059 ZoneList<Label*>* target_list = new ZoneList<Label*>(0); 2060 TargetCollector collector(target_list); 2061 Block* try_block; 2062 2063 { Target target(&this->target_stack_, &collector); 2064 try_block = ParseBlock(NULL, CHECK_OK); 2065 } 2066 2067 Block* catch_block = NULL; 2068 Variable* catch_var = NULL; 2069 Block* finally_block = NULL; 2070 2071 Token::Value tok = peek(); 2072 if (tok != Token::CATCH && tok != Token::FINALLY) { 2073 ReportMessage("no_catch_or_finally", Vector<const char*>::empty()); 2074 *ok = false; 2075 return NULL; 2076 } 2077 2078 // If we can break out from the catch block and there is a finally block, 2079 // then we will need to collect jump targets from the catch block. Since 2080 // we don't know yet if there will be a finally block, we always collect 2081 // the jump targets. 2082 ZoneList<Label*>* catch_target_list = new ZoneList<Label*>(0); 2083 TargetCollector catch_collector(catch_target_list); 2084 bool has_catch = false; 2085 if (tok == Token::CATCH) { 2086 has_catch = true; 2087 Consume(Token::CATCH); 2088 2089 Expect(Token::LPAREN, CHECK_OK); 2090 Handle<String> name = ParseIdentifier(CHECK_OK); 2091 2092 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { 2093 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); 2094 *ok = false; 2095 return NULL; 2096 } 2097 2098 Expect(Token::RPAREN, CHECK_OK); 2099 2100 if (peek() == Token::LBRACE) { 2101 // Allocate a temporary for holding the finally state while 2102 // executing the finally block. 2103 catch_var = 2104 top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol()); 2105 Literal* name_literal = new(zone()) Literal(name); 2106 VariableProxy* catch_var_use = new(zone()) VariableProxy(catch_var); 2107 Expression* obj = 2108 new(zone()) CatchExtensionObject(name_literal, catch_var_use); 2109 { Target target(&this->target_stack_, &catch_collector); 2110 catch_block = WithHelper(obj, NULL, true, CHECK_OK); 2111 } 2112 } else { 2113 Expect(Token::LBRACE, CHECK_OK); 2114 } 2115 2116 tok = peek(); 2117 } 2118 2119 if (tok == Token::FINALLY || !has_catch) { 2120 Consume(Token::FINALLY); 2121 // Declare a variable for holding the finally state while 2122 // executing the finally block. 2123 finally_block = ParseBlock(NULL, CHECK_OK); 2124 } 2125 2126 // Simplify the AST nodes by converting: 2127 // 'try { } catch { } finally { }' 2128 // to: 2129 // 'try { try { } catch { } } finally { }' 2130 2131 if (catch_block != NULL && finally_block != NULL) { 2132 VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var); 2133 TryCatchStatement* statement = 2134 new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block); 2135 statement->set_escaping_targets(collector.targets()); 2136 try_block = new(zone()) Block(NULL, 1, false); 2137 try_block->AddStatement(statement); 2138 catch_block = NULL; 2139 } 2140 2141 TryStatement* result = NULL; 2142 if (catch_block != NULL) { 2143 ASSERT(finally_block == NULL); 2144 VariableProxy* catch_var_defn = new(zone()) VariableProxy(catch_var); 2145 result = 2146 new(zone()) TryCatchStatement(try_block, catch_var_defn, catch_block); 2147 result->set_escaping_targets(collector.targets()); 2148 } else { 2149 ASSERT(finally_block != NULL); 2150 result = new(zone()) TryFinallyStatement(try_block, finally_block); 2151 // Add the jump targets of the try block and the catch block. 2152 for (int i = 0; i < collector.targets()->length(); i++) { 2153 catch_collector.AddTarget(collector.targets()->at(i)); 2154 } 2155 result->set_escaping_targets(catch_collector.targets()); 2156 } 2157 2158 return result; 2159} 2160 2161 2162DoWhileStatement* Parser::ParseDoWhileStatement(ZoneStringList* labels, 2163 bool* ok) { 2164 // DoStatement :: 2165 // 'do' Statement 'while' '(' Expression ')' ';' 2166 2167 DoWhileStatement* loop = new(zone()) DoWhileStatement(labels); 2168 Target target(&this->target_stack_, loop); 2169 2170 Expect(Token::DO, CHECK_OK); 2171 Statement* body = ParseStatement(NULL, CHECK_OK); 2172 Expect(Token::WHILE, CHECK_OK); 2173 Expect(Token::LPAREN, CHECK_OK); 2174 2175 if (loop != NULL) { 2176 int position = scanner().location().beg_pos; 2177 loop->set_condition_position(position); 2178 } 2179 2180 Expression* cond = ParseExpression(true, CHECK_OK); 2181 Expect(Token::RPAREN, CHECK_OK); 2182 2183 // Allow do-statements to be terminated with and without 2184 // semi-colons. This allows code such as 'do;while(0)return' to 2185 // parse, which would not be the case if we had used the 2186 // ExpectSemicolon() functionality here. 2187 if (peek() == Token::SEMICOLON) Consume(Token::SEMICOLON); 2188 2189 if (loop != NULL) loop->Initialize(cond, body); 2190 return loop; 2191} 2192 2193 2194WhileStatement* Parser::ParseWhileStatement(ZoneStringList* labels, bool* ok) { 2195 // WhileStatement :: 2196 // 'while' '(' Expression ')' Statement 2197 2198 WhileStatement* loop = new(zone()) WhileStatement(labels); 2199 Target target(&this->target_stack_, loop); 2200 2201 Expect(Token::WHILE, CHECK_OK); 2202 Expect(Token::LPAREN, CHECK_OK); 2203 Expression* cond = ParseExpression(true, CHECK_OK); 2204 Expect(Token::RPAREN, CHECK_OK); 2205 Statement* body = ParseStatement(NULL, CHECK_OK); 2206 2207 if (loop != NULL) loop->Initialize(cond, body); 2208 return loop; 2209} 2210 2211 2212Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { 2213 // ForStatement :: 2214 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement 2215 2216 Statement* init = NULL; 2217 2218 Expect(Token::FOR, CHECK_OK); 2219 Expect(Token::LPAREN, CHECK_OK); 2220 if (peek() != Token::SEMICOLON) { 2221 if (peek() == Token::VAR || peek() == Token::CONST) { 2222 Expression* each = NULL; 2223 Block* variable_statement = 2224 ParseVariableDeclarations(false, &each, CHECK_OK); 2225 if (peek() == Token::IN && each != NULL) { 2226 ForInStatement* loop = new(zone()) ForInStatement(labels); 2227 Target target(&this->target_stack_, loop); 2228 2229 Expect(Token::IN, CHECK_OK); 2230 Expression* enumerable = ParseExpression(true, CHECK_OK); 2231 Expect(Token::RPAREN, CHECK_OK); 2232 2233 Statement* body = ParseStatement(NULL, CHECK_OK); 2234 loop->Initialize(each, enumerable, body); 2235 Block* result = new(zone()) Block(NULL, 2, false); 2236 result->AddStatement(variable_statement); 2237 result->AddStatement(loop); 2238 // Parsed for-in loop w/ variable/const declaration. 2239 return result; 2240 } else { 2241 init = variable_statement; 2242 } 2243 2244 } else { 2245 Expression* expression = ParseExpression(false, CHECK_OK); 2246 if (peek() == Token::IN) { 2247 // Signal a reference error if the expression is an invalid 2248 // left-hand side expression. We could report this as a syntax 2249 // error here but for compatibility with JSC we choose to report 2250 // the error at runtime. 2251 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2252 Handle<String> type = 2253 isolate()->factory()->invalid_lhs_in_for_in_symbol(); 2254 expression = NewThrowReferenceError(type); 2255 } 2256 ForInStatement* loop = new(zone()) ForInStatement(labels); 2257 Target target(&this->target_stack_, loop); 2258 2259 Expect(Token::IN, CHECK_OK); 2260 Expression* enumerable = ParseExpression(true, CHECK_OK); 2261 Expect(Token::RPAREN, CHECK_OK); 2262 2263 Statement* body = ParseStatement(NULL, CHECK_OK); 2264 if (loop) loop->Initialize(expression, enumerable, body); 2265 // Parsed for-in loop. 2266 return loop; 2267 2268 } else { 2269 init = new(zone()) ExpressionStatement(expression); 2270 } 2271 } 2272 } 2273 2274 // Standard 'for' loop 2275 ForStatement* loop = new(zone()) ForStatement(labels); 2276 Target target(&this->target_stack_, loop); 2277 2278 // Parsed initializer at this point. 2279 Expect(Token::SEMICOLON, CHECK_OK); 2280 2281 Expression* cond = NULL; 2282 if (peek() != Token::SEMICOLON) { 2283 cond = ParseExpression(true, CHECK_OK); 2284 } 2285 Expect(Token::SEMICOLON, CHECK_OK); 2286 2287 Statement* next = NULL; 2288 if (peek() != Token::RPAREN) { 2289 Expression* exp = ParseExpression(true, CHECK_OK); 2290 next = new(zone()) ExpressionStatement(exp); 2291 } 2292 Expect(Token::RPAREN, CHECK_OK); 2293 2294 Statement* body = ParseStatement(NULL, CHECK_OK); 2295 if (loop) loop->Initialize(init, cond, next, body); 2296 return loop; 2297} 2298 2299 2300// Precedence = 1 2301Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { 2302 // Expression :: 2303 // AssignmentExpression 2304 // Expression ',' AssignmentExpression 2305 2306 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); 2307 while (peek() == Token::COMMA) { 2308 Expect(Token::COMMA, CHECK_OK); 2309 int position = scanner().location().beg_pos; 2310 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2311 result = new(zone()) BinaryOperation(Token::COMMA, result, right, position); 2312 } 2313 return result; 2314} 2315 2316 2317// Precedence = 2 2318Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2319 // AssignmentExpression :: 2320 // ConditionalExpression 2321 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2322 2323 if (fni_ != NULL) fni_->Enter(); 2324 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); 2325 2326 if (!Token::IsAssignmentOp(peek())) { 2327 if (fni_ != NULL) fni_->Leave(); 2328 // Parsed conditional expression only (no assignment). 2329 return expression; 2330 } 2331 2332 // Signal a reference error if the expression is an invalid left-hand 2333 // side expression. We could report this as a syntax error here but 2334 // for compatibility with JSC we choose to report the error at 2335 // runtime. 2336 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2337 Handle<String> type = 2338 isolate()->factory()->invalid_lhs_in_assignment_symbol(); 2339 expression = NewThrowReferenceError(type); 2340 } 2341 2342 if (top_scope_->is_strict_mode()) { 2343 // Assignment to eval or arguments is disallowed in strict mode. 2344 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); 2345 } 2346 2347 Token::Value op = Next(); // Get assignment operator. 2348 int pos = scanner().location().beg_pos; 2349 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2350 2351 // TODO(1231235): We try to estimate the set of properties set by 2352 // constructors. We define a new property whenever there is an 2353 // assignment to a property of 'this'. We should probably only add 2354 // properties if we haven't seen them before. Otherwise we'll 2355 // probably overestimate the number of properties. 2356 Property* property = expression ? expression->AsProperty() : NULL; 2357 if (op == Token::ASSIGN && 2358 property != NULL && 2359 property->obj()->AsVariableProxy() != NULL && 2360 property->obj()->AsVariableProxy()->is_this()) { 2361 lexical_scope_->AddProperty(); 2362 } 2363 2364 // If we assign a function literal to a property we pretenure the 2365 // literal so it can be added as a constant function property. 2366 if (property != NULL && right->AsFunctionLiteral() != NULL) { 2367 right->AsFunctionLiteral()->set_pretenure(true); 2368 } 2369 2370 if (fni_ != NULL) { 2371 // Check if the right hand side is a call to avoid inferring a 2372 // name if we're dealing with "a = function(){...}();"-like 2373 // expression. 2374 if ((op == Token::INIT_VAR 2375 || op == Token::INIT_CONST 2376 || op == Token::ASSIGN) 2377 && (right->AsCall() == NULL)) { 2378 fni_->Infer(); 2379 } 2380 fni_->Leave(); 2381 } 2382 2383 return new(zone()) Assignment(op, expression, right, pos); 2384} 2385 2386 2387// Precedence = 3 2388Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { 2389 // ConditionalExpression :: 2390 // LogicalOrExpression 2391 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression 2392 2393 // We start using the binary expression parser for prec >= 4 only! 2394 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); 2395 if (peek() != Token::CONDITIONAL) return expression; 2396 Consume(Token::CONDITIONAL); 2397 // In parsing the first assignment expression in conditional 2398 // expressions we always accept the 'in' keyword; see ECMA-262, 2399 // section 11.12, page 58. 2400 int left_position = scanner().peek_location().beg_pos; 2401 Expression* left = ParseAssignmentExpression(true, CHECK_OK); 2402 Expect(Token::COLON, CHECK_OK); 2403 int right_position = scanner().peek_location().beg_pos; 2404 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2405 return new(zone()) Conditional(expression, left, right, 2406 left_position, right_position); 2407} 2408 2409 2410static int Precedence(Token::Value tok, bool accept_IN) { 2411 if (tok == Token::IN && !accept_IN) 2412 return 0; // 0 precedence will terminate binary expression parsing 2413 2414 return Token::Precedence(tok); 2415} 2416 2417 2418// Precedence >= 4 2419Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 2420 ASSERT(prec >= 4); 2421 Expression* x = ParseUnaryExpression(CHECK_OK); 2422 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 2423 // prec1 >= 4 2424 while (Precedence(peek(), accept_IN) == prec1) { 2425 Token::Value op = Next(); 2426 int position = scanner().location().beg_pos; 2427 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 2428 2429 // Compute some expressions involving only number literals. 2430 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() && 2431 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { 2432 double x_val = x->AsLiteral()->handle()->Number(); 2433 double y_val = y->AsLiteral()->handle()->Number(); 2434 2435 switch (op) { 2436 case Token::ADD: 2437 x = NewNumberLiteral(x_val + y_val); 2438 continue; 2439 case Token::SUB: 2440 x = NewNumberLiteral(x_val - y_val); 2441 continue; 2442 case Token::MUL: 2443 x = NewNumberLiteral(x_val * y_val); 2444 continue; 2445 case Token::DIV: 2446 x = NewNumberLiteral(x_val / y_val); 2447 continue; 2448 case Token::BIT_OR: 2449 x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val)); 2450 continue; 2451 case Token::BIT_AND: 2452 x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val)); 2453 continue; 2454 case Token::BIT_XOR: 2455 x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val)); 2456 continue; 2457 case Token::SHL: { 2458 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); 2459 x = NewNumberLiteral(value); 2460 continue; 2461 } 2462 case Token::SHR: { 2463 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 2464 uint32_t value = DoubleToUint32(x_val) >> shift; 2465 x = NewNumberLiteral(value); 2466 continue; 2467 } 2468 case Token::SAR: { 2469 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 2470 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 2471 x = NewNumberLiteral(value); 2472 continue; 2473 } 2474 default: 2475 break; 2476 } 2477 } 2478 2479 // For now we distinguish between comparisons and other binary 2480 // operations. (We could combine the two and get rid of this 2481 // code and AST node eventually.) 2482 if (Token::IsCompareOp(op)) { 2483 // We have a comparison. 2484 Token::Value cmp = op; 2485 switch (op) { 2486 case Token::NE: cmp = Token::EQ; break; 2487 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2488 default: break; 2489 } 2490 x = NewCompareNode(cmp, x, y, position); 2491 if (cmp != op) { 2492 // The comparison was negated - add a NOT. 2493 x = new(zone()) UnaryOperation(Token::NOT, x); 2494 } 2495 2496 } else { 2497 // We have a "normal" binary operation. 2498 x = new(zone()) BinaryOperation(op, x, y, position); 2499 } 2500 } 2501 } 2502 return x; 2503} 2504 2505 2506Expression* Parser::NewCompareNode(Token::Value op, 2507 Expression* x, 2508 Expression* y, 2509 int position) { 2510 ASSERT(op != Token::NE && op != Token::NE_STRICT); 2511 if (op == Token::EQ || op == Token::EQ_STRICT) { 2512 bool is_strict = (op == Token::EQ_STRICT); 2513 Literal* x_literal = x->AsLiteral(); 2514 if (x_literal != NULL && x_literal->IsNull()) { 2515 return new(zone()) CompareToNull(is_strict, y); 2516 } 2517 2518 Literal* y_literal = y->AsLiteral(); 2519 if (y_literal != NULL && y_literal->IsNull()) { 2520 return new(zone()) CompareToNull(is_strict, x); 2521 } 2522 } 2523 return new(zone()) CompareOperation(op, x, y, position); 2524} 2525 2526 2527Expression* Parser::ParseUnaryExpression(bool* ok) { 2528 // UnaryExpression :: 2529 // PostfixExpression 2530 // 'delete' UnaryExpression 2531 // 'void' UnaryExpression 2532 // 'typeof' UnaryExpression 2533 // '++' UnaryExpression 2534 // '--' UnaryExpression 2535 // '+' UnaryExpression 2536 // '-' UnaryExpression 2537 // '~' UnaryExpression 2538 // '!' UnaryExpression 2539 2540 Token::Value op = peek(); 2541 if (Token::IsUnaryOp(op)) { 2542 op = Next(); 2543 Expression* expression = ParseUnaryExpression(CHECK_OK); 2544 2545 // Compute some expressions involving only number literals. 2546 if (expression != NULL && expression->AsLiteral() && 2547 expression->AsLiteral()->handle()->IsNumber()) { 2548 double value = expression->AsLiteral()->handle()->Number(); 2549 switch (op) { 2550 case Token::ADD: 2551 return expression; 2552 case Token::SUB: 2553 return NewNumberLiteral(-value); 2554 case Token::BIT_NOT: 2555 return NewNumberLiteral(~DoubleToInt32(value)); 2556 default: break; 2557 } 2558 } 2559 2560 // "delete identifier" is a syntax error in strict mode. 2561 if (op == Token::DELETE && top_scope_->is_strict_mode()) { 2562 VariableProxy* operand = expression->AsVariableProxy(); 2563 if (operand != NULL && !operand->is_this()) { 2564 ReportMessage("strict_delete", Vector<const char*>::empty()); 2565 *ok = false; 2566 return NULL; 2567 } 2568 } 2569 2570 return new(zone()) UnaryOperation(op, expression); 2571 2572 } else if (Token::IsCountOp(op)) { 2573 op = Next(); 2574 Expression* expression = ParseUnaryExpression(CHECK_OK); 2575 // Signal a reference error if the expression is an invalid 2576 // left-hand side expression. We could report this as a syntax 2577 // error here but for compatibility with JSC we choose to report the 2578 // error at runtime. 2579 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2580 Handle<String> type = 2581 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); 2582 expression = NewThrowReferenceError(type); 2583 } 2584 2585 if (top_scope_->is_strict_mode()) { 2586 // Prefix expression operand in strict mode may not be eval or arguments. 2587 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 2588 } 2589 2590 int position = scanner().location().beg_pos; 2591 return new(zone()) CountOperation(op, 2592 true /* prefix */, 2593 expression, 2594 position); 2595 2596 } else { 2597 return ParsePostfixExpression(ok); 2598 } 2599} 2600 2601 2602Expression* Parser::ParsePostfixExpression(bool* ok) { 2603 // PostfixExpression :: 2604 // LeftHandSideExpression ('++' | '--')? 2605 2606 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 2607 if (!scanner().has_line_terminator_before_next() && 2608 Token::IsCountOp(peek())) { 2609 // Signal a reference error if the expression is an invalid 2610 // left-hand side expression. We could report this as a syntax 2611 // error here but for compatibility with JSC we choose to report the 2612 // error at runtime. 2613 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2614 Handle<String> type = 2615 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); 2616 expression = NewThrowReferenceError(type); 2617 } 2618 2619 if (top_scope_->is_strict_mode()) { 2620 // Postfix expression operand in strict mode may not be eval or arguments. 2621 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); 2622 } 2623 2624 Token::Value next = Next(); 2625 int position = scanner().location().beg_pos; 2626 expression = 2627 new(zone()) CountOperation(next, 2628 false /* postfix */, 2629 expression, 2630 position); 2631 } 2632 return expression; 2633} 2634 2635 2636Expression* Parser::ParseLeftHandSideExpression(bool* ok) { 2637 // LeftHandSideExpression :: 2638 // (NewExpression | MemberExpression) ... 2639 2640 Expression* result; 2641 if (peek() == Token::NEW) { 2642 result = ParseNewExpression(CHECK_OK); 2643 } else { 2644 result = ParseMemberExpression(CHECK_OK); 2645 } 2646 2647 while (true) { 2648 switch (peek()) { 2649 case Token::LBRACK: { 2650 Consume(Token::LBRACK); 2651 int pos = scanner().location().beg_pos; 2652 Expression* index = ParseExpression(true, CHECK_OK); 2653 result = new(zone()) Property(result, index, pos); 2654 Expect(Token::RBRACK, CHECK_OK); 2655 break; 2656 } 2657 2658 case Token::LPAREN: { 2659 int pos = scanner().location().beg_pos; 2660 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 2661 2662 // Keep track of eval() calls since they disable all local variable 2663 // optimizations. 2664 // The calls that need special treatment are the 2665 // direct (i.e. not aliased) eval calls. These calls are all of the 2666 // form eval(...) with no explicit receiver object where eval is not 2667 // declared in the current scope chain. 2668 // These calls are marked as potentially direct eval calls. Whether 2669 // they are actually direct calls to eval is determined at run time. 2670 // TODO(994): In ES5, it doesn't matter if the "eval" var is declared 2671 // in the local scope chain. It only matters that it's called "eval", 2672 // is called without a receiver and it refers to the original eval 2673 // function. 2674 VariableProxy* callee = result->AsVariableProxy(); 2675 if (callee != NULL && 2676 callee->IsVariable(isolate()->factory()->eval_symbol())) { 2677 Handle<String> name = callee->name(); 2678 Variable* var = top_scope_->Lookup(name); 2679 if (var == NULL) { 2680 top_scope_->RecordEvalCall(); 2681 } 2682 } 2683 result = NewCall(result, args, pos); 2684 break; 2685 } 2686 2687 case Token::PERIOD: { 2688 Consume(Token::PERIOD); 2689 int pos = scanner().location().beg_pos; 2690 Handle<String> name = ParseIdentifierName(CHECK_OK); 2691 result = new(zone()) Property(result, new(zone()) Literal(name), pos); 2692 if (fni_ != NULL) fni_->PushLiteralName(name); 2693 break; 2694 } 2695 2696 default: 2697 return result; 2698 } 2699 } 2700} 2701 2702 2703Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { 2704 // NewExpression :: 2705 // ('new')+ MemberExpression 2706 2707 // The grammar for new expressions is pretty warped. The keyword 2708 // 'new' can either be a part of the new expression (where it isn't 2709 // followed by an argument list) or a part of the member expression, 2710 // where it must be followed by an argument list. To accommodate 2711 // this, we parse the 'new' keywords greedily and keep track of how 2712 // many we have parsed. This information is then passed on to the 2713 // member expression parser, which is only allowed to match argument 2714 // lists as long as it has 'new' prefixes left 2715 Expect(Token::NEW, CHECK_OK); 2716 PositionStack::Element pos(stack, scanner().location().beg_pos); 2717 2718 Expression* result; 2719 if (peek() == Token::NEW) { 2720 result = ParseNewPrefix(stack, CHECK_OK); 2721 } else { 2722 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); 2723 } 2724 2725 if (!stack->is_empty()) { 2726 int last = stack->pop(); 2727 result = new(zone()) CallNew(result, new ZoneList<Expression*>(0), last); 2728 } 2729 return result; 2730} 2731 2732 2733Expression* Parser::ParseNewExpression(bool* ok) { 2734 PositionStack stack(ok); 2735 return ParseNewPrefix(&stack, ok); 2736} 2737 2738 2739Expression* Parser::ParseMemberExpression(bool* ok) { 2740 return ParseMemberWithNewPrefixesExpression(NULL, ok); 2741} 2742 2743 2744Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, 2745 bool* ok) { 2746 // MemberExpression :: 2747 // (PrimaryExpression | FunctionLiteral) 2748 // ('[' Expression ']' | '.' Identifier | Arguments)* 2749 2750 // Parse the initial primary or function expression. 2751 Expression* result = NULL; 2752 if (peek() == Token::FUNCTION) { 2753 Expect(Token::FUNCTION, CHECK_OK); 2754 int function_token_position = scanner().location().beg_pos; 2755 Handle<String> name; 2756 bool is_reserved_name = false; 2757 if (peek_any_identifier()) { 2758 name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK); 2759 } 2760 result = ParseFunctionLiteral(name, is_reserved_name, 2761 function_token_position, NESTED, CHECK_OK); 2762 } else { 2763 result = ParsePrimaryExpression(CHECK_OK); 2764 } 2765 2766 while (true) { 2767 switch (peek()) { 2768 case Token::LBRACK: { 2769 Consume(Token::LBRACK); 2770 int pos = scanner().location().beg_pos; 2771 Expression* index = ParseExpression(true, CHECK_OK); 2772 result = new(zone()) Property(result, index, pos); 2773 Expect(Token::RBRACK, CHECK_OK); 2774 break; 2775 } 2776 case Token::PERIOD: { 2777 Consume(Token::PERIOD); 2778 int pos = scanner().location().beg_pos; 2779 Handle<String> name = ParseIdentifierName(CHECK_OK); 2780 result = new(zone()) Property(result, new(zone()) Literal(name), pos); 2781 if (fni_ != NULL) fni_->PushLiteralName(name); 2782 break; 2783 } 2784 case Token::LPAREN: { 2785 if ((stack == NULL) || stack->is_empty()) return result; 2786 // Consume one of the new prefixes (already parsed). 2787 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 2788 int last = stack->pop(); 2789 result = new CallNew(result, args, last); 2790 break; 2791 } 2792 default: 2793 return result; 2794 } 2795 } 2796} 2797 2798 2799DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { 2800 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser 2801 // contexts this is used as a statement which invokes the debugger as i a 2802 // break point is present. 2803 // DebuggerStatement :: 2804 // 'debugger' ';' 2805 2806 Expect(Token::DEBUGGER, CHECK_OK); 2807 ExpectSemicolon(CHECK_OK); 2808 return new(zone()) DebuggerStatement(); 2809} 2810 2811 2812void Parser::ReportUnexpectedToken(Token::Value token) { 2813 // We don't report stack overflows here, to avoid increasing the 2814 // stack depth even further. Instead we report it after parsing is 2815 // over, in ParseProgram/ParseJson. 2816 if (token == Token::ILLEGAL && stack_overflow_) return; 2817 // Four of the tokens are treated specially 2818 switch (token) { 2819 case Token::EOS: 2820 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 2821 case Token::NUMBER: 2822 return ReportMessage("unexpected_token_number", 2823 Vector<const char*>::empty()); 2824 case Token::STRING: 2825 return ReportMessage("unexpected_token_string", 2826 Vector<const char*>::empty()); 2827 case Token::IDENTIFIER: 2828 return ReportMessage("unexpected_token_identifier", 2829 Vector<const char*>::empty()); 2830 case Token::FUTURE_RESERVED_WORD: 2831 return ReportMessage(top_scope_->is_strict_mode() ? 2832 "unexpected_strict_reserved" : 2833 "unexpected_token_identifier", 2834 Vector<const char*>::empty()); 2835 default: 2836 const char* name = Token::String(token); 2837 ASSERT(name != NULL); 2838 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 2839 } 2840} 2841 2842 2843void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 2844 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 2845 const char* element[1] = { *name_string }; 2846 ReportMessage("invalid_preparser_data", 2847 Vector<const char*>(element, 1)); 2848 *ok = false; 2849} 2850 2851 2852Expression* Parser::ParsePrimaryExpression(bool* ok) { 2853 // PrimaryExpression :: 2854 // 'this' 2855 // 'null' 2856 // 'true' 2857 // 'false' 2858 // Identifier 2859 // Number 2860 // String 2861 // ArrayLiteral 2862 // ObjectLiteral 2863 // RegExpLiteral 2864 // '(' Expression ')' 2865 2866 Expression* result = NULL; 2867 switch (peek()) { 2868 case Token::THIS: { 2869 Consume(Token::THIS); 2870 VariableProxy* recv = top_scope_->receiver(); 2871 result = recv; 2872 break; 2873 } 2874 2875 case Token::NULL_LITERAL: 2876 Consume(Token::NULL_LITERAL); 2877 result = new(zone()) Literal(isolate()->factory()->null_value()); 2878 break; 2879 2880 case Token::TRUE_LITERAL: 2881 Consume(Token::TRUE_LITERAL); 2882 result = new(zone()) Literal(isolate()->factory()->true_value()); 2883 break; 2884 2885 case Token::FALSE_LITERAL: 2886 Consume(Token::FALSE_LITERAL); 2887 result = new(zone()) Literal(isolate()->factory()->false_value()); 2888 break; 2889 2890 case Token::IDENTIFIER: 2891 case Token::FUTURE_RESERVED_WORD: { 2892 Handle<String> name = ParseIdentifier(CHECK_OK); 2893 if (fni_ != NULL) fni_->PushVariableName(name); 2894 result = top_scope_->NewUnresolved(name, 2895 inside_with(), 2896 scanner().location().beg_pos); 2897 break; 2898 } 2899 2900 case Token::NUMBER: { 2901 Consume(Token::NUMBER); 2902 ASSERT(scanner().is_literal_ascii()); 2903 double value = StringToDouble(isolate()->unicode_cache(), 2904 scanner().literal_ascii_string(), 2905 ALLOW_HEX | ALLOW_OCTALS); 2906 result = NewNumberLiteral(value); 2907 break; 2908 } 2909 2910 case Token::STRING: { 2911 Consume(Token::STRING); 2912 Handle<String> symbol = GetSymbol(CHECK_OK); 2913 result = new(zone()) Literal(symbol); 2914 if (fni_ != NULL) fni_->PushLiteralName(symbol); 2915 break; 2916 } 2917 2918 case Token::ASSIGN_DIV: 2919 result = ParseRegExpLiteral(true, CHECK_OK); 2920 break; 2921 2922 case Token::DIV: 2923 result = ParseRegExpLiteral(false, CHECK_OK); 2924 break; 2925 2926 case Token::LBRACK: 2927 result = ParseArrayLiteral(CHECK_OK); 2928 break; 2929 2930 case Token::LBRACE: 2931 result = ParseObjectLiteral(CHECK_OK); 2932 break; 2933 2934 case Token::LPAREN: 2935 Consume(Token::LPAREN); 2936 // Heuristically try to detect immediately called functions before 2937 // seeing the call parentheses. 2938 parenthesized_function_ = (peek() == Token::FUNCTION); 2939 result = ParseExpression(true, CHECK_OK); 2940 Expect(Token::RPAREN, CHECK_OK); 2941 break; 2942 2943 case Token::MOD: 2944 if (allow_natives_syntax_ || extension_ != NULL) { 2945 result = ParseV8Intrinsic(CHECK_OK); 2946 break; 2947 } 2948 // If we're not allowing special syntax we fall-through to the 2949 // default case. 2950 2951 default: { 2952 Token::Value tok = Next(); 2953 ReportUnexpectedToken(tok); 2954 *ok = false; 2955 return NULL; 2956 } 2957 } 2958 2959 return result; 2960} 2961 2962 2963void Parser::BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* values, 2964 Handle<FixedArray> literals, 2965 bool* is_simple, 2966 int* depth) { 2967 // Fill in the literals. 2968 // Accumulate output values in local variables. 2969 bool is_simple_acc = true; 2970 int depth_acc = 1; 2971 for (int i = 0; i < values->length(); i++) { 2972 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 2973 if (m_literal != NULL && m_literal->depth() >= depth_acc) { 2974 depth_acc = m_literal->depth() + 1; 2975 } 2976 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 2977 if (boilerplate_value->IsUndefined()) { 2978 literals->set_the_hole(i); 2979 is_simple_acc = false; 2980 } else { 2981 literals->set(i, *boilerplate_value); 2982 } 2983 } 2984 2985 *is_simple = is_simple_acc; 2986 *depth = depth_acc; 2987} 2988 2989 2990Expression* Parser::ParseArrayLiteral(bool* ok) { 2991 // ArrayLiteral :: 2992 // '[' Expression? (',' Expression?)* ']' 2993 2994 ZoneList<Expression*>* values = new ZoneList<Expression*>(4); 2995 Expect(Token::LBRACK, CHECK_OK); 2996 while (peek() != Token::RBRACK) { 2997 Expression* elem; 2998 if (peek() == Token::COMMA) { 2999 elem = GetLiteralTheHole(); 3000 } else { 3001 elem = ParseAssignmentExpression(true, CHECK_OK); 3002 } 3003 values->Add(elem); 3004 if (peek() != Token::RBRACK) { 3005 Expect(Token::COMMA, CHECK_OK); 3006 } 3007 } 3008 Expect(Token::RBRACK, CHECK_OK); 3009 3010 // Update the scope information before the pre-parsing bailout. 3011 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); 3012 3013 // Allocate a fixed array with all the literals. 3014 Handle<FixedArray> literals = 3015 isolate()->factory()->NewFixedArray(values->length(), TENURED); 3016 3017 // Fill in the literals. 3018 bool is_simple = true; 3019 int depth = 1; 3020 for (int i = 0, n = values->length(); i < n; i++) { 3021 MaterializedLiteral* m_literal = values->at(i)->AsMaterializedLiteral(); 3022 if (m_literal != NULL && m_literal->depth() + 1 > depth) { 3023 depth = m_literal->depth() + 1; 3024 } 3025 Handle<Object> boilerplate_value = GetBoilerplateValue(values->at(i)); 3026 if (boilerplate_value->IsUndefined()) { 3027 literals->set_the_hole(i); 3028 is_simple = false; 3029 } else { 3030 literals->set(i, *boilerplate_value); 3031 } 3032 } 3033 3034 // Simple and shallow arrays can be lazily copied, we transform the 3035 // elements array to a copy-on-write array. 3036 if (is_simple && depth == 1 && values->length() > 0) { 3037 literals->set_map(isolate()->heap()->fixed_cow_array_map()); 3038 } 3039 3040 return new(zone()) ArrayLiteral(literals, values, 3041 literal_index, is_simple, depth); 3042} 3043 3044 3045bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { 3046 return property != NULL && 3047 property->kind() != ObjectLiteral::Property::PROTOTYPE; 3048} 3049 3050 3051bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { 3052 if (expression->AsLiteral() != NULL) return true; 3053 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); 3054 return lit != NULL && lit->is_simple(); 3055} 3056 3057 3058bool CompileTimeValue::ArrayLiteralElementNeedsInitialization( 3059 Expression* value) { 3060 // If value is a literal the property value is already set in the 3061 // boilerplate object. 3062 if (value->AsLiteral() != NULL) return false; 3063 // If value is a materialized literal the property value is already set 3064 // in the boilerplate object if it is simple. 3065 if (CompileTimeValue::IsCompileTimeValue(value)) return false; 3066 return true; 3067} 3068 3069 3070Handle<FixedArray> CompileTimeValue::GetValue(Expression* expression) { 3071 ASSERT(IsCompileTimeValue(expression)); 3072 Handle<FixedArray> result = FACTORY->NewFixedArray(2, TENURED); 3073 ObjectLiteral* object_literal = expression->AsObjectLiteral(); 3074 if (object_literal != NULL) { 3075 ASSERT(object_literal->is_simple()); 3076 if (object_literal->fast_elements()) { 3077 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_FAST_ELEMENTS)); 3078 } else { 3079 result->set(kTypeSlot, Smi::FromInt(OBJECT_LITERAL_SLOW_ELEMENTS)); 3080 } 3081 result->set(kElementsSlot, *object_literal->constant_properties()); 3082 } else { 3083 ArrayLiteral* array_literal = expression->AsArrayLiteral(); 3084 ASSERT(array_literal != NULL && array_literal->is_simple()); 3085 result->set(kTypeSlot, Smi::FromInt(ARRAY_LITERAL)); 3086 result->set(kElementsSlot, *array_literal->constant_elements()); 3087 } 3088 return result; 3089} 3090 3091 3092CompileTimeValue::Type CompileTimeValue::GetType(Handle<FixedArray> value) { 3093 Smi* type_value = Smi::cast(value->get(kTypeSlot)); 3094 return static_cast<Type>(type_value->value()); 3095} 3096 3097 3098Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { 3099 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); 3100} 3101 3102 3103Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { 3104 if (expression->AsLiteral() != NULL) { 3105 return expression->AsLiteral()->handle(); 3106 } 3107 if (CompileTimeValue::IsCompileTimeValue(expression)) { 3108 return CompileTimeValue::GetValue(expression); 3109 } 3110 return isolate()->factory()->undefined_value(); 3111} 3112 3113// Defined in ast.cc 3114bool IsEqualString(void* first, void* second); 3115bool IsEqualNumber(void* first, void* second); 3116 3117 3118// Validation per 11.1.5 Object Initialiser 3119class ObjectLiteralPropertyChecker { 3120 public: 3121 ObjectLiteralPropertyChecker(Parser* parser, bool strict) : 3122 props(&IsEqualString), 3123 elems(&IsEqualNumber), 3124 parser_(parser), 3125 strict_(strict) { 3126 } 3127 3128 void CheckProperty( 3129 ObjectLiteral::Property* property, 3130 Scanner::Location loc, 3131 bool* ok); 3132 3133 private: 3134 enum PropertyKind { 3135 kGetAccessor = 0x01, 3136 kSetAccessor = 0x02, 3137 kAccessor = kGetAccessor | kSetAccessor, 3138 kData = 0x04 3139 }; 3140 3141 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) { 3142 switch (property->kind()) { 3143 case ObjectLiteral::Property::GETTER: 3144 return kGetAccessor; 3145 case ObjectLiteral::Property::SETTER: 3146 return kSetAccessor; 3147 default: 3148 return kData; 3149 } 3150 } 3151 3152 HashMap props; 3153 HashMap elems; 3154 Parser* parser_; 3155 bool strict_; 3156}; 3157 3158 3159void ObjectLiteralPropertyChecker::CheckProperty( 3160 ObjectLiteral::Property* property, 3161 Scanner::Location loc, 3162 bool* ok) { 3163 3164 ASSERT(property != NULL); 3165 3166 Literal *lit = property->key(); 3167 Handle<Object> handle = lit->handle(); 3168 3169 uint32_t hash; 3170 HashMap* map; 3171 void* key; 3172 3173 if (handle->IsSymbol()) { 3174 Handle<String> name(String::cast(*handle)); 3175 if (name->AsArrayIndex(&hash)) { 3176 Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash); 3177 key = key_handle.location(); 3178 map = &elems; 3179 } else { 3180 key = handle.location(); 3181 hash = name->Hash(); 3182 map = &props; 3183 } 3184 } else if (handle->ToArrayIndex(&hash)) { 3185 key = handle.location(); 3186 map = &elems; 3187 } else { 3188 ASSERT(handle->IsNumber()); 3189 double num = handle->Number(); 3190 char arr[100]; 3191 Vector<char> buffer(arr, ARRAY_SIZE(arr)); 3192 const char* str = DoubleToCString(num, buffer); 3193 Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str)); 3194 key = name.location(); 3195 hash = name->Hash(); 3196 map = &props; 3197 } 3198 3199 // Lookup property previously defined, if any. 3200 HashMap::Entry* entry = map->Lookup(key, hash, true); 3201 intptr_t prev = reinterpret_cast<intptr_t> (entry->value); 3202 intptr_t curr = GetPropertyKind(property); 3203 3204 // Duplicate data properties are illegal in strict mode. 3205 if (strict_ && (curr & prev & kData) != 0) { 3206 parser_->ReportMessageAt(loc, "strict_duplicate_property", 3207 Vector<const char*>::empty()); 3208 *ok = false; 3209 return; 3210 } 3211 // Data property conflicting with an accessor. 3212 if (((curr & kData) && (prev & kAccessor)) || 3213 ((prev & kData) && (curr & kAccessor))) { 3214 parser_->ReportMessageAt(loc, "accessor_data_property", 3215 Vector<const char*>::empty()); 3216 *ok = false; 3217 return; 3218 } 3219 // Two accessors of the same type conflicting 3220 if ((curr & prev & kAccessor) != 0) { 3221 parser_->ReportMessageAt(loc, "accessor_get_set", 3222 Vector<const char*>::empty()); 3223 *ok = false; 3224 return; 3225 } 3226 3227 // Update map 3228 entry->value = reinterpret_cast<void*> (prev | curr); 3229 *ok = true; 3230} 3231 3232 3233void Parser::BuildObjectLiteralConstantProperties( 3234 ZoneList<ObjectLiteral::Property*>* properties, 3235 Handle<FixedArray> constant_properties, 3236 bool* is_simple, 3237 bool* fast_elements, 3238 int* depth) { 3239 int position = 0; 3240 // Accumulate the value in local variables and store it at the end. 3241 bool is_simple_acc = true; 3242 int depth_acc = 1; 3243 uint32_t max_element_index = 0; 3244 uint32_t elements = 0; 3245 for (int i = 0; i < properties->length(); i++) { 3246 ObjectLiteral::Property* property = properties->at(i); 3247 if (!IsBoilerplateProperty(property)) { 3248 is_simple_acc = false; 3249 continue; 3250 } 3251 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); 3252 if (m_literal != NULL && m_literal->depth() >= depth_acc) { 3253 depth_acc = m_literal->depth() + 1; 3254 } 3255 3256 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined 3257 // value for COMPUTED properties, the real value is filled in at 3258 // runtime. The enumeration order is maintained. 3259 Handle<Object> key = property->key()->handle(); 3260 Handle<Object> value = GetBoilerplateValue(property->value()); 3261 is_simple_acc = is_simple_acc && !value->IsUndefined(); 3262 3263 // Keep track of the number of elements in the object literal and 3264 // the largest element index. If the largest element index is 3265 // much larger than the number of elements, creating an object 3266 // literal with fast elements will be a waste of space. 3267 uint32_t element_index = 0; 3268 if (key->IsString() 3269 && Handle<String>::cast(key)->AsArrayIndex(&element_index) 3270 && element_index > max_element_index) { 3271 max_element_index = element_index; 3272 elements++; 3273 } else if (key->IsSmi()) { 3274 int key_value = Smi::cast(*key)->value(); 3275 if (key_value > 0 3276 && static_cast<uint32_t>(key_value) > max_element_index) { 3277 max_element_index = key_value; 3278 } 3279 elements++; 3280 } 3281 3282 // Add name, value pair to the fixed array. 3283 constant_properties->set(position++, *key); 3284 constant_properties->set(position++, *value); 3285 } 3286 *fast_elements = 3287 (max_element_index <= 32) || ((2 * elements) >= max_element_index); 3288 *is_simple = is_simple_acc; 3289 *depth = depth_acc; 3290} 3291 3292 3293ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3294 bool* ok) { 3295 // Special handling of getter and setter syntax: 3296 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3297 // We have already read the "get" or "set" keyword. 3298 Token::Value next = Next(); 3299 bool is_keyword = Token::IsKeyword(next); 3300 if (next == Token::IDENTIFIER || next == Token::NUMBER || 3301 next == Token::FUTURE_RESERVED_WORD || 3302 next == Token::STRING || is_keyword) { 3303 Handle<String> name; 3304 if (is_keyword) { 3305 name = isolate_->factory()->LookupAsciiSymbol(Token::String(next)); 3306 } else { 3307 name = GetSymbol(CHECK_OK); 3308 } 3309 FunctionLiteral* value = 3310 ParseFunctionLiteral(name, 3311 false, // reserved words are allowed here 3312 RelocInfo::kNoPosition, 3313 DECLARATION, 3314 CHECK_OK); 3315 // Allow any number of parameters for compatiabilty with JSC. 3316 // Specification only allows zero parameters for get and one for set. 3317 ObjectLiteral::Property* property = 3318 new(zone()) ObjectLiteral::Property(is_getter, value); 3319 return property; 3320 } else { 3321 ReportUnexpectedToken(next); 3322 *ok = false; 3323 return NULL; 3324 } 3325} 3326 3327 3328Expression* Parser::ParseObjectLiteral(bool* ok) { 3329 // ObjectLiteral :: 3330 // '{' ( 3331 // ((IdentifierName | String | Number) ':' AssignmentExpression) 3332 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 3333 // )*[','] '}' 3334 3335 ZoneList<ObjectLiteral::Property*>* properties = 3336 new ZoneList<ObjectLiteral::Property*>(4); 3337 int number_of_boilerplate_properties = 0; 3338 bool has_function = false; 3339 3340 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode()); 3341 3342 Expect(Token::LBRACE, CHECK_OK); 3343 Scanner::Location loc = scanner().location(); 3344 3345 while (peek() != Token::RBRACE) { 3346 if (fni_ != NULL) fni_->Enter(); 3347 3348 Literal* key = NULL; 3349 Token::Value next = peek(); 3350 3351 // Location of the property name token 3352 Scanner::Location loc = scanner().peek_location(); 3353 3354 switch (next) { 3355 case Token::FUTURE_RESERVED_WORD: 3356 case Token::IDENTIFIER: { 3357 bool is_getter = false; 3358 bool is_setter = false; 3359 Handle<String> id = 3360 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3361 if (fni_ != NULL) fni_->PushLiteralName(id); 3362 3363 if ((is_getter || is_setter) && peek() != Token::COLON) { 3364 // Update loc to point to the identifier 3365 loc = scanner().peek_location(); 3366 ObjectLiteral::Property* property = 3367 ParseObjectLiteralGetSet(is_getter, CHECK_OK); 3368 if (IsBoilerplateProperty(property)) { 3369 number_of_boilerplate_properties++; 3370 } 3371 // Validate the property. 3372 checker.CheckProperty(property, loc, CHECK_OK); 3373 properties->Add(property); 3374 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3375 3376 if (fni_ != NULL) { 3377 fni_->Infer(); 3378 fni_->Leave(); 3379 } 3380 continue; // restart the while 3381 } 3382 // Failed to parse as get/set property, so it's just a property 3383 // called "get" or "set". 3384 key = new(zone()) Literal(id); 3385 break; 3386 } 3387 case Token::STRING: { 3388 Consume(Token::STRING); 3389 Handle<String> string = GetSymbol(CHECK_OK); 3390 if (fni_ != NULL) fni_->PushLiteralName(string); 3391 uint32_t index; 3392 if (!string.is_null() && string->AsArrayIndex(&index)) { 3393 key = NewNumberLiteral(index); 3394 break; 3395 } 3396 key = new(zone()) Literal(string); 3397 break; 3398 } 3399 case Token::NUMBER: { 3400 Consume(Token::NUMBER); 3401 ASSERT(scanner().is_literal_ascii()); 3402 double value = StringToDouble(isolate()->unicode_cache(), 3403 scanner().literal_ascii_string(), 3404 ALLOW_HEX | ALLOW_OCTALS); 3405 key = NewNumberLiteral(value); 3406 break; 3407 } 3408 default: 3409 if (Token::IsKeyword(next)) { 3410 Consume(next); 3411 Handle<String> string = GetSymbol(CHECK_OK); 3412 key = new(zone()) Literal(string); 3413 } else { 3414 // Unexpected token. 3415 Token::Value next = Next(); 3416 ReportUnexpectedToken(next); 3417 *ok = false; 3418 return NULL; 3419 } 3420 } 3421 3422 Expect(Token::COLON, CHECK_OK); 3423 Expression* value = ParseAssignmentExpression(true, CHECK_OK); 3424 3425 ObjectLiteral::Property* property = 3426 new(zone()) ObjectLiteral::Property(key, value); 3427 3428 // Mark object literals that contain function literals and pretenure the 3429 // literal so it can be added as a constant function property. 3430 if (value->AsFunctionLiteral() != NULL) { 3431 has_function = true; 3432 value->AsFunctionLiteral()->set_pretenure(true); 3433 } 3434 3435 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 3436 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; 3437 // Validate the property 3438 checker.CheckProperty(property, loc, CHECK_OK); 3439 properties->Add(property); 3440 3441 // TODO(1240767): Consider allowing trailing comma. 3442 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3443 3444 if (fni_ != NULL) { 3445 fni_->Infer(); 3446 fni_->Leave(); 3447 } 3448 } 3449 Expect(Token::RBRACE, CHECK_OK); 3450 3451 // Computation of literal_index must happen before pre parse bailout. 3452 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); 3453 3454 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( 3455 number_of_boilerplate_properties * 2, TENURED); 3456 3457 bool is_simple = true; 3458 bool fast_elements = true; 3459 int depth = 1; 3460 BuildObjectLiteralConstantProperties(properties, 3461 constant_properties, 3462 &is_simple, 3463 &fast_elements, 3464 &depth); 3465 return new(zone()) ObjectLiteral(constant_properties, 3466 properties, 3467 literal_index, 3468 is_simple, 3469 fast_elements, 3470 depth, 3471 has_function); 3472} 3473 3474 3475Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { 3476 if (!scanner().ScanRegExpPattern(seen_equal)) { 3477 Next(); 3478 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); 3479 *ok = false; 3480 return NULL; 3481 } 3482 3483 int literal_index = lexical_scope_->NextMaterializedLiteralIndex(); 3484 3485 Handle<String> js_pattern = NextLiteralString(TENURED); 3486 scanner().ScanRegExpFlags(); 3487 Handle<String> js_flags = NextLiteralString(TENURED); 3488 Next(); 3489 3490 return new(zone()) RegExpLiteral(js_pattern, js_flags, literal_index); 3491} 3492 3493 3494ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { 3495 // Arguments :: 3496 // '(' (AssignmentExpression)*[','] ')' 3497 3498 ZoneList<Expression*>* result = new ZoneList<Expression*>(4); 3499 Expect(Token::LPAREN, CHECK_OK); 3500 bool done = (peek() == Token::RPAREN); 3501 while (!done) { 3502 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); 3503 result->Add(argument); 3504 if (result->length() > kMaxNumFunctionParameters) { 3505 ReportMessageAt(scanner().location(), "too_many_arguments", 3506 Vector<const char*>::empty()); 3507 *ok = false; 3508 return NULL; 3509 } 3510 done = (peek() == Token::RPAREN); 3511 if (!done) Expect(Token::COMMA, CHECK_OK); 3512 } 3513 Expect(Token::RPAREN, CHECK_OK); 3514 return result; 3515} 3516 3517 3518FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3519 bool name_is_reserved, 3520 int function_token_position, 3521 FunctionLiteralType type, 3522 bool* ok) { 3523 // Function :: 3524 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3525 bool is_named = !var_name.is_null(); 3526 3527 // The name associated with this function. If it's a function expression, 3528 // this is the actual function name, otherwise this is the name of the 3529 // variable declared and initialized with the function (expression). In 3530 // that case, we don't have a function name (it's empty). 3531 Handle<String> name = 3532 is_named ? var_name : isolate()->factory()->empty_symbol(); 3533 // The function name, if any. 3534 Handle<String> function_name = isolate()->factory()->empty_symbol(); 3535 if (is_named && (type == EXPRESSION || type == NESTED)) { 3536 function_name = name; 3537 } 3538 3539 int num_parameters = 0; 3540 Scope* scope = NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3541 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); 3542 int materialized_literal_count; 3543 int expected_property_count; 3544 int start_pos; 3545 int end_pos; 3546 bool only_simple_this_property_assignments; 3547 Handle<FixedArray> this_property_assignments; 3548 // Parse function body. 3549 { LexicalScope lexical_scope(this, scope, isolate()); 3550 top_scope_->SetScopeName(name); 3551 3552 // FormalParameterList :: 3553 // '(' (Identifier)*[','] ')' 3554 Expect(Token::LPAREN, CHECK_OK); 3555 start_pos = scanner().location().beg_pos; 3556 Scanner::Location name_loc = Scanner::NoLocation(); 3557 Scanner::Location dupe_loc = Scanner::NoLocation(); 3558 Scanner::Location reserved_loc = Scanner::NoLocation(); 3559 3560 bool done = (peek() == Token::RPAREN); 3561 while (!done) { 3562 bool is_reserved = false; 3563 Handle<String> param_name = 3564 ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK); 3565 3566 // Store locations for possible future error reports. 3567 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 3568 name_loc = scanner().location(); 3569 } 3570 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 3571 dupe_loc = scanner().location(); 3572 } 3573 if (!reserved_loc.IsValid() && is_reserved) { 3574 reserved_loc = scanner().location(); 3575 } 3576 3577 Variable* parameter = top_scope_->DeclareLocal(param_name, 3578 Variable::VAR, 3579 Scope::PARAMETER); 3580 top_scope_->AddParameter(parameter); 3581 num_parameters++; 3582 if (num_parameters > kMaxNumFunctionParameters) { 3583 ReportMessageAt(scanner().location(), "too_many_parameters", 3584 Vector<const char*>::empty()); 3585 *ok = false; 3586 return NULL; 3587 } 3588 done = (peek() == Token::RPAREN); 3589 if (!done) Expect(Token::COMMA, CHECK_OK); 3590 } 3591 Expect(Token::RPAREN, CHECK_OK); 3592 3593 Expect(Token::LBRACE, CHECK_OK); 3594 3595 // If we have a named function expression, we add a local variable 3596 // declaration to the body of the function with the name of the 3597 // function and let it refer to the function itself (closure). 3598 // NOTE: We create a proxy and resolve it here so that in the 3599 // future we can change the AST to only refer to VariableProxies 3600 // instead of Variables and Proxis as is the case now. 3601 if (!function_name.is_null() && function_name->length() > 0) { 3602 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 3603 VariableProxy* fproxy = 3604 top_scope_->NewUnresolved(function_name, inside_with()); 3605 fproxy->BindTo(fvar); 3606 body->Add(new(zone()) ExpressionStatement( 3607 new(zone()) Assignment(Token::INIT_CONST, fproxy, 3608 new(zone()) ThisFunction(), 3609 RelocInfo::kNoPosition))); 3610 } 3611 3612 // Determine if the function will be lazily compiled. The mode can 3613 // only be PARSE_LAZILY if the --lazy flag is true. 3614 bool is_lazily_compiled = (mode() == PARSE_LAZILY && 3615 top_scope_->outer_scope()->is_global_scope() && 3616 top_scope_->HasTrivialOuterContext() && 3617 !parenthesized_function_); 3618 parenthesized_function_ = false; // The bit was set for this function only. 3619 3620 int function_block_pos = scanner().location().beg_pos; 3621 if (is_lazily_compiled && pre_data() != NULL) { 3622 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 3623 if (!entry.is_valid()) { 3624 ReportInvalidPreparseData(name, CHECK_OK); 3625 } 3626 end_pos = entry.end_pos(); 3627 if (end_pos <= function_block_pos) { 3628 // End position greater than end of stream is safe, and hard to check. 3629 ReportInvalidPreparseData(name, CHECK_OK); 3630 } 3631 isolate()->counters()->total_preparse_skipped()->Increment( 3632 end_pos - function_block_pos); 3633 // Seek to position just before terminal '}'. 3634 scanner().SeekForward(end_pos - 1); 3635 materialized_literal_count = entry.literal_count(); 3636 expected_property_count = entry.property_count(); 3637 only_simple_this_property_assignments = false; 3638 this_property_assignments = isolate()->factory()->empty_fixed_array(); 3639 Expect(Token::RBRACE, CHECK_OK); 3640 } else { 3641 ParseSourceElements(body, Token::RBRACE, CHECK_OK); 3642 3643 materialized_literal_count = lexical_scope.materialized_literal_count(); 3644 expected_property_count = lexical_scope.expected_property_count(); 3645 only_simple_this_property_assignments = 3646 lexical_scope.only_simple_this_property_assignments(); 3647 this_property_assignments = lexical_scope.this_property_assignments(); 3648 3649 Expect(Token::RBRACE, CHECK_OK); 3650 end_pos = scanner().location().end_pos; 3651 } 3652 3653 // Validate strict mode. 3654 if (top_scope_->is_strict_mode()) { 3655 if (IsEvalOrArguments(name)) { 3656 int position = function_token_position != RelocInfo::kNoPosition 3657 ? function_token_position 3658 : (start_pos > 0 ? start_pos - 1 : start_pos); 3659 Scanner::Location location = Scanner::Location(position, start_pos); 3660 ReportMessageAt(location, 3661 "strict_function_name", Vector<const char*>::empty()); 3662 *ok = false; 3663 return NULL; 3664 } 3665 if (name_loc.IsValid()) { 3666 ReportMessageAt(name_loc, "strict_param_name", 3667 Vector<const char*>::empty()); 3668 *ok = false; 3669 return NULL; 3670 } 3671 if (dupe_loc.IsValid()) { 3672 ReportMessageAt(dupe_loc, "strict_param_dupe", 3673 Vector<const char*>::empty()); 3674 *ok = false; 3675 return NULL; 3676 } 3677 if (name_is_reserved) { 3678 int position = function_token_position != RelocInfo::kNoPosition 3679 ? function_token_position 3680 : (start_pos > 0 ? start_pos - 1 : start_pos); 3681 Scanner::Location location = Scanner::Location(position, start_pos); 3682 ReportMessageAt(location, "strict_reserved_word", 3683 Vector<const char*>::empty()); 3684 *ok = false; 3685 return NULL; 3686 } 3687 if (reserved_loc.IsValid()) { 3688 ReportMessageAt(reserved_loc, "strict_reserved_word", 3689 Vector<const char*>::empty()); 3690 *ok = false; 3691 return NULL; 3692 } 3693 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 3694 } 3695 } 3696 3697 FunctionLiteral* function_literal = 3698 new(zone()) FunctionLiteral(name, 3699 scope, 3700 body, 3701 materialized_literal_count, 3702 expected_property_count, 3703 only_simple_this_property_assignments, 3704 this_property_assignments, 3705 num_parameters, 3706 start_pos, 3707 end_pos, 3708 (function_name->length() > 0)); 3709 function_literal->set_function_token_position(function_token_position); 3710 3711 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); 3712 return function_literal; 3713} 3714 3715 3716Expression* Parser::ParseV8Intrinsic(bool* ok) { 3717 // CallRuntime :: 3718 // '%' Identifier Arguments 3719 3720 Expect(Token::MOD, CHECK_OK); 3721 Handle<String> name = ParseIdentifier(CHECK_OK); 3722 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 3723 3724 if (extension_ != NULL) { 3725 // The extension structures are only accessible while parsing the 3726 // very first time not when reparsing because of lazy compilation. 3727 top_scope_->ForceEagerCompilation(); 3728 } 3729 3730 const Runtime::Function* function = Runtime::FunctionForSymbol(name); 3731 3732 // Check for built-in IS_VAR macro. 3733 if (function != NULL && 3734 function->intrinsic_type == Runtime::RUNTIME && 3735 function->function_id == Runtime::kIS_VAR) { 3736 // %IS_VAR(x) evaluates to x if x is a variable, 3737 // leads to a parse error otherwise. Could be implemented as an 3738 // inline function %_IS_VAR(x) to eliminate this special case. 3739 if (args->length() == 1 && args->at(0)->AsVariableProxy() != NULL) { 3740 return args->at(0); 3741 } else { 3742 ReportMessage("unable_to_parse", Vector<const char*>::empty()); 3743 *ok = false; 3744 return NULL; 3745 } 3746 } 3747 3748 // Check that the expected number of arguments are being passed. 3749 if (function != NULL && 3750 function->nargs != -1 && 3751 function->nargs != args->length()) { 3752 ReportMessage("illegal_access", Vector<const char*>::empty()); 3753 *ok = false; 3754 return NULL; 3755 } 3756 3757 // We have a valid intrinsics call or a call to a builtin. 3758 return new(zone()) CallRuntime(name, function, args); 3759} 3760 3761 3762bool Parser::peek_any_identifier() { 3763 Token::Value next = peek(); 3764 return next == Token::IDENTIFIER || 3765 next == Token::FUTURE_RESERVED_WORD; 3766} 3767 3768 3769void Parser::Consume(Token::Value token) { 3770 Token::Value next = Next(); 3771 USE(next); 3772 USE(token); 3773 ASSERT(next == token); 3774} 3775 3776 3777void Parser::Expect(Token::Value token, bool* ok) { 3778 Token::Value next = Next(); 3779 if (next == token) return; 3780 ReportUnexpectedToken(next); 3781 *ok = false; 3782} 3783 3784 3785bool Parser::Check(Token::Value token) { 3786 Token::Value next = peek(); 3787 if (next == token) { 3788 Consume(next); 3789 return true; 3790 } 3791 return false; 3792} 3793 3794 3795void Parser::ExpectSemicolon(bool* ok) { 3796 // Check for automatic semicolon insertion according to 3797 // the rules given in ECMA-262, section 7.9, page 21. 3798 Token::Value tok = peek(); 3799 if (tok == Token::SEMICOLON) { 3800 Next(); 3801 return; 3802 } 3803 if (scanner().has_line_terminator_before_next() || 3804 tok == Token::RBRACE || 3805 tok == Token::EOS) { 3806 return; 3807 } 3808 Expect(Token::SEMICOLON, ok); 3809} 3810 3811 3812Literal* Parser::GetLiteralUndefined() { 3813 return new(zone()) Literal(isolate()->factory()->undefined_value()); 3814} 3815 3816 3817Literal* Parser::GetLiteralTheHole() { 3818 return new(zone()) Literal(isolate()->factory()->the_hole_value()); 3819} 3820 3821 3822Literal* Parser::GetLiteralNumber(double value) { 3823 return NewNumberLiteral(value); 3824} 3825 3826 3827Handle<String> Parser::ParseIdentifier(bool* ok) { 3828 bool is_reserved; 3829 return ParseIdentifierOrReservedWord(&is_reserved, ok); 3830} 3831 3832 3833Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, 3834 bool* ok) { 3835 *is_reserved = false; 3836 if (top_scope_->is_strict_mode()) { 3837 Expect(Token::IDENTIFIER, ok); 3838 } else { 3839 if (!Check(Token::IDENTIFIER)) { 3840 Expect(Token::FUTURE_RESERVED_WORD, ok); 3841 *is_reserved = true; 3842 } 3843 } 3844 if (!*ok) return Handle<String>(); 3845 return GetSymbol(ok); 3846} 3847 3848 3849Handle<String> Parser::ParseIdentifierName(bool* ok) { 3850 Token::Value next = Next(); 3851 if (next != Token::IDENTIFIER && 3852 next != Token::FUTURE_RESERVED_WORD && 3853 !Token::IsKeyword(next)) { 3854 ReportUnexpectedToken(next); 3855 *ok = false; 3856 return Handle<String>(); 3857 } 3858 return GetSymbol(ok); 3859} 3860 3861 3862// Checks LHS expression for assignment and prefix/postfix increment/decrement 3863// in strict mode. 3864void Parser::CheckStrictModeLValue(Expression* expression, 3865 const char* error, 3866 bool* ok) { 3867 ASSERT(top_scope_->is_strict_mode()); 3868 VariableProxy* lhs = expression != NULL 3869 ? expression->AsVariableProxy() 3870 : NULL; 3871 3872 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { 3873 ReportMessage(error, Vector<const char*>::empty()); 3874 *ok = false; 3875 } 3876} 3877 3878 3879// Checks whether octal literal last seen is between beg_pos and end_pos. 3880// If so, reports an error. 3881void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 3882 int octal = scanner().octal_position(); 3883 if (beg_pos <= octal && octal <= end_pos) { 3884 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", 3885 Vector<const char*>::empty()); 3886 scanner().clear_octal_position(); 3887 *ok = false; 3888 } 3889} 3890 3891 3892// This function reads an identifier and determines whether or not it 3893// is 'get' or 'set'. 3894Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3895 bool* is_set, 3896 bool* ok) { 3897 Handle<String> result = ParseIdentifier(ok); 3898 if (!*ok) return Handle<String>(); 3899 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 3900 const char* token = scanner().literal_ascii_string().start(); 3901 *is_get = strncmp(token, "get", 3) == 0; 3902 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 3903 } 3904 return result; 3905} 3906 3907 3908// ---------------------------------------------------------------------------- 3909// Parser support 3910 3911 3912bool Parser::TargetStackContainsLabel(Handle<String> label) { 3913 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3914 BreakableStatement* stat = t->node()->AsBreakableStatement(); 3915 if (stat != NULL && ContainsLabel(stat->labels(), label)) 3916 return true; 3917 } 3918 return false; 3919} 3920 3921 3922BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) { 3923 bool anonymous = label.is_null(); 3924 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3925 BreakableStatement* stat = t->node()->AsBreakableStatement(); 3926 if (stat == NULL) continue; 3927 if ((anonymous && stat->is_target_for_anonymous()) || 3928 (!anonymous && ContainsLabel(stat->labels(), label))) { 3929 RegisterTargetUse(stat->break_target(), t->previous()); 3930 return stat; 3931 } 3932 } 3933 return NULL; 3934} 3935 3936 3937IterationStatement* Parser::LookupContinueTarget(Handle<String> label, 3938 bool* ok) { 3939 bool anonymous = label.is_null(); 3940 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3941 IterationStatement* stat = t->node()->AsIterationStatement(); 3942 if (stat == NULL) continue; 3943 3944 ASSERT(stat->is_target_for_anonymous()); 3945 if (anonymous || ContainsLabel(stat->labels(), label)) { 3946 RegisterTargetUse(stat->continue_target(), t->previous()); 3947 return stat; 3948 } 3949 } 3950 return NULL; 3951} 3952 3953 3954void Parser::RegisterTargetUse(Label* target, Target* stop) { 3955 // Register that a break target found at the given stop in the 3956 // target stack has been used from the top of the target stack. Add 3957 // the break target to any TargetCollectors passed on the stack. 3958 for (Target* t = target_stack_; t != stop; t = t->previous()) { 3959 TargetCollector* collector = t->node()->AsTargetCollector(); 3960 if (collector != NULL) collector->AddTarget(target); 3961 } 3962} 3963 3964 3965Literal* Parser::NewNumberLiteral(double number) { 3966 return new(zone()) Literal(isolate()->factory()->NewNumber(number, TENURED)); 3967} 3968 3969 3970Expression* Parser::NewThrowReferenceError(Handle<String> type) { 3971 return NewThrowError(isolate()->factory()->MakeReferenceError_symbol(), 3972 type, HandleVector<Object>(NULL, 0)); 3973} 3974 3975 3976Expression* Parser::NewThrowSyntaxError(Handle<String> type, 3977 Handle<Object> first) { 3978 int argc = first.is_null() ? 0 : 1; 3979 Vector< Handle<Object> > arguments = HandleVector<Object>(&first, argc); 3980 return NewThrowError( 3981 isolate()->factory()->MakeSyntaxError_symbol(), type, arguments); 3982} 3983 3984 3985Expression* Parser::NewThrowTypeError(Handle<String> type, 3986 Handle<Object> first, 3987 Handle<Object> second) { 3988 ASSERT(!first.is_null() && !second.is_null()); 3989 Handle<Object> elements[] = { first, second }; 3990 Vector< Handle<Object> > arguments = 3991 HandleVector<Object>(elements, ARRAY_SIZE(elements)); 3992 return NewThrowError( 3993 isolate()->factory()->MakeTypeError_symbol(), type, arguments); 3994} 3995 3996 3997Expression* Parser::NewThrowError(Handle<String> constructor, 3998 Handle<String> type, 3999 Vector< Handle<Object> > arguments) { 4000 int argc = arguments.length(); 4001 Handle<FixedArray> elements = isolate()->factory()->NewFixedArray(argc, 4002 TENURED); 4003 for (int i = 0; i < argc; i++) { 4004 Handle<Object> element = arguments[i]; 4005 if (!element.is_null()) { 4006 elements->set(i, *element); 4007 } 4008 } 4009 Handle<JSArray> array = isolate()->factory()->NewJSArrayWithElements(elements, 4010 TENURED); 4011 4012 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); 4013 args->Add(new(zone()) Literal(type)); 4014 args->Add(new(zone()) Literal(array)); 4015 return new(zone()) Throw(new(zone()) CallRuntime(constructor, NULL, args), 4016 scanner().location().beg_pos); 4017} 4018 4019// ---------------------------------------------------------------------------- 4020// JSON 4021 4022Handle<Object> JsonParser::ParseJson(Handle<String> script, 4023 UC16CharacterStream* source) { 4024 scanner_.Initialize(source); 4025 stack_overflow_ = false; 4026 Handle<Object> result = ParseJsonValue(); 4027 if (result.is_null() || scanner_.Next() != Token::EOS) { 4028 if (stack_overflow_) { 4029 // Scanner failed. 4030 isolate()->StackOverflow(); 4031 } else { 4032 // Parse failed. Scanner's current token is the unexpected token. 4033 Token::Value token = scanner_.current_token(); 4034 4035 const char* message; 4036 const char* name_opt = NULL; 4037 4038 switch (token) { 4039 case Token::EOS: 4040 message = "unexpected_eos"; 4041 break; 4042 case Token::NUMBER: 4043 message = "unexpected_token_number"; 4044 break; 4045 case Token::STRING: 4046 message = "unexpected_token_string"; 4047 break; 4048 case Token::IDENTIFIER: 4049 case Token::FUTURE_RESERVED_WORD: 4050 message = "unexpected_token_identifier"; 4051 break; 4052 default: 4053 message = "unexpected_token"; 4054 name_opt = Token::String(token); 4055 ASSERT(name_opt != NULL); 4056 break; 4057 } 4058 4059 Scanner::Location source_location = scanner_.location(); 4060 Factory* factory = isolate()->factory(); 4061 MessageLocation location(factory->NewScript(script), 4062 source_location.beg_pos, 4063 source_location.end_pos); 4064 Handle<JSArray> array; 4065 if (name_opt == NULL) { 4066 array = factory->NewJSArray(0); 4067 } else { 4068 Handle<String> name = factory->NewStringFromUtf8(CStrVector(name_opt)); 4069 Handle<FixedArray> element = factory->NewFixedArray(1); 4070 element->set(0, *name); 4071 array = factory->NewJSArrayWithElements(element); 4072 } 4073 Handle<Object> result = factory->NewSyntaxError(message, array); 4074 isolate()->Throw(*result, &location); 4075 return Handle<Object>::null(); 4076 } 4077 } 4078 return result; 4079} 4080 4081 4082Handle<String> JsonParser::GetString() { 4083 int literal_length = scanner_.literal_length(); 4084 if (literal_length == 0) { 4085 return isolate()->factory()->empty_string(); 4086 } 4087 if (scanner_.is_literal_ascii()) { 4088 return isolate()->factory()->NewStringFromAscii( 4089 scanner_.literal_ascii_string()); 4090 } else { 4091 return isolate()->factory()->NewStringFromTwoByte( 4092 scanner_.literal_uc16_string()); 4093 } 4094} 4095 4096 4097// Parse any JSON value. 4098Handle<Object> JsonParser::ParseJsonValue() { 4099 Token::Value token = scanner_.Next(); 4100 switch (token) { 4101 case Token::STRING: 4102 return GetString(); 4103 case Token::NUMBER: 4104 return isolate()->factory()->NewNumber(scanner_.number()); 4105 case Token::FALSE_LITERAL: 4106 return isolate()->factory()->false_value(); 4107 case Token::TRUE_LITERAL: 4108 return isolate()->factory()->true_value(); 4109 case Token::NULL_LITERAL: 4110 return isolate()->factory()->null_value(); 4111 case Token::LBRACE: 4112 return ParseJsonObject(); 4113 case Token::LBRACK: 4114 return ParseJsonArray(); 4115 default: 4116 return ReportUnexpectedToken(); 4117 } 4118} 4119 4120 4121// Parse a JSON object. Scanner must be right after '{' token. 4122Handle<Object> JsonParser::ParseJsonObject() { 4123 Handle<JSFunction> object_constructor( 4124 isolate()->global_context()->object_function()); 4125 Handle<JSObject> json_object = 4126 isolate()->factory()->NewJSObject(object_constructor); 4127 if (scanner_.peek() == Token::RBRACE) { 4128 scanner_.Next(); 4129 } else { 4130 if (StackLimitCheck(isolate()).HasOverflowed()) { 4131 stack_overflow_ = true; 4132 return Handle<Object>::null(); 4133 } 4134 do { 4135 if (scanner_.Next() != Token::STRING) { 4136 return ReportUnexpectedToken(); 4137 } 4138 Handle<String> key = GetString(); 4139 if (scanner_.Next() != Token::COLON) { 4140 return ReportUnexpectedToken(); 4141 } 4142 Handle<Object> value = ParseJsonValue(); 4143 if (value.is_null()) return Handle<Object>::null(); 4144 uint32_t index; 4145 if (key->AsArrayIndex(&index)) { 4146 SetOwnElement(json_object, index, value, kNonStrictMode); 4147 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { 4148 // We can't remove the __proto__ accessor since it's hardcoded 4149 // in several places. Instead go along and add the value as 4150 // the prototype of the created object if possible. 4151 SetPrototype(json_object, value); 4152 } else { 4153 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); 4154 } 4155 } while (scanner_.Next() == Token::COMMA); 4156 if (scanner_.current_token() != Token::RBRACE) { 4157 return ReportUnexpectedToken(); 4158 } 4159 } 4160 return json_object; 4161} 4162 4163 4164// Parse a JSON array. Scanner must be right after '[' token. 4165Handle<Object> JsonParser::ParseJsonArray() { 4166 ZoneScope zone_scope(DELETE_ON_EXIT); 4167 ZoneList<Handle<Object> > elements(4); 4168 4169 Token::Value token = scanner_.peek(); 4170 if (token == Token::RBRACK) { 4171 scanner_.Next(); 4172 } else { 4173 if (StackLimitCheck(isolate()).HasOverflowed()) { 4174 stack_overflow_ = true; 4175 return Handle<Object>::null(); 4176 } 4177 do { 4178 Handle<Object> element = ParseJsonValue(); 4179 if (element.is_null()) return Handle<Object>::null(); 4180 elements.Add(element); 4181 token = scanner_.Next(); 4182 } while (token == Token::COMMA); 4183 if (token != Token::RBRACK) { 4184 return ReportUnexpectedToken(); 4185 } 4186 } 4187 4188 // Allocate a fixed array with all the elements. 4189 Handle<FixedArray> fast_elements = 4190 isolate()->factory()->NewFixedArray(elements.length()); 4191 4192 for (int i = 0, n = elements.length(); i < n; i++) { 4193 fast_elements->set(i, *elements[i]); 4194 } 4195 4196 return isolate()->factory()->NewJSArrayWithElements(fast_elements); 4197} 4198 4199// ---------------------------------------------------------------------------- 4200// Regular expressions 4201 4202 4203RegExpParser::RegExpParser(FlatStringReader* in, 4204 Handle<String>* error, 4205 bool multiline) 4206 : isolate_(Isolate::Current()), 4207 error_(error), 4208 captures_(NULL), 4209 in_(in), 4210 current_(kEndMarker), 4211 next_pos_(0), 4212 capture_count_(0), 4213 has_more_(true), 4214 multiline_(multiline), 4215 simple_(false), 4216 contains_anchor_(false), 4217 is_scanned_for_captures_(false), 4218 failed_(false) { 4219 Advance(); 4220} 4221 4222 4223uc32 RegExpParser::Next() { 4224 if (has_next()) { 4225 return in()->Get(next_pos_); 4226 } else { 4227 return kEndMarker; 4228 } 4229} 4230 4231 4232void RegExpParser::Advance() { 4233 if (next_pos_ < in()->length()) { 4234 StackLimitCheck check(isolate()); 4235 if (check.HasOverflowed()) { 4236 ReportError(CStrVector(Isolate::kStackOverflowMessage)); 4237 } else if (isolate()->zone()->excess_allocation()) { 4238 ReportError(CStrVector("Regular expression too large")); 4239 } else { 4240 current_ = in()->Get(next_pos_); 4241 next_pos_++; 4242 } 4243 } else { 4244 current_ = kEndMarker; 4245 has_more_ = false; 4246 } 4247} 4248 4249 4250void RegExpParser::Reset(int pos) { 4251 next_pos_ = pos; 4252 Advance(); 4253} 4254 4255 4256void RegExpParser::Advance(int dist) { 4257 next_pos_ += dist - 1; 4258 Advance(); 4259} 4260 4261 4262bool RegExpParser::simple() { 4263 return simple_; 4264} 4265 4266RegExpTree* RegExpParser::ReportError(Vector<const char> message) { 4267 failed_ = true; 4268 *error_ = isolate()->factory()->NewStringFromAscii(message, NOT_TENURED); 4269 // Zip to the end to make sure the no more input is read. 4270 current_ = kEndMarker; 4271 next_pos_ = in()->length(); 4272 return NULL; 4273} 4274 4275 4276// Pattern :: 4277// Disjunction 4278RegExpTree* RegExpParser::ParsePattern() { 4279 RegExpTree* result = ParseDisjunction(CHECK_FAILED); 4280 ASSERT(!has_more()); 4281 // If the result of parsing is a literal string atom, and it has the 4282 // same length as the input, then the atom is identical to the input. 4283 if (result->IsAtom() && result->AsAtom()->length() == in()->length()) { 4284 simple_ = true; 4285 } 4286 return result; 4287} 4288 4289 4290// Disjunction :: 4291// Alternative 4292// Alternative | Disjunction 4293// Alternative :: 4294// [empty] 4295// Term Alternative 4296// Term :: 4297// Assertion 4298// Atom 4299// Atom Quantifier 4300RegExpTree* RegExpParser::ParseDisjunction() { 4301 // Used to store current state while parsing subexpressions. 4302 RegExpParserState initial_state(NULL, INITIAL, 0); 4303 RegExpParserState* stored_state = &initial_state; 4304 // Cache the builder in a local variable for quick access. 4305 RegExpBuilder* builder = initial_state.builder(); 4306 while (true) { 4307 switch (current()) { 4308 case kEndMarker: 4309 if (stored_state->IsSubexpression()) { 4310 // Inside a parenthesized group when hitting end of input. 4311 ReportError(CStrVector("Unterminated group") CHECK_FAILED); 4312 } 4313 ASSERT_EQ(INITIAL, stored_state->group_type()); 4314 // Parsing completed successfully. 4315 return builder->ToRegExp(); 4316 case ')': { 4317 if (!stored_state->IsSubexpression()) { 4318 ReportError(CStrVector("Unmatched ')'") CHECK_FAILED); 4319 } 4320 ASSERT_NE(INITIAL, stored_state->group_type()); 4321 4322 Advance(); 4323 // End disjunction parsing and convert builder content to new single 4324 // regexp atom. 4325 RegExpTree* body = builder->ToRegExp(); 4326 4327 int end_capture_index = captures_started(); 4328 4329 int capture_index = stored_state->capture_index(); 4330 SubexpressionType type = stored_state->group_type(); 4331 4332 // Restore previous state. 4333 stored_state = stored_state->previous_state(); 4334 builder = stored_state->builder(); 4335 4336 // Build result of subexpression. 4337 if (type == CAPTURE) { 4338 RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index); 4339 captures_->at(capture_index - 1) = capture; 4340 body = capture; 4341 } else if (type != GROUPING) { 4342 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); 4343 bool is_positive = (type == POSITIVE_LOOKAHEAD); 4344 body = new(zone()) RegExpLookahead(body, 4345 is_positive, 4346 end_capture_index - capture_index, 4347 capture_index); 4348 } 4349 builder->AddAtom(body); 4350 // For compatability with JSC and ES3, we allow quantifiers after 4351 // lookaheads, and break in all cases. 4352 break; 4353 } 4354 case '|': { 4355 Advance(); 4356 builder->NewAlternative(); 4357 continue; 4358 } 4359 case '*': 4360 case '+': 4361 case '?': 4362 return ReportError(CStrVector("Nothing to repeat")); 4363 case '^': { 4364 Advance(); 4365 if (multiline_) { 4366 builder->AddAssertion( 4367 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE)); 4368 } else { 4369 builder->AddAssertion( 4370 new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT)); 4371 set_contains_anchor(); 4372 } 4373 continue; 4374 } 4375 case '$': { 4376 Advance(); 4377 RegExpAssertion::Type type = 4378 multiline_ ? RegExpAssertion::END_OF_LINE : 4379 RegExpAssertion::END_OF_INPUT; 4380 builder->AddAssertion(new(zone()) RegExpAssertion(type)); 4381 continue; 4382 } 4383 case '.': { 4384 Advance(); 4385 // everything except \x0a, \x0d, \u2028 and \u2029 4386 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); 4387 CharacterRange::AddClassEscape('.', ranges); 4388 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 4389 builder->AddAtom(atom); 4390 break; 4391 } 4392 case '(': { 4393 SubexpressionType type = CAPTURE; 4394 Advance(); 4395 if (current() == '?') { 4396 switch (Next()) { 4397 case ':': 4398 type = GROUPING; 4399 break; 4400 case '=': 4401 type = POSITIVE_LOOKAHEAD; 4402 break; 4403 case '!': 4404 type = NEGATIVE_LOOKAHEAD; 4405 break; 4406 default: 4407 ReportError(CStrVector("Invalid group") CHECK_FAILED); 4408 break; 4409 } 4410 Advance(2); 4411 } else { 4412 if (captures_ == NULL) { 4413 captures_ = new ZoneList<RegExpCapture*>(2); 4414 } 4415 if (captures_started() >= kMaxCaptures) { 4416 ReportError(CStrVector("Too many captures") CHECK_FAILED); 4417 } 4418 captures_->Add(NULL); 4419 } 4420 // Store current state and begin new disjunction parsing. 4421 stored_state = new(zone()) RegExpParserState(stored_state, 4422 type, 4423 captures_started()); 4424 builder = stored_state->builder(); 4425 continue; 4426 } 4427 case '[': { 4428 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); 4429 builder->AddAtom(atom); 4430 break; 4431 } 4432 // Atom :: 4433 // \ AtomEscape 4434 case '\\': 4435 switch (Next()) { 4436 case kEndMarker: 4437 return ReportError(CStrVector("\\ at end of pattern")); 4438 case 'b': 4439 Advance(2); 4440 builder->AddAssertion( 4441 new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY)); 4442 continue; 4443 case 'B': 4444 Advance(2); 4445 builder->AddAssertion( 4446 new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); 4447 continue; 4448 // AtomEscape :: 4449 // CharacterClassEscape 4450 // 4451 // CharacterClassEscape :: one of 4452 // d D s S w W 4453 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { 4454 uc32 c = Next(); 4455 Advance(2); 4456 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); 4457 CharacterRange::AddClassEscape(c, ranges); 4458 RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false); 4459 builder->AddAtom(atom); 4460 break; 4461 } 4462 case '1': case '2': case '3': case '4': case '5': case '6': 4463 case '7': case '8': case '9': { 4464 int index = 0; 4465 if (ParseBackReferenceIndex(&index)) { 4466 RegExpCapture* capture = NULL; 4467 if (captures_ != NULL && index <= captures_->length()) { 4468 capture = captures_->at(index - 1); 4469 } 4470 if (capture == NULL) { 4471 builder->AddEmpty(); 4472 break; 4473 } 4474 RegExpTree* atom = new(zone()) RegExpBackReference(capture); 4475 builder->AddAtom(atom); 4476 break; 4477 } 4478 uc32 first_digit = Next(); 4479 if (first_digit == '8' || first_digit == '9') { 4480 // Treat as identity escape 4481 builder->AddCharacter(first_digit); 4482 Advance(2); 4483 break; 4484 } 4485 } 4486 // FALLTHROUGH 4487 case '0': { 4488 Advance(); 4489 uc32 octal = ParseOctalLiteral(); 4490 builder->AddCharacter(octal); 4491 break; 4492 } 4493 // ControlEscape :: one of 4494 // f n r t v 4495 case 'f': 4496 Advance(2); 4497 builder->AddCharacter('\f'); 4498 break; 4499 case 'n': 4500 Advance(2); 4501 builder->AddCharacter('\n'); 4502 break; 4503 case 'r': 4504 Advance(2); 4505 builder->AddCharacter('\r'); 4506 break; 4507 case 't': 4508 Advance(2); 4509 builder->AddCharacter('\t'); 4510 break; 4511 case 'v': 4512 Advance(2); 4513 builder->AddCharacter('\v'); 4514 break; 4515 case 'c': { 4516 Advance(); 4517 uc32 controlLetter = Next(); 4518 // Special case if it is an ASCII letter. 4519 // Convert lower case letters to uppercase. 4520 uc32 letter = controlLetter & ~('a' ^ 'A'); 4521 if (letter < 'A' || 'Z' < letter) { 4522 // controlLetter is not in range 'A'-'Z' or 'a'-'z'. 4523 // This is outside the specification. We match JSC in 4524 // reading the backslash as a literal character instead 4525 // of as starting an escape. 4526 builder->AddCharacter('\\'); 4527 } else { 4528 Advance(2); 4529 builder->AddCharacter(controlLetter & 0x1f); 4530 } 4531 break; 4532 } 4533 case 'x': { 4534 Advance(2); 4535 uc32 value; 4536 if (ParseHexEscape(2, &value)) { 4537 builder->AddCharacter(value); 4538 } else { 4539 builder->AddCharacter('x'); 4540 } 4541 break; 4542 } 4543 case 'u': { 4544 Advance(2); 4545 uc32 value; 4546 if (ParseHexEscape(4, &value)) { 4547 builder->AddCharacter(value); 4548 } else { 4549 builder->AddCharacter('u'); 4550 } 4551 break; 4552 } 4553 default: 4554 // Identity escape. 4555 builder->AddCharacter(Next()); 4556 Advance(2); 4557 break; 4558 } 4559 break; 4560 case '{': { 4561 int dummy; 4562 if (ParseIntervalQuantifier(&dummy, &dummy)) { 4563 ReportError(CStrVector("Nothing to repeat") CHECK_FAILED); 4564 } 4565 // fallthrough 4566 } 4567 default: 4568 builder->AddCharacter(current()); 4569 Advance(); 4570 break; 4571 } // end switch(current()) 4572 4573 int min; 4574 int max; 4575 switch (current()) { 4576 // QuantifierPrefix :: 4577 // * 4578 // + 4579 // ? 4580 // { 4581 case '*': 4582 min = 0; 4583 max = RegExpTree::kInfinity; 4584 Advance(); 4585 break; 4586 case '+': 4587 min = 1; 4588 max = RegExpTree::kInfinity; 4589 Advance(); 4590 break; 4591 case '?': 4592 min = 0; 4593 max = 1; 4594 Advance(); 4595 break; 4596 case '{': 4597 if (ParseIntervalQuantifier(&min, &max)) { 4598 if (max < min) { 4599 ReportError(CStrVector("numbers out of order in {} quantifier.") 4600 CHECK_FAILED); 4601 } 4602 break; 4603 } else { 4604 continue; 4605 } 4606 default: 4607 continue; 4608 } 4609 RegExpQuantifier::Type type = RegExpQuantifier::GREEDY; 4610 if (current() == '?') { 4611 type = RegExpQuantifier::NON_GREEDY; 4612 Advance(); 4613 } else if (FLAG_regexp_possessive_quantifier && current() == '+') { 4614 // FLAG_regexp_possessive_quantifier is a debug-only flag. 4615 type = RegExpQuantifier::POSSESSIVE; 4616 Advance(); 4617 } 4618 builder->AddQuantifierToAtom(min, max, type); 4619 } 4620} 4621 4622 4623#ifdef DEBUG 4624// Currently only used in an ASSERT. 4625static bool IsSpecialClassEscape(uc32 c) { 4626 switch (c) { 4627 case 'd': case 'D': 4628 case 's': case 'S': 4629 case 'w': case 'W': 4630 return true; 4631 default: 4632 return false; 4633 } 4634} 4635#endif 4636 4637 4638// In order to know whether an escape is a backreference or not we have to scan 4639// the entire regexp and find the number of capturing parentheses. However we 4640// don't want to scan the regexp twice unless it is necessary. This mini-parser 4641// is called when needed. It can see the difference between capturing and 4642// noncapturing parentheses and can skip character classes and backslash-escaped 4643// characters. 4644void RegExpParser::ScanForCaptures() { 4645 // Start with captures started previous to current position 4646 int capture_count = captures_started(); 4647 // Add count of captures after this position. 4648 int n; 4649 while ((n = current()) != kEndMarker) { 4650 Advance(); 4651 switch (n) { 4652 case '\\': 4653 Advance(); 4654 break; 4655 case '[': { 4656 int c; 4657 while ((c = current()) != kEndMarker) { 4658 Advance(); 4659 if (c == '\\') { 4660 Advance(); 4661 } else { 4662 if (c == ']') break; 4663 } 4664 } 4665 break; 4666 } 4667 case '(': 4668 if (current() != '?') capture_count++; 4669 break; 4670 } 4671 } 4672 capture_count_ = capture_count; 4673 is_scanned_for_captures_ = true; 4674} 4675 4676 4677bool RegExpParser::ParseBackReferenceIndex(int* index_out) { 4678 ASSERT_EQ('\\', current()); 4679 ASSERT('1' <= Next() && Next() <= '9'); 4680 // Try to parse a decimal literal that is no greater than the total number 4681 // of left capturing parentheses in the input. 4682 int start = position(); 4683 int value = Next() - '0'; 4684 Advance(2); 4685 while (true) { 4686 uc32 c = current(); 4687 if (IsDecimalDigit(c)) { 4688 value = 10 * value + (c - '0'); 4689 if (value > kMaxCaptures) { 4690 Reset(start); 4691 return false; 4692 } 4693 Advance(); 4694 } else { 4695 break; 4696 } 4697 } 4698 if (value > captures_started()) { 4699 if (!is_scanned_for_captures_) { 4700 int saved_position = position(); 4701 ScanForCaptures(); 4702 Reset(saved_position); 4703 } 4704 if (value > capture_count_) { 4705 Reset(start); 4706 return false; 4707 } 4708 } 4709 *index_out = value; 4710 return true; 4711} 4712 4713 4714// QuantifierPrefix :: 4715// { DecimalDigits } 4716// { DecimalDigits , } 4717// { DecimalDigits , DecimalDigits } 4718// 4719// Returns true if parsing succeeds, and set the min_out and max_out 4720// values. Values are truncated to RegExpTree::kInfinity if they overflow. 4721bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) { 4722 ASSERT_EQ(current(), '{'); 4723 int start = position(); 4724 Advance(); 4725 int min = 0; 4726 if (!IsDecimalDigit(current())) { 4727 Reset(start); 4728 return false; 4729 } 4730 while (IsDecimalDigit(current())) { 4731 int next = current() - '0'; 4732 if (min > (RegExpTree::kInfinity - next) / 10) { 4733 // Overflow. Skip past remaining decimal digits and return -1. 4734 do { 4735 Advance(); 4736 } while (IsDecimalDigit(current())); 4737 min = RegExpTree::kInfinity; 4738 break; 4739 } 4740 min = 10 * min + next; 4741 Advance(); 4742 } 4743 int max = 0; 4744 if (current() == '}') { 4745 max = min; 4746 Advance(); 4747 } else if (current() == ',') { 4748 Advance(); 4749 if (current() == '}') { 4750 max = RegExpTree::kInfinity; 4751 Advance(); 4752 } else { 4753 while (IsDecimalDigit(current())) { 4754 int next = current() - '0'; 4755 if (max > (RegExpTree::kInfinity - next) / 10) { 4756 do { 4757 Advance(); 4758 } while (IsDecimalDigit(current())); 4759 max = RegExpTree::kInfinity; 4760 break; 4761 } 4762 max = 10 * max + next; 4763 Advance(); 4764 } 4765 if (current() != '}') { 4766 Reset(start); 4767 return false; 4768 } 4769 Advance(); 4770 } 4771 } else { 4772 Reset(start); 4773 return false; 4774 } 4775 *min_out = min; 4776 *max_out = max; 4777 return true; 4778} 4779 4780 4781uc32 RegExpParser::ParseOctalLiteral() { 4782 ASSERT('0' <= current() && current() <= '7'); 4783 // For compatibility with some other browsers (not all), we parse 4784 // up to three octal digits with a value below 256. 4785 uc32 value = current() - '0'; 4786 Advance(); 4787 if ('0' <= current() && current() <= '7') { 4788 value = value * 8 + current() - '0'; 4789 Advance(); 4790 if (value < 32 && '0' <= current() && current() <= '7') { 4791 value = value * 8 + current() - '0'; 4792 Advance(); 4793 } 4794 } 4795 return value; 4796} 4797 4798 4799bool RegExpParser::ParseHexEscape(int length, uc32 *value) { 4800 int start = position(); 4801 uc32 val = 0; 4802 bool done = false; 4803 for (int i = 0; !done; i++) { 4804 uc32 c = current(); 4805 int d = HexValue(c); 4806 if (d < 0) { 4807 Reset(start); 4808 return false; 4809 } 4810 val = val * 16 + d; 4811 Advance(); 4812 if (i == length - 1) { 4813 done = true; 4814 } 4815 } 4816 *value = val; 4817 return true; 4818} 4819 4820 4821uc32 RegExpParser::ParseClassCharacterEscape() { 4822 ASSERT(current() == '\\'); 4823 ASSERT(has_next() && !IsSpecialClassEscape(Next())); 4824 Advance(); 4825 switch (current()) { 4826 case 'b': 4827 Advance(); 4828 return '\b'; 4829 // ControlEscape :: one of 4830 // f n r t v 4831 case 'f': 4832 Advance(); 4833 return '\f'; 4834 case 'n': 4835 Advance(); 4836 return '\n'; 4837 case 'r': 4838 Advance(); 4839 return '\r'; 4840 case 't': 4841 Advance(); 4842 return '\t'; 4843 case 'v': 4844 Advance(); 4845 return '\v'; 4846 case 'c': { 4847 uc32 controlLetter = Next(); 4848 uc32 letter = controlLetter & ~('A' ^ 'a'); 4849 // For compatibility with JSC, inside a character class 4850 // we also accept digits and underscore as control characters. 4851 if ((controlLetter >= '0' && controlLetter <= '9') || 4852 controlLetter == '_' || 4853 (letter >= 'A' && letter <= 'Z')) { 4854 Advance(2); 4855 // Control letters mapped to ASCII control characters in the range 4856 // 0x00-0x1f. 4857 return controlLetter & 0x1f; 4858 } 4859 // We match JSC in reading the backslash as a literal 4860 // character instead of as starting an escape. 4861 return '\\'; 4862 } 4863 case '0': case '1': case '2': case '3': case '4': case '5': 4864 case '6': case '7': 4865 // For compatibility, we interpret a decimal escape that isn't 4866 // a back reference (and therefore either \0 or not valid according 4867 // to the specification) as a 1..3 digit octal character code. 4868 return ParseOctalLiteral(); 4869 case 'x': { 4870 Advance(); 4871 uc32 value; 4872 if (ParseHexEscape(2, &value)) { 4873 return value; 4874 } 4875 // If \x is not followed by a two-digit hexadecimal, treat it 4876 // as an identity escape. 4877 return 'x'; 4878 } 4879 case 'u': { 4880 Advance(); 4881 uc32 value; 4882 if (ParseHexEscape(4, &value)) { 4883 return value; 4884 } 4885 // If \u is not followed by a four-digit hexadecimal, treat it 4886 // as an identity escape. 4887 return 'u'; 4888 } 4889 default: { 4890 // Extended identity escape. We accept any character that hasn't 4891 // been matched by a more specific case, not just the subset required 4892 // by the ECMAScript specification. 4893 uc32 result = current(); 4894 Advance(); 4895 return result; 4896 } 4897 } 4898 return 0; 4899} 4900 4901 4902CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) { 4903 ASSERT_EQ(0, *char_class); 4904 uc32 first = current(); 4905 if (first == '\\') { 4906 switch (Next()) { 4907 case 'w': case 'W': case 'd': case 'D': case 's': case 'S': { 4908 *char_class = Next(); 4909 Advance(2); 4910 return CharacterRange::Singleton(0); // Return dummy value. 4911 } 4912 case kEndMarker: 4913 return ReportError(CStrVector("\\ at end of pattern")); 4914 default: 4915 uc32 c = ParseClassCharacterEscape(CHECK_FAILED); 4916 return CharacterRange::Singleton(c); 4917 } 4918 } else { 4919 Advance(); 4920 return CharacterRange::Singleton(first); 4921 } 4922} 4923 4924 4925static const uc16 kNoCharClass = 0; 4926 4927// Adds range or pre-defined character class to character ranges. 4928// If char_class is not kInvalidClass, it's interpreted as a class 4929// escape (i.e., 's' means whitespace, from '\s'). 4930static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges, 4931 uc16 char_class, 4932 CharacterRange range) { 4933 if (char_class != kNoCharClass) { 4934 CharacterRange::AddClassEscape(char_class, ranges); 4935 } else { 4936 ranges->Add(range); 4937 } 4938} 4939 4940 4941RegExpTree* RegExpParser::ParseCharacterClass() { 4942 static const char* kUnterminated = "Unterminated character class"; 4943 static const char* kRangeOutOfOrder = "Range out of order in character class"; 4944 4945 ASSERT_EQ(current(), '['); 4946 Advance(); 4947 bool is_negated = false; 4948 if (current() == '^') { 4949 is_negated = true; 4950 Advance(); 4951 } 4952 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); 4953 while (has_more() && current() != ']') { 4954 uc16 char_class = kNoCharClass; 4955 CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED); 4956 if (current() == '-') { 4957 Advance(); 4958 if (current() == kEndMarker) { 4959 // If we reach the end we break out of the loop and let the 4960 // following code report an error. 4961 break; 4962 } else if (current() == ']') { 4963 AddRangeOrEscape(ranges, char_class, first); 4964 ranges->Add(CharacterRange::Singleton('-')); 4965 break; 4966 } 4967 uc16 char_class_2 = kNoCharClass; 4968 CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED); 4969 if (char_class != kNoCharClass || char_class_2 != kNoCharClass) { 4970 // Either end is an escaped character class. Treat the '-' verbatim. 4971 AddRangeOrEscape(ranges, char_class, first); 4972 ranges->Add(CharacterRange::Singleton('-')); 4973 AddRangeOrEscape(ranges, char_class_2, next); 4974 continue; 4975 } 4976 if (first.from() > next.to()) { 4977 return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED); 4978 } 4979 ranges->Add(CharacterRange::Range(first.from(), next.to())); 4980 } else { 4981 AddRangeOrEscape(ranges, char_class, first); 4982 } 4983 } 4984 if (!has_more()) { 4985 return ReportError(CStrVector(kUnterminated) CHECK_FAILED); 4986 } 4987 Advance(); 4988 if (ranges->length() == 0) { 4989 ranges->Add(CharacterRange::Everything()); 4990 is_negated = !is_negated; 4991 } 4992 return new(zone()) RegExpCharacterClass(ranges, is_negated); 4993} 4994 4995 4996// ---------------------------------------------------------------------------- 4997// The Parser interface. 4998 4999ParserMessage::~ParserMessage() { 5000 for (int i = 0; i < args().length(); i++) 5001 DeleteArray(args()[i]); 5002 DeleteArray(args().start()); 5003} 5004 5005 5006ScriptDataImpl::~ScriptDataImpl() { 5007 if (owns_store_) store_.Dispose(); 5008} 5009 5010 5011int ScriptDataImpl::Length() { 5012 return store_.length() * sizeof(unsigned); 5013} 5014 5015 5016const char* ScriptDataImpl::Data() { 5017 return reinterpret_cast<const char*>(store_.start()); 5018} 5019 5020 5021bool ScriptDataImpl::HasError() { 5022 return has_error(); 5023} 5024 5025 5026void ScriptDataImpl::Initialize() { 5027 // Prepares state for use. 5028 if (store_.length() >= PreparseDataConstants::kHeaderSize) { 5029 function_index_ = PreparseDataConstants::kHeaderSize; 5030 int symbol_data_offset = PreparseDataConstants::kHeaderSize 5031 + store_[PreparseDataConstants::kFunctionsSizeOffset]; 5032 if (store_.length() > symbol_data_offset) { 5033 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); 5034 } else { 5035 // Partial preparse causes no symbol information. 5036 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5037 } 5038 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); 5039 } 5040} 5041 5042 5043int ScriptDataImpl::ReadNumber(byte** source) { 5044 // Reads a number from symbol_data_ in base 128. The most significant 5045 // bit marks that there are more digits. 5046 // If the first byte is 0x80 (kNumberTerminator), it would normally 5047 // represent a leading zero. Since that is useless, and therefore won't 5048 // appear as the first digit of any actual value, it is used to 5049 // mark the end of the input stream. 5050 byte* data = *source; 5051 if (data >= symbol_data_end_) return -1; 5052 byte input = *data; 5053 if (input == PreparseDataConstants::kNumberTerminator) { 5054 // End of stream marker. 5055 return -1; 5056 } 5057 int result = input & 0x7f; 5058 data++; 5059 while ((input & 0x80u) != 0) { 5060 if (data >= symbol_data_end_) return -1; 5061 input = *data; 5062 result = (result << 7) | (input & 0x7f); 5063 data++; 5064 } 5065 *source = data; 5066 return result; 5067} 5068 5069 5070// Create a Scanner for the preparser to use as input, and preparse the source. 5071static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5072 bool allow_lazy, 5073 ParserRecorder* recorder) { 5074 Isolate* isolate = Isolate::Current(); 5075 V8JavaScriptScanner scanner(isolate->unicode_cache()); 5076 scanner.Initialize(source); 5077 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5078 if (!preparser::PreParser::PreParseProgram(&scanner, 5079 recorder, 5080 allow_lazy, 5081 stack_limit)) { 5082 isolate->StackOverflow(); 5083 return NULL; 5084 } 5085 5086 // Extract the accumulated data from the recorder as a single 5087 // contiguous vector that we are responsible for disposing. 5088 Vector<unsigned> store = recorder->ExtractData(); 5089 return new ScriptDataImpl(store); 5090} 5091 5092 5093// Preparse, but only collect data that is immediately useful, 5094// even if the preparser data is only used once. 5095ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, 5096 v8::Extension* extension) { 5097 bool allow_lazy = FLAG_lazy && (extension == NULL); 5098 if (!allow_lazy) { 5099 // Partial preparsing is only about lazily compiled functions. 5100 // If we don't allow lazy compilation, the log data will be empty. 5101 return NULL; 5102 } 5103 PartialParserRecorder recorder; 5104 return DoPreParse(source, allow_lazy, &recorder); 5105} 5106 5107 5108ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, 5109 v8::Extension* extension) { 5110 Handle<Script> no_script; 5111 bool allow_lazy = FLAG_lazy && (extension == NULL); 5112 CompleteParserRecorder recorder; 5113 return DoPreParse(source, allow_lazy, &recorder); 5114} 5115 5116 5117bool RegExpParser::ParseRegExp(FlatStringReader* input, 5118 bool multiline, 5119 RegExpCompileData* result) { 5120 ASSERT(result != NULL); 5121 RegExpParser parser(input, &result->error, multiline); 5122 RegExpTree* tree = parser.ParsePattern(); 5123 if (parser.failed()) { 5124 ASSERT(tree == NULL); 5125 ASSERT(!result->error.is_null()); 5126 } else { 5127 ASSERT(tree != NULL); 5128 ASSERT(result->error.is_null()); 5129 result->tree = tree; 5130 int capture_count = parser.captures_started(); 5131 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; 5132 result->contains_anchor = parser.contains_anchor(); 5133 result->capture_count = capture_count; 5134 } 5135 return !parser.failed(); 5136} 5137 5138 5139bool ParserApi::Parse(CompilationInfo* info) { 5140 ASSERT(info->function() == NULL); 5141 FunctionLiteral* result = NULL; 5142 Handle<Script> script = info->script(); 5143 if (info->is_lazy()) { 5144 bool allow_natives_syntax = 5145 FLAG_allow_natives_syntax || 5146 info->is_native(); 5147 Parser parser(script, allow_natives_syntax, NULL, NULL); 5148 result = parser.ParseLazy(info); 5149 } else { 5150 bool allow_natives_syntax = 5151 info->is_native() || FLAG_allow_natives_syntax; 5152 ScriptDataImpl* pre_data = info->pre_parse_data(); 5153 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); 5154 if (pre_data != NULL && pre_data->has_error()) { 5155 Scanner::Location loc = pre_data->MessageLocation(); 5156 const char* message = pre_data->BuildMessage(); 5157 Vector<const char*> args = pre_data->BuildArgs(); 5158 parser.ReportMessageAt(loc, message, args); 5159 DeleteArray(message); 5160 for (int i = 0; i < args.length(); i++) { 5161 DeleteArray(args[i]); 5162 } 5163 DeleteArray(args.start()); 5164 ASSERT(info->isolate()->has_pending_exception()); 5165 } else { 5166 Handle<String> source = Handle<String>(String::cast(script->source())); 5167 result = parser.ParseProgram(source, 5168 info->is_global(), 5169 info->StrictMode()); 5170 } 5171 } 5172 5173 info->SetFunction(result); 5174 return (result != NULL); 5175} 5176 5177} } // namespace v8::internal 5178