| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "platform.h" | 39 #include "platform.h" |
| 40 #include "preparser.h" | 40 #include "preparser.h" |
| 41 #include "runtime.h" | 41 #include "runtime.h" |
| 42 #include "scanner-character-streams.h" | 42 #include "scanner-character-streams.h" |
| 43 #include "scopeinfo.h" | 43 #include "scopeinfo.h" |
| 44 #include "string-stream.h" | 44 #include "string-stream.h" |
| 45 | 45 |
| 46 namespace v8 { | 46 namespace v8 { |
| 47 namespace internal { | 47 namespace internal { |
| 48 | 48 |
| 49 // PositionStack is used for on-stack allocation of token positions for |
| 50 // new expressions. Please look at ParseNewExpression. |
| 51 |
| 52 class PositionStack { |
| 53 public: |
| 54 explicit PositionStack(bool* ok) : top_(NULL), ok_(ok) {} |
| 55 ~PositionStack() { |
| 56 ASSERT(!*ok_ || is_empty()); |
| 57 USE(ok_); |
| 58 } |
| 59 |
| 60 class Element { |
| 61 public: |
| 62 Element(PositionStack* stack, int value) { |
| 63 previous_ = stack->top(); |
| 64 value_ = value; |
| 65 stack->set_top(this); |
| 66 } |
| 67 |
| 68 private: |
| 69 Element* previous() { return previous_; } |
| 70 int value() { return value_; } |
| 71 friend class PositionStack; |
| 72 Element* previous_; |
| 73 int value_; |
| 74 }; |
| 75 |
| 76 bool is_empty() { return top_ == NULL; } |
| 77 int pop() { |
| 78 ASSERT(!is_empty()); |
| 79 int result = top_->value(); |
| 80 top_ = top_->previous(); |
| 81 return result; |
| 82 } |
| 83 |
| 84 private: |
| 85 Element* top() { return top_; } |
| 86 void set_top(Element* value) { top_ = value; } |
| 87 Element* top_; |
| 88 bool* ok_; |
| 89 }; |
| 90 |
| 91 |
| 49 RegExpBuilder::RegExpBuilder(Zone* zone) | 92 RegExpBuilder::RegExpBuilder(Zone* zone) |
| 50 : zone_(zone), | 93 : zone_(zone), |
| 51 pending_empty_(false), | 94 pending_empty_(false), |
| 52 characters_(NULL), | 95 characters_(NULL), |
| 53 terms_(), | 96 terms_(), |
| 54 alternatives_() | 97 alternatives_() |
| 55 #ifdef DEBUG | 98 #ifdef DEBUG |
| 56 , last_added_(ADD_NONE) | 99 , last_added_(ADD_NONE) |
| 57 #endif | 100 #endif |
| 58 {} | 101 {} |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 UNREACHABLE(); | 243 UNREACHABLE(); |
| 201 return; | 244 return; |
| 202 } | 245 } |
| 203 terms_.Add( | 246 terms_.Add( |
| 204 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); | 247 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); |
| 205 LAST(ADD_TERM); | 248 LAST(ADD_TERM); |
| 206 } | 249 } |
| 207 | 250 |
| 208 | 251 |
| 209 Handle<String> Parser::LookupSymbol(int symbol_id) { | 252 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 210 // If there is no preparser symbol data, a negative number will be passed. In | 253 // Length of symbol cache is the number of identified symbols. |
| 211 // that case, we'll just read the literal from Scanner. This also guards | 254 // If we are larger than that, or negative, it's not a cached symbol. |
| 212 // against corrupt preparse data where the symbol id is larger than the symbol | 255 // This might also happen if there is no preparser symbol data, even |
| 213 // count. | 256 // if there is some preparser data. |
| 214 if (symbol_id < 0 || | 257 if (static_cast<unsigned>(symbol_id) |
| 215 (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) { | 258 >= static_cast<unsigned>(symbol_cache_.length())) { |
| 216 if (scanner()->is_literal_ascii()) { | 259 if (scanner().is_literal_ascii()) { |
| 217 return isolate()->factory()->InternalizeOneByteString( | 260 return isolate()->factory()->InternalizeOneByteString( |
| 218 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); | 261 Vector<const uint8_t>::cast(scanner().literal_ascii_string())); |
| 219 } else { | 262 } else { |
| 220 return isolate()->factory()->InternalizeTwoByteString( | 263 return isolate()->factory()->InternalizeTwoByteString( |
| 221 scanner()->literal_utf16_string()); | 264 scanner().literal_utf16_string()); |
| 222 } | 265 } |
| 223 } | 266 } |
| 224 return LookupCachedSymbol(symbol_id); | 267 return LookupCachedSymbol(symbol_id); |
| 225 } | 268 } |
| 226 | 269 |
| 227 | 270 |
| 228 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { | 271 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { |
| 229 // Make sure the cache is large enough to hold the symbol identifier. | 272 // Make sure the cache is large enough to hold the symbol identifier. |
| 230 if (symbol_cache_.length() <= symbol_id) { | 273 if (symbol_cache_.length() <= symbol_id) { |
| 231 // Increase length to index + 1. | 274 // Increase length to index + 1. |
| 232 symbol_cache_.AddBlock(Handle<String>::null(), | 275 symbol_cache_.AddBlock(Handle<String>::null(), |
| 233 symbol_id + 1 - symbol_cache_.length(), zone()); | 276 symbol_id + 1 - symbol_cache_.length(), zone()); |
| 234 } | 277 } |
| 235 Handle<String> result = symbol_cache_.at(symbol_id); | 278 Handle<String> result = symbol_cache_.at(symbol_id); |
| 236 if (result.is_null()) { | 279 if (result.is_null()) { |
| 237 if (scanner()->is_literal_ascii()) { | 280 if (scanner().is_literal_ascii()) { |
| 238 result = isolate()->factory()->InternalizeOneByteString( | 281 result = isolate()->factory()->InternalizeOneByteString( |
| 239 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); | 282 Vector<const uint8_t>::cast(scanner().literal_ascii_string())); |
| 240 } else { | 283 } else { |
| 241 result = isolate()->factory()->InternalizeTwoByteString( | 284 result = isolate()->factory()->InternalizeTwoByteString( |
| 242 scanner()->literal_utf16_string()); | 285 scanner().literal_utf16_string()); |
| 243 } | 286 } |
| 244 symbol_cache_.at(symbol_id) = result; | 287 symbol_cache_.at(symbol_id) = result; |
| 245 return result; | 288 return result; |
| 246 } | 289 } |
| 247 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); | 290 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); |
| 248 return result; | 291 return result; |
| 249 } | 292 } |
| 250 | 293 |
| 251 | 294 |
| 252 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 295 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 *variable_ = previous_; | 456 *variable_ = previous_; |
| 414 } | 457 } |
| 415 | 458 |
| 416 private: | 459 private: |
| 417 Target** variable_; | 460 Target** variable_; |
| 418 Target* previous_; | 461 Target* previous_; |
| 419 }; | 462 }; |
| 420 | 463 |
| 421 | 464 |
| 422 // ---------------------------------------------------------------------------- | 465 // ---------------------------------------------------------------------------- |
| 466 // FunctionState and BlockState together implement the parser's scope stack. |
| 467 // The parser's current scope is in top_scope_. The BlockState and |
| 468 // FunctionState constructors push on the scope stack and the destructors |
| 469 // pop. They are also used to hold the parser's per-function and per-block |
| 470 // state. |
| 471 |
| 472 class Parser::BlockState BASE_EMBEDDED { |
| 473 public: |
| 474 BlockState(Parser* parser, Scope* scope) |
| 475 : parser_(parser), |
| 476 outer_scope_(parser->top_scope_) { |
| 477 parser->top_scope_ = scope; |
| 478 } |
| 479 |
| 480 ~BlockState() { parser_->top_scope_ = outer_scope_; } |
| 481 |
| 482 private: |
| 483 Parser* parser_; |
| 484 Scope* outer_scope_; |
| 485 }; |
| 486 |
| 487 |
| 488 Parser::FunctionState::FunctionState(Parser* parser, Scope* scope) |
| 489 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
| 490 next_handler_index_(0), |
| 491 expected_property_count_(0), |
| 492 generator_object_variable_(NULL), |
| 493 parser_(parser), |
| 494 outer_function_state_(parser->current_function_state_), |
| 495 outer_scope_(parser->top_scope_), |
| 496 saved_ast_node_id_(parser->zone()->isolate()->ast_node_id()), |
| 497 factory_(parser->zone()) { |
| 498 parser->top_scope_ = scope; |
| 499 parser->current_function_state_ = this; |
| 500 parser->zone()->isolate()->set_ast_node_id(BailoutId::FirstUsable().ToInt()); |
| 501 } |
| 502 |
| 503 |
| 504 Parser::FunctionState::~FunctionState() { |
| 505 parser_->top_scope_ = outer_scope_; |
| 506 parser_->current_function_state_ = outer_function_state_; |
| 507 if (outer_function_state_ != NULL) { |
| 508 parser_->isolate()->set_ast_node_id(saved_ast_node_id_); |
| 509 } |
| 510 } |
| 511 |
| 512 |
| 513 // ---------------------------------------------------------------------------- |
| 423 // The CHECK_OK macro is a convenient macro to enforce error | 514 // The CHECK_OK macro is a convenient macro to enforce error |
| 424 // handling for functions that may fail (by returning !*ok). | 515 // handling for functions that may fail (by returning !*ok). |
| 425 // | 516 // |
| 426 // CAUTION: This macro appends extra statements after a call, | 517 // CAUTION: This macro appends extra statements after a call, |
| 427 // thus it must never be used where only a single statement | 518 // thus it must never be used where only a single statement |
| 428 // is correct (e.g. an if statement branch w/o braces)! | 519 // is correct (e.g. an if statement branch w/o braces)! |
| 429 | 520 |
| 430 #define CHECK_OK ok); \ | 521 #define CHECK_OK ok); \ |
| 431 if (!*ok) return NULL; \ | 522 if (!*ok) return NULL; \ |
| 432 ((void)0 | 523 ((void)0 |
| 433 #define DUMMY ) // to make indentation work | 524 #define DUMMY ) // to make indentation work |
| 434 #undef DUMMY | 525 #undef DUMMY |
| 435 | 526 |
| 436 #define CHECK_FAILED /**/); \ | 527 #define CHECK_FAILED /**/); \ |
| 437 if (failed_) return NULL; \ | 528 if (failed_) return NULL; \ |
| 438 ((void)0 | 529 ((void)0 |
| 439 #define DUMMY ) // to make indentation work | 530 #define DUMMY ) // to make indentation work |
| 440 #undef DUMMY | 531 #undef DUMMY |
| 441 | 532 |
| 442 // ---------------------------------------------------------------------------- | 533 // ---------------------------------------------------------------------------- |
| 443 // Implementation of Parser | 534 // Implementation of Parser |
| 444 | 535 |
| 445 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | |
| 446 return identifier.is_identical_to( | |
| 447 parser_->isolate()->factory()->eval_string()) || | |
| 448 identifier.is_identical_to( | |
| 449 parser_->isolate()->factory()->arguments_string()); | |
| 450 } | |
| 451 | |
| 452 | |
| 453 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | |
| 454 const char* message, | |
| 455 Vector<const char*> args) { | |
| 456 MessageLocation location(parser_->script_, | |
| 457 source_location.beg_pos, | |
| 458 source_location.end_pos); | |
| 459 Factory* factory = parser_->isolate()->factory(); | |
| 460 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 461 for (int i = 0; i < args.length(); i++) { | |
| 462 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | |
| 463 elements->set(i, *arg_string); | |
| 464 } | |
| 465 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 466 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 467 parser_->isolate()->Throw(*result, &location); | |
| 468 } | |
| 469 | |
| 470 | |
| 471 void ParserTraits::ReportMessage(const char* message, | |
| 472 Vector<Handle<String> > args) { | |
| 473 Scanner::Location source_location = parser_->scanner()->location(); | |
| 474 ReportMessageAt(source_location, message, args); | |
| 475 } | |
| 476 | |
| 477 | |
| 478 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | |
| 479 const char* message, | |
| 480 Vector<Handle<String> > args) { | |
| 481 MessageLocation location(parser_->script_, | |
| 482 source_location.beg_pos, | |
| 483 source_location.end_pos); | |
| 484 Factory* factory = parser_->isolate()->factory(); | |
| 485 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | |
| 486 for (int i = 0; i < args.length(); i++) { | |
| 487 elements->set(i, *args[i]); | |
| 488 } | |
| 489 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | |
| 490 Handle<Object> result = factory->NewSyntaxError(message, array); | |
| 491 parser_->isolate()->Throw(*result, &location); | |
| 492 } | |
| 493 | |
| 494 | |
| 495 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | |
| 496 int symbol_id = -1; | |
| 497 if (parser_->pre_parse_data() != NULL) { | |
| 498 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | |
| 499 } | |
| 500 return parser_->LookupSymbol(symbol_id); | |
| 501 } | |
| 502 | |
| 503 | |
| 504 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | |
| 505 PretenureFlag tenured) { | |
| 506 if (scanner->is_next_literal_ascii()) { | |
| 507 return parser_->isolate_->factory()->NewStringFromAscii( | |
| 508 scanner->next_literal_ascii_string(), tenured); | |
| 509 } else { | |
| 510 return parser_->isolate_->factory()->NewStringFromTwoByte( | |
| 511 scanner->next_literal_utf16_string(), tenured); | |
| 512 } | |
| 513 } | |
| 514 | |
| 515 | |
| 516 Expression* ParserTraits::ThisExpression( | |
| 517 Scope* scope, | |
| 518 AstNodeFactory<AstConstructionVisitor>* factory) { | |
| 519 return factory->NewVariableProxy(scope->receiver()); | |
| 520 } | |
| 521 | |
| 522 | |
| 523 Expression* ParserTraits::ExpressionFromLiteral( | |
| 524 Token::Value token, int pos, | |
| 525 Scanner* scanner, | |
| 526 AstNodeFactory<AstConstructionVisitor>* factory) { | |
| 527 Factory* isolate_factory = parser_->isolate()->factory(); | |
| 528 switch (token) { | |
| 529 case Token::NULL_LITERAL: | |
| 530 return factory->NewLiteral(isolate_factory->null_value(), pos); | |
| 531 case Token::TRUE_LITERAL: | |
| 532 return factory->NewLiteral(isolate_factory->true_value(), pos); | |
| 533 case Token::FALSE_LITERAL: | |
| 534 return factory->NewLiteral(isolate_factory->false_value(), pos); | |
| 535 case Token::NUMBER: { | |
| 536 ASSERT(scanner->is_literal_ascii()); | |
| 537 double value = StringToDouble(parser_->isolate()->unicode_cache(), | |
| 538 scanner->literal_ascii_string(), | |
| 539 ALLOW_HEX | ALLOW_OCTAL | | |
| 540 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | |
| 541 return factory->NewNumberLiteral(value, pos); | |
| 542 } | |
| 543 default: | |
| 544 ASSERT(false); | |
| 545 } | |
| 546 return NULL; | |
| 547 } | |
| 548 | |
| 549 | |
| 550 Expression* ParserTraits::ExpressionFromIdentifier( | |
| 551 Handle<String> name, int pos, Scope* scope, | |
| 552 AstNodeFactory<AstConstructionVisitor>* factory) { | |
| 553 if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name); | |
| 554 // The name may refer to a module instance object, so its type is unknown. | |
| 555 #ifdef DEBUG | |
| 556 if (FLAG_print_interface_details) | |
| 557 PrintF("# Variable %s ", name->ToAsciiArray()); | |
| 558 #endif | |
| 559 Interface* interface = Interface::NewUnknown(parser_->zone()); | |
| 560 return scope->NewUnresolved(factory, name, interface, pos); | |
| 561 } | |
| 562 | |
| 563 | |
| 564 Expression* ParserTraits::ExpressionFromString( | |
| 565 int pos, Scanner* scanner, | |
| 566 AstNodeFactory<AstConstructionVisitor>* factory) { | |
| 567 Handle<String> symbol = GetSymbol(scanner); | |
| 568 if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol); | |
| 569 return factory->NewLiteral(symbol, pos); | |
| 570 } | |
| 571 | |
| 572 | |
| 573 Literal* ParserTraits::GetLiteralTheHole( | |
| 574 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | |
| 575 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | |
| 576 RelocInfo::kNoPosition); | |
| 577 } | |
| 578 | |
| 579 | |
| 580 Expression* ParserTraits::ParseObjectLiteral(bool* ok) { | |
| 581 return parser_->ParseObjectLiteral(ok); | |
| 582 } | |
| 583 | |
| 584 | |
| 585 Expression* ParserTraits::ParseAssignmentExpression(bool accept_IN, bool* ok) { | |
| 586 return parser_->ParseAssignmentExpression(accept_IN, ok); | |
| 587 } | |
| 588 | |
| 589 | |
| 590 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | |
| 591 return parser_->ParseV8Intrinsic(ok); | |
| 592 } | |
| 593 | |
| 594 | |
| 595 Parser::Parser(CompilationInfo* info) | 536 Parser::Parser(CompilationInfo* info) |
| 596 : ParserBase<ParserTraits>(&scanner_, | 537 : ParserBase(&scanner_, info->isolate()->stack_guard()->real_climit()), |
| 597 info->isolate()->stack_guard()->real_climit(), | |
| 598 info->extension(), | |
| 599 info->zone(), | |
| 600 this), | |
| 601 isolate_(info->isolate()), | 538 isolate_(info->isolate()), |
| 602 symbol_cache_(0, info->zone()), | 539 symbol_cache_(0, info->zone()), |
| 603 script_(info->script()), | 540 script_(info->script()), |
| 604 scanner_(isolate_->unicode_cache()), | 541 scanner_(isolate_->unicode_cache()), |
| 605 reusable_preparser_(NULL), | 542 reusable_preparser_(NULL), |
| 543 top_scope_(NULL), |
| 606 original_scope_(NULL), | 544 original_scope_(NULL), |
| 545 current_function_state_(NULL), |
| 607 target_stack_(NULL), | 546 target_stack_(NULL), |
| 547 extension_(info->extension()), |
| 608 pre_parse_data_(NULL), | 548 pre_parse_data_(NULL), |
| 609 fni_(NULL), | 549 fni_(NULL), |
| 550 parenthesized_function_(false), |
| 551 zone_(info->zone()), |
| 610 info_(info) { | 552 info_(info) { |
| 611 ASSERT(!script_.is_null()); | 553 ASSERT(!script_.is_null()); |
| 612 isolate_->set_ast_node_id(0); | 554 isolate_->set_ast_node_id(0); |
| 613 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 555 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 614 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 556 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 615 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 557 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 616 set_allow_lazy(false); // Must be explicitly enabled. | 558 set_allow_lazy(false); // Must be explicitly enabled. |
| 617 set_allow_generators(FLAG_harmony_generators); | 559 set_allow_generators(FLAG_harmony_generators); |
| 618 set_allow_for_of(FLAG_harmony_iteration); | 560 set_allow_for_of(FLAG_harmony_iteration); |
| 619 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 561 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 PrintF("[parsing script"); | 603 PrintF("[parsing script"); |
| 662 } | 604 } |
| 663 PrintF(" - took %0.3f ms]\n", ms); | 605 PrintF(" - took %0.3f ms]\n", ms); |
| 664 } | 606 } |
| 665 return result; | 607 return result; |
| 666 } | 608 } |
| 667 | 609 |
| 668 | 610 |
| 669 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 611 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
| 670 Handle<String> source) { | 612 Handle<String> source) { |
| 671 ASSERT(scope_ == NULL); | 613 ASSERT(top_scope_ == NULL); |
| 672 ASSERT(target_stack_ == NULL); | 614 ASSERT(target_stack_ == NULL); |
| 673 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | 615 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
| 674 | 616 |
| 675 Handle<String> no_name = isolate()->factory()->empty_string(); | 617 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 676 | 618 |
| 677 FunctionLiteral* result = NULL; | 619 FunctionLiteral* result = NULL; |
| 678 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 679 info->SetGlobalScope(scope); | 621 info->SetGlobalScope(scope); |
| 680 if (!info->context().is_null()) { | 622 if (!info->context().is_null()) { |
| 681 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 682 } | 624 } |
| 683 original_scope_ = scope; | 625 original_scope_ = scope; |
| 684 if (info->is_eval()) { | 626 if (info->is_eval()) { |
| 685 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 627 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
| 686 scope = NewScope(scope, EVAL_SCOPE); | 628 scope = NewScope(scope, EVAL_SCOPE); |
| 687 } | 629 } |
| 688 } else if (info->is_global()) { | 630 } else if (info->is_global()) { |
| 689 scope = NewScope(scope, GLOBAL_SCOPE); | 631 scope = NewScope(scope, GLOBAL_SCOPE); |
| 690 } | 632 } |
| 691 scope->set_start_position(0); | 633 scope->set_start_position(0); |
| 692 scope->set_end_position(source->length()); | 634 scope->set_end_position(source->length()); |
| 693 | 635 |
| 694 // Compute the parsing mode. | 636 // Compute the parsing mode. |
| 695 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 637 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 696 if (allow_natives_syntax() || | 638 if (allow_natives_syntax() || |
| 697 extension_ != NULL || | 639 extension_ != NULL || |
| 698 scope->is_eval_scope()) { | 640 scope->is_eval_scope()) { |
| 699 mode = PARSE_EAGERLY; | 641 mode = PARSE_EAGERLY; |
| 700 } | 642 } |
| 701 ParsingModeScope parsing_mode(this, mode); | 643 ParsingModeScope parsing_mode(this, mode); |
| 702 | 644 |
| 703 // Enters 'scope'. | 645 // Enters 'scope'. |
| 704 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 646 FunctionState function_state(this, scope); |
| 705 | 647 |
| 706 scope_->SetLanguageMode(info->language_mode()); | 648 top_scope_->SetLanguageMode(info->language_mode()); |
| 707 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 649 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 708 bool ok = true; | 650 bool ok = true; |
| 709 int beg_pos = scanner()->location().beg_pos; | 651 int beg_pos = scanner().location().beg_pos; |
| 710 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 652 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 711 if (ok && !scope_->is_classic_mode()) { | 653 if (ok && !top_scope_->is_classic_mode()) { |
| 712 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 654 CheckOctalLiteral(beg_pos, scanner().location().end_pos, &ok); |
| 713 } | 655 } |
| 714 | 656 |
| 715 if (ok && is_extended_mode()) { | 657 if (ok && is_extended_mode()) { |
| 716 CheckConflictingVarDeclarations(scope_, &ok); | 658 CheckConflictingVarDeclarations(top_scope_, &ok); |
| 717 } | 659 } |
| 718 | 660 |
| 719 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 661 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 720 if (body->length() != 1 || | 662 if (body->length() != 1 || |
| 721 !body->at(0)->IsExpressionStatement() || | 663 !body->at(0)->IsExpressionStatement() || |
| 722 !body->at(0)->AsExpressionStatement()-> | 664 !body->at(0)->AsExpressionStatement()-> |
| 723 expression()->IsFunctionLiteral()) { | 665 expression()->IsFunctionLiteral()) { |
| 724 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 666 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 725 ok = false; | 667 ok = false; |
| 726 } | 668 } |
| 727 } | 669 } |
| 728 | 670 |
| 729 if (ok) { | 671 if (ok) { |
| 730 result = factory()->NewFunctionLiteral( | 672 result = factory()->NewFunctionLiteral( |
| 731 no_name, | 673 no_name, |
| 732 scope_, | 674 top_scope_, |
| 733 body, | 675 body, |
| 734 function_state.materialized_literal_count(), | 676 function_state.materialized_literal_count(), |
| 735 function_state.expected_property_count(), | 677 function_state.expected_property_count(), |
| 736 function_state.handler_count(), | 678 function_state.handler_count(), |
| 737 0, | 679 0, |
| 738 FunctionLiteral::kNoDuplicateParameters, | 680 FunctionLiteral::kNoDuplicateParameters, |
| 739 FunctionLiteral::ANONYMOUS_EXPRESSION, | 681 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 740 FunctionLiteral::kGlobalOrEval, | 682 FunctionLiteral::kGlobalOrEval, |
| 741 FunctionLiteral::kNotParenthesized, | 683 FunctionLiteral::kNotParenthesized, |
| 742 FunctionLiteral::kNotGenerator, | 684 FunctionLiteral::kNotGenerator, |
| 743 0); | 685 0); |
| 744 result->set_ast_properties(factory()->visitor()->ast_properties()); | 686 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 745 result->set_slot_processor(factory()->visitor()->slot_processor()); | |
| 746 result->set_dont_optimize_reason( | 687 result->set_dont_optimize_reason( |
| 747 factory()->visitor()->dont_optimize_reason()); | 688 factory()->visitor()->dont_optimize_reason()); |
| 748 } else if (stack_overflow()) { | 689 } else if (stack_overflow()) { |
| 749 isolate()->StackOverflow(); | 690 isolate()->StackOverflow(); |
| 750 } | 691 } |
| 751 } | 692 } |
| 752 | 693 |
| 753 // Make sure the target stack is empty. | 694 // Make sure the target stack is empty. |
| 754 ASSERT(target_stack_ == NULL); | 695 ASSERT(target_stack_ == NULL); |
| 755 | 696 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 729 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
| 789 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 730 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
| 790 } | 731 } |
| 791 return result; | 732 return result; |
| 792 } | 733 } |
| 793 | 734 |
| 794 | 735 |
| 795 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 736 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
| 796 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 737 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 797 scanner_.Initialize(source); | 738 scanner_.Initialize(source); |
| 798 ASSERT(scope_ == NULL); | 739 ASSERT(top_scope_ == NULL); |
| 799 ASSERT(target_stack_ == NULL); | 740 ASSERT(target_stack_ == NULL); |
| 800 | 741 |
| 801 Handle<String> name(String::cast(shared_info->name())); | 742 Handle<String> name(String::cast(shared_info->name())); |
| 802 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 743 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
| 803 fni_->PushEnclosingName(name); | 744 fni_->PushEnclosingName(name); |
| 804 | 745 |
| 805 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 746 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 806 | 747 |
| 807 // Place holder for the result. | 748 // Place holder for the result. |
| 808 FunctionLiteral* result = NULL; | 749 FunctionLiteral* result = NULL; |
| 809 | 750 |
| 810 { | 751 { |
| 811 // Parse the function literal. | 752 // Parse the function literal. |
| 812 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 753 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 813 info()->SetGlobalScope(scope); | 754 info()->SetGlobalScope(scope); |
| 814 if (!info()->closure().is_null()) { | 755 if (!info()->closure().is_null()) { |
| 815 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 756 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 816 zone()); | 757 zone()); |
| 817 } | 758 } |
| 818 original_scope_ = scope; | 759 original_scope_ = scope; |
| 819 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 760 FunctionState function_state(this, scope); |
| 820 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 761 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
| 821 ASSERT(scope->language_mode() != EXTENDED_MODE || | 762 ASSERT(scope->language_mode() != EXTENDED_MODE || |
| 822 info()->is_extended_mode()); | 763 info()->is_extended_mode()); |
| 823 ASSERT(info()->language_mode() == shared_info->language_mode()); | 764 ASSERT(info()->language_mode() == shared_info->language_mode()); |
| 824 scope->SetLanguageMode(shared_info->language_mode()); | 765 scope->SetLanguageMode(shared_info->language_mode()); |
| 825 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 766 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 826 ? (shared_info->is_anonymous() | 767 ? (shared_info->is_anonymous() |
| 827 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 768 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 828 : FunctionLiteral::NAMED_EXPRESSION) | 769 : FunctionLiteral::NAMED_EXPRESSION) |
| 829 : FunctionLiteral::DECLARATION; | 770 : FunctionLiteral::DECLARATION; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 845 if (result == NULL) { | 786 if (result == NULL) { |
| 846 if (stack_overflow()) isolate()->StackOverflow(); | 787 if (stack_overflow()) isolate()->StackOverflow(); |
| 847 } else { | 788 } else { |
| 848 Handle<String> inferred_name(shared_info->inferred_name()); | 789 Handle<String> inferred_name(shared_info->inferred_name()); |
| 849 result->set_inferred_name(inferred_name); | 790 result->set_inferred_name(inferred_name); |
| 850 } | 791 } |
| 851 return result; | 792 return result; |
| 852 } | 793 } |
| 853 | 794 |
| 854 | 795 |
| 796 Handle<String> Parser::GetSymbol() { |
| 797 int symbol_id = -1; |
| 798 if (pre_parse_data() != NULL) { |
| 799 symbol_id = pre_parse_data()->GetSymbolIdentifier(); |
| 800 } |
| 801 return LookupSymbol(symbol_id); |
| 802 } |
| 803 |
| 804 |
| 805 void Parser::ReportMessage(const char* message, Vector<const char*> args) { |
| 806 Scanner::Location source_location = scanner().location(); |
| 807 ReportMessageAt(source_location, message, args); |
| 808 } |
| 809 |
| 810 |
| 811 void Parser::ReportMessage(const char* message, Vector<Handle<String> > args) { |
| 812 Scanner::Location source_location = scanner().location(); |
| 813 ReportMessageAt(source_location, message, args); |
| 814 } |
| 815 |
| 816 |
| 817 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 818 const char* message, |
| 819 Vector<const char*> args) { |
| 820 MessageLocation location(script_, |
| 821 source_location.beg_pos, |
| 822 source_location.end_pos); |
| 823 Factory* factory = isolate()->factory(); |
| 824 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 825 for (int i = 0; i < args.length(); i++) { |
| 826 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| 827 elements->set(i, *arg_string); |
| 828 } |
| 829 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 830 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 831 isolate()->Throw(*result, &location); |
| 832 } |
| 833 |
| 834 |
| 835 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 836 const char* message, |
| 837 Vector<Handle<String> > args) { |
| 838 MessageLocation location(script_, |
| 839 source_location.beg_pos, |
| 840 source_location.end_pos); |
| 841 Factory* factory = isolate()->factory(); |
| 842 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 843 for (int i = 0; i < args.length(); i++) { |
| 844 elements->set(i, *args[i]); |
| 845 } |
| 846 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 847 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 848 isolate()->Throw(*result, &location); |
| 849 } |
| 850 |
| 851 |
| 855 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 852 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 856 int end_token, | 853 int end_token, |
| 857 bool is_eval, | 854 bool is_eval, |
| 858 bool is_global, | 855 bool is_global, |
| 859 bool* ok) { | 856 bool* ok) { |
| 860 // SourceElements :: | 857 // SourceElements :: |
| 861 // (ModuleElement)* <end_token> | 858 // (ModuleElement)* <end_token> |
| 862 | 859 |
| 863 // Allocate a target stack to use for this set of source | 860 // Allocate a target stack to use for this set of source |
| 864 // elements. This way, all scripts and functions get their own | 861 // elements. This way, all scripts and functions get their own |
| 865 // target stack thus avoiding illegal breaks and continues across | 862 // target stack thus avoiding illegal breaks and continues across |
| 866 // functions. | 863 // functions. |
| 867 TargetScope scope(&this->target_stack_); | 864 TargetScope scope(&this->target_stack_); |
| 868 | 865 |
| 869 ASSERT(processor != NULL); | 866 ASSERT(processor != NULL); |
| 870 bool directive_prologue = true; // Parsing directive prologue. | 867 bool directive_prologue = true; // Parsing directive prologue. |
| 871 | 868 |
| 872 while (peek() != end_token) { | 869 while (peek() != end_token) { |
| 873 if (directive_prologue && peek() != Token::STRING) { | 870 if (directive_prologue && peek() != Token::STRING) { |
| 874 directive_prologue = false; | 871 directive_prologue = false; |
| 875 } | 872 } |
| 876 | 873 |
| 877 Scanner::Location token_loc = scanner()->peek_location(); | 874 Scanner::Location token_loc = scanner().peek_location(); |
| 878 Statement* stat; | 875 Statement* stat; |
| 879 if (is_global && !is_eval) { | 876 if (is_global && !is_eval) { |
| 880 stat = ParseModuleElement(NULL, CHECK_OK); | 877 stat = ParseModuleElement(NULL, CHECK_OK); |
| 881 } else { | 878 } else { |
| 882 stat = ParseBlockElement(NULL, CHECK_OK); | 879 stat = ParseBlockElement(NULL, CHECK_OK); |
| 883 } | 880 } |
| 884 if (stat == NULL || stat->IsEmpty()) { | 881 if (stat == NULL || stat->IsEmpty()) { |
| 885 directive_prologue = false; // End of directive prologue. | 882 directive_prologue = false; // End of directive prologue. |
| 886 continue; | 883 continue; |
| 887 } | 884 } |
| 888 | 885 |
| 889 if (directive_prologue) { | 886 if (directive_prologue) { |
| 890 // A shot at a directive. | 887 // A shot at a directive. |
| 891 ExpressionStatement* e_stat; | 888 ExpressionStatement* e_stat; |
| 892 Literal* literal; | 889 Literal* literal; |
| 893 // Still processing directive prologue? | 890 // Still processing directive prologue? |
| 894 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 891 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 895 (literal = e_stat->expression()->AsLiteral()) != NULL && | 892 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 896 literal->value()->IsString()) { | 893 literal->value()->IsString()) { |
| 897 Handle<String> directive = Handle<String>::cast(literal->value()); | 894 Handle<String> directive = Handle<String>::cast(literal->value()); |
| 898 | 895 |
| 899 // Check "use strict" directive (ES5 14.1). | 896 // Check "use strict" directive (ES5 14.1). |
| 900 if (scope_->is_classic_mode() && | 897 if (top_scope_->is_classic_mode() && |
| 901 directive->Equals(isolate()->heap()->use_strict_string()) && | 898 directive->Equals(isolate()->heap()->use_strict_string()) && |
| 902 token_loc.end_pos - token_loc.beg_pos == | 899 token_loc.end_pos - token_loc.beg_pos == |
| 903 isolate()->heap()->use_strict_string()->length() + 2) { | 900 isolate()->heap()->use_strict_string()->length() + 2) { |
| 904 // TODO(mstarzinger): Global strict eval calls, need their own scope | 901 // TODO(mstarzinger): Global strict eval calls, need their own scope |
| 905 // as specified in ES5 10.4.2(3). The correct fix would be to always | 902 // as specified in ES5 10.4.2(3). The correct fix would be to always |
| 906 // add this scope in DoParseProgram(), but that requires adaptations | 903 // add this scope in DoParseProgram(), but that requires adaptations |
| 907 // all over the code base, so we go with a quick-fix for now. | 904 // all over the code base, so we go with a quick-fix for now. |
| 908 // In the same manner, we have to patch the parsing mode. | 905 // In the same manner, we have to patch the parsing mode. |
| 909 if (is_eval && !scope_->is_eval_scope()) { | 906 if (is_eval && !top_scope_->is_eval_scope()) { |
| 910 ASSERT(scope_->is_global_scope()); | 907 ASSERT(top_scope_->is_global_scope()); |
| 911 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 908 Scope* scope = NewScope(top_scope_, EVAL_SCOPE); |
| 912 scope->set_start_position(scope_->start_position()); | 909 scope->set_start_position(top_scope_->start_position()); |
| 913 scope->set_end_position(scope_->end_position()); | 910 scope->set_end_position(top_scope_->end_position()); |
| 914 scope_ = scope; | 911 top_scope_ = scope; |
| 915 mode_ = PARSE_EAGERLY; | 912 mode_ = PARSE_EAGERLY; |
| 916 } | 913 } |
| 917 // TODO(ES6): Fix entering extended mode, once it is specified. | 914 // TODO(ES6): Fix entering extended mode, once it is specified. |
| 918 scope_->SetLanguageMode(allow_harmony_scoping() | 915 top_scope_->SetLanguageMode(allow_harmony_scoping() |
| 919 ? EXTENDED_MODE : STRICT_MODE); | 916 ? EXTENDED_MODE : STRICT_MODE); |
| 920 // "use strict" is the only directive for now. | 917 // "use strict" is the only directive for now. |
| 921 directive_prologue = false; | 918 directive_prologue = false; |
| 922 } | 919 } |
| 923 } else { | 920 } else { |
| 924 // End of the directive prologue. | 921 // End of the directive prologue. |
| 925 directive_prologue = false; | 922 directive_prologue = false; |
| 926 } | 923 } |
| 927 } | 924 } |
| 928 | 925 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 957 return ParseVariableStatement(kModuleElement, NULL, ok); | 954 return ParseVariableStatement(kModuleElement, NULL, ok); |
| 958 case Token::IMPORT: | 955 case Token::IMPORT: |
| 959 return ParseImportDeclaration(ok); | 956 return ParseImportDeclaration(ok); |
| 960 case Token::EXPORT: | 957 case Token::EXPORT: |
| 961 return ParseExportDeclaration(ok); | 958 return ParseExportDeclaration(ok); |
| 962 default: { | 959 default: { |
| 963 Statement* stmt = ParseStatement(labels, CHECK_OK); | 960 Statement* stmt = ParseStatement(labels, CHECK_OK); |
| 964 // Handle 'module' as a context-sensitive keyword. | 961 // Handle 'module' as a context-sensitive keyword. |
| 965 if (FLAG_harmony_modules && | 962 if (FLAG_harmony_modules && |
| 966 peek() == Token::IDENTIFIER && | 963 peek() == Token::IDENTIFIER && |
| 967 !scanner()->HasAnyLineTerminatorBeforeNext() && | 964 !scanner().HasAnyLineTerminatorBeforeNext() && |
| 968 stmt != NULL) { | 965 stmt != NULL) { |
| 969 ExpressionStatement* estmt = stmt->AsExpressionStatement(); | 966 ExpressionStatement* estmt = stmt->AsExpressionStatement(); |
| 970 if (estmt != NULL && | 967 if (estmt != NULL && |
| 971 estmt->expression()->AsVariableProxy() != NULL && | 968 estmt->expression()->AsVariableProxy() != NULL && |
| 972 estmt->expression()->AsVariableProxy()->name()->Equals( | 969 estmt->expression()->AsVariableProxy()->name()->Equals( |
| 973 isolate()->heap()->module_string()) && | 970 isolate()->heap()->module_string()) && |
| 974 !scanner()->literal_contains_escapes()) { | 971 !scanner().literal_contains_escapes()) { |
| 975 return ParseModuleDeclaration(NULL, ok); | 972 return ParseModuleDeclaration(NULL, ok); |
| 976 } | 973 } |
| 977 } | 974 } |
| 978 return stmt; | 975 return stmt; |
| 979 } | 976 } |
| 980 } | 977 } |
| 981 } | 978 } |
| 982 | 979 |
| 983 | 980 |
| 984 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 981 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 985 // ModuleDeclaration: | 982 // ModuleDeclaration: |
| 986 // 'module' Identifier Module | 983 // 'module' Identifier Module |
| 987 | 984 |
| 988 int pos = peek_position(); | 985 int pos = peek_position(); |
| 989 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 986 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 990 | 987 |
| 991 #ifdef DEBUG | 988 #ifdef DEBUG |
| 992 if (FLAG_print_interface_details) | 989 if (FLAG_print_interface_details) |
| 993 PrintF("# Module %s...\n", name->ToAsciiArray()); | 990 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 994 #endif | 991 #endif |
| 995 | 992 |
| 996 Module* module = ParseModule(CHECK_OK); | 993 Module* module = ParseModule(CHECK_OK); |
| 997 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 994 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 998 Declaration* declaration = | 995 Declaration* declaration = |
| 999 factory()->NewModuleDeclaration(proxy, module, scope_, pos); | 996 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); |
| 1000 Declare(declaration, true, CHECK_OK); | 997 Declare(declaration, true, CHECK_OK); |
| 1001 | 998 |
| 1002 #ifdef DEBUG | 999 #ifdef DEBUG |
| 1003 if (FLAG_print_interface_details) | 1000 if (FLAG_print_interface_details) |
| 1004 PrintF("# Module %s.\n", name->ToAsciiArray()); | 1001 PrintF("# Module %s.\n", name->ToAsciiArray()); |
| 1005 | 1002 |
| 1006 if (FLAG_print_interfaces) { | 1003 if (FLAG_print_interfaces) { |
| 1007 PrintF("module %s : ", name->ToAsciiArray()); | 1004 PrintF("module %s : ", name->ToAsciiArray()); |
| 1008 module->interface()->Print(); | 1005 module->interface()->Print(); |
| 1009 } | 1006 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1047 Module* Parser::ParseModuleLiteral(bool* ok) { | 1044 Module* Parser::ParseModuleLiteral(bool* ok) { |
| 1048 // Module: | 1045 // Module: |
| 1049 // '{' ModuleElement '}' | 1046 // '{' ModuleElement '}' |
| 1050 | 1047 |
| 1051 int pos = peek_position(); | 1048 int pos = peek_position(); |
| 1052 // Construct block expecting 16 statements. | 1049 // Construct block expecting 16 statements. |
| 1053 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1050 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1054 #ifdef DEBUG | 1051 #ifdef DEBUG |
| 1055 if (FLAG_print_interface_details) PrintF("# Literal "); | 1052 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1056 #endif | 1053 #endif |
| 1057 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1054 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1058 | 1055 |
| 1059 Expect(Token::LBRACE, CHECK_OK); | 1056 Expect(Token::LBRACE, CHECK_OK); |
| 1060 scope->set_start_position(scanner()->location().beg_pos); | 1057 scope->set_start_position(scanner().location().beg_pos); |
| 1061 scope->SetLanguageMode(EXTENDED_MODE); | 1058 scope->SetLanguageMode(EXTENDED_MODE); |
| 1062 | 1059 |
| 1063 { | 1060 { |
| 1064 BlockState block_state(&scope_, scope); | 1061 BlockState block_state(this, scope); |
| 1065 TargetCollector collector(zone()); | 1062 TargetCollector collector(zone()); |
| 1066 Target target(&this->target_stack_, &collector); | 1063 Target target(&this->target_stack_, &collector); |
| 1067 Target target_body(&this->target_stack_, body); | 1064 Target target_body(&this->target_stack_, body); |
| 1068 | 1065 |
| 1069 while (peek() != Token::RBRACE) { | 1066 while (peek() != Token::RBRACE) { |
| 1070 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1067 Statement* stat = ParseModuleElement(NULL, CHECK_OK); |
| 1071 if (stat && !stat->IsEmpty()) { | 1068 if (stat && !stat->IsEmpty()) { |
| 1072 body->AddStatement(stat, zone()); | 1069 body->AddStatement(stat, zone()); |
| 1073 } | 1070 } |
| 1074 } | 1071 } |
| 1075 } | 1072 } |
| 1076 | 1073 |
| 1077 Expect(Token::RBRACE, CHECK_OK); | 1074 Expect(Token::RBRACE, CHECK_OK); |
| 1078 scope->set_end_position(scanner()->location().end_pos); | 1075 scope->set_end_position(scanner().location().end_pos); |
| 1079 body->set_scope(scope); | 1076 body->set_scope(scope); |
| 1080 | 1077 |
| 1081 // Check that all exports are bound. | 1078 // Check that all exports are bound. |
| 1082 Interface* interface = scope->interface(); | 1079 Interface* interface = scope->interface(); |
| 1083 for (Interface::Iterator it = interface->iterator(); | 1080 for (Interface::Iterator it = interface->iterator(); |
| 1084 !it.done(); it.Advance()) { | 1081 !it.done(); it.Advance()) { |
| 1085 if (scope->LocalLookup(it.name()) == NULL) { | 1082 if (scope->LocalLookup(it.name()) == NULL) { |
| 1086 Handle<String> name(it.name()); | 1083 Handle<String> name(it.name()); |
| 1087 ParserTraits::ReportMessage("module_export_undefined", | 1084 ReportMessage("module_export_undefined", |
| 1088 Vector<Handle<String> >(&name, 1)); | 1085 Vector<Handle<String> >(&name, 1)); |
| 1089 *ok = false; | 1086 *ok = false; |
| 1090 return NULL; | 1087 return NULL; |
| 1091 } | 1088 } |
| 1092 } | 1089 } |
| 1093 | 1090 |
| 1094 interface->MakeModule(ok); | 1091 interface->MakeModule(ok); |
| 1095 ASSERT(*ok); | 1092 ASSERT(*ok); |
| 1096 interface->Freeze(ok); | 1093 interface->Freeze(ok); |
| 1097 ASSERT(*ok); | 1094 ASSERT(*ok); |
| 1098 return factory()->NewModuleLiteral(body, interface, pos); | 1095 return factory()->NewModuleLiteral(body, interface, pos); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1117 if (!*ok) { | 1114 if (!*ok) { |
| 1118 #ifdef DEBUG | 1115 #ifdef DEBUG |
| 1119 if (FLAG_print_interfaces) { | 1116 if (FLAG_print_interfaces) { |
| 1120 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); | 1117 PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray()); |
| 1121 PrintF("result: "); | 1118 PrintF("result: "); |
| 1122 result->interface()->Print(); | 1119 result->interface()->Print(); |
| 1123 PrintF("member: "); | 1120 PrintF("member: "); |
| 1124 member->interface()->Print(); | 1121 member->interface()->Print(); |
| 1125 } | 1122 } |
| 1126 #endif | 1123 #endif |
| 1127 ParserTraits::ReportMessage("invalid_module_path", | 1124 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1128 Vector<Handle<String> >(&name, 1)); | |
| 1129 return NULL; | 1125 return NULL; |
| 1130 } | 1126 } |
| 1131 result = member; | 1127 result = member; |
| 1132 } | 1128 } |
| 1133 | 1129 |
| 1134 return result; | 1130 return result; |
| 1135 } | 1131 } |
| 1136 | 1132 |
| 1137 | 1133 |
| 1138 Module* Parser::ParseModuleVariable(bool* ok) { | 1134 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1139 // ModulePath: | 1135 // ModulePath: |
| 1140 // Identifier | 1136 // Identifier |
| 1141 | 1137 |
| 1142 int pos = peek_position(); | 1138 int pos = peek_position(); |
| 1143 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 1139 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1144 #ifdef DEBUG | 1140 #ifdef DEBUG |
| 1145 if (FLAG_print_interface_details) | 1141 if (FLAG_print_interface_details) |
| 1146 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1142 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1147 #endif | 1143 #endif |
| 1148 VariableProxy* proxy = scope_->NewUnresolved( | 1144 VariableProxy* proxy = top_scope_->NewUnresolved( |
| 1149 factory(), name, Interface::NewModule(zone()), | 1145 factory(), name, Interface::NewModule(zone()), |
| 1150 scanner()->location().beg_pos); | 1146 scanner().location().beg_pos); |
| 1151 | 1147 |
| 1152 return factory()->NewModuleVariable(proxy, pos); | 1148 return factory()->NewModuleVariable(proxy, pos); |
| 1153 } | 1149 } |
| 1154 | 1150 |
| 1155 | 1151 |
| 1156 Module* Parser::ParseModuleUrl(bool* ok) { | 1152 Module* Parser::ParseModuleUrl(bool* ok) { |
| 1157 // Module: | 1153 // Module: |
| 1158 // String | 1154 // String |
| 1159 | 1155 |
| 1160 int pos = peek_position(); | 1156 int pos = peek_position(); |
| 1161 Expect(Token::STRING, CHECK_OK); | 1157 Expect(Token::STRING, CHECK_OK); |
| 1162 Handle<String> symbol = GetSymbol(); | 1158 Handle<String> symbol = GetSymbol(); |
| 1163 | 1159 |
| 1164 // TODO(ES6): Request JS resource from environment... | 1160 // TODO(ES6): Request JS resource from environment... |
| 1165 | 1161 |
| 1166 #ifdef DEBUG | 1162 #ifdef DEBUG |
| 1167 if (FLAG_print_interface_details) PrintF("# Url "); | 1163 if (FLAG_print_interface_details) PrintF("# Url "); |
| 1168 #endif | 1164 #endif |
| 1169 | 1165 |
| 1170 // Create an empty literal as long as the feature isn't finished. | 1166 // Create an empty literal as long as the feature isn't finished. |
| 1171 USE(symbol); | 1167 USE(symbol); |
| 1172 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1168 Scope* scope = NewScope(top_scope_, MODULE_SCOPE); |
| 1173 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 1169 Block* body = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 1174 body->set_scope(scope); | 1170 body->set_scope(scope); |
| 1175 Interface* interface = scope->interface(); | 1171 Interface* interface = scope->interface(); |
| 1176 Module* result = factory()->NewModuleLiteral(body, interface, pos); | 1172 Module* result = factory()->NewModuleLiteral(body, interface, pos); |
| 1177 interface->Freeze(ok); | 1173 interface->Freeze(ok); |
| 1178 ASSERT(*ok); | 1174 ASSERT(*ok); |
| 1179 interface->Unify(scope->interface(), zone(), ok); | 1175 interface->Unify(scope->interface(), zone(), ok); |
| 1180 ASSERT(*ok); | 1176 ASSERT(*ok); |
| 1181 return result; | 1177 return result; |
| 1182 } | 1178 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 Interface* interface = Interface::NewUnknown(zone()); | 1224 Interface* interface = Interface::NewUnknown(zone()); |
| 1229 module->interface()->Add(names[i], interface, zone(), ok); | 1225 module->interface()->Add(names[i], interface, zone(), ok); |
| 1230 if (!*ok) { | 1226 if (!*ok) { |
| 1231 #ifdef DEBUG | 1227 #ifdef DEBUG |
| 1232 if (FLAG_print_interfaces) { | 1228 if (FLAG_print_interfaces) { |
| 1233 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); | 1229 PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray()); |
| 1234 PrintF("module: "); | 1230 PrintF("module: "); |
| 1235 module->interface()->Print(); | 1231 module->interface()->Print(); |
| 1236 } | 1232 } |
| 1237 #endif | 1233 #endif |
| 1238 ParserTraits::ReportMessage("invalid_module_path", | 1234 ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1)); |
| 1239 Vector<Handle<String> >(&name, 1)); | |
| 1240 return NULL; | 1235 return NULL; |
| 1241 } | 1236 } |
| 1242 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); | 1237 VariableProxy* proxy = NewUnresolved(names[i], LET, interface); |
| 1243 Declaration* declaration = | 1238 Declaration* declaration = |
| 1244 factory()->NewImportDeclaration(proxy, module, scope_, pos); | 1239 factory()->NewImportDeclaration(proxy, module, top_scope_, pos); |
| 1245 Declare(declaration, true, CHECK_OK); | 1240 Declare(declaration, true, CHECK_OK); |
| 1246 } | 1241 } |
| 1247 | 1242 |
| 1248 return block; | 1243 return block; |
| 1249 } | 1244 } |
| 1250 | 1245 |
| 1251 | 1246 |
| 1252 Statement* Parser::ParseExportDeclaration(bool* ok) { | 1247 Statement* Parser::ParseExportDeclaration(bool* ok) { |
| 1253 // ExportDeclaration: | 1248 // ExportDeclaration: |
| 1254 // 'export' Identifier (',' Identifier)* ';' | 1249 // 'export' Identifier (',' Identifier)* ';' |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 break; | 1284 break; |
| 1290 | 1285 |
| 1291 case Token::VAR: | 1286 case Token::VAR: |
| 1292 case Token::LET: | 1287 case Token::LET: |
| 1293 case Token::CONST: | 1288 case Token::CONST: |
| 1294 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); | 1289 result = ParseVariableStatement(kModuleElement, &names, CHECK_OK); |
| 1295 break; | 1290 break; |
| 1296 | 1291 |
| 1297 default: | 1292 default: |
| 1298 *ok = false; | 1293 *ok = false; |
| 1299 ReportUnexpectedToken(scanner()->current_token()); | 1294 ReportUnexpectedToken(scanner().current_token()); |
| 1300 return NULL; | 1295 return NULL; |
| 1301 } | 1296 } |
| 1302 | 1297 |
| 1303 // Extract declared names into export declarations and interface. | 1298 // Extract declared names into export declarations and interface. |
| 1304 Interface* interface = scope_->interface(); | 1299 Interface* interface = top_scope_->interface(); |
| 1305 for (int i = 0; i < names.length(); ++i) { | 1300 for (int i = 0; i < names.length(); ++i) { |
| 1306 #ifdef DEBUG | 1301 #ifdef DEBUG |
| 1307 if (FLAG_print_interface_details) | 1302 if (FLAG_print_interface_details) |
| 1308 PrintF("# Export %s ", names[i]->ToAsciiArray()); | 1303 PrintF("# Export %s ", names[i]->ToAsciiArray()); |
| 1309 #endif | 1304 #endif |
| 1310 Interface* inner = Interface::NewUnknown(zone()); | 1305 Interface* inner = Interface::NewUnknown(zone()); |
| 1311 interface->Add(names[i], inner, zone(), CHECK_OK); | 1306 interface->Add(names[i], inner, zone(), CHECK_OK); |
| 1312 if (!*ok) | 1307 if (!*ok) |
| 1313 return NULL; | 1308 return NULL; |
| 1314 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); | 1309 VariableProxy* proxy = NewUnresolved(names[i], LET, inner); |
| 1315 USE(proxy); | 1310 USE(proxy); |
| 1316 // TODO(rossberg): Rethink whether we actually need to store export | 1311 // TODO(rossberg): Rethink whether we actually need to store export |
| 1317 // declarations (for compilation?). | 1312 // declarations (for compilation?). |
| 1318 // ExportDeclaration* declaration = | 1313 // ExportDeclaration* declaration = |
| 1319 // factory()->NewExportDeclaration(proxy, scope_, position); | 1314 // factory()->NewExportDeclaration(proxy, top_scope_, position); |
| 1320 // scope_->AddDeclaration(declaration); | 1315 // top_scope_->AddDeclaration(declaration); |
| 1321 } | 1316 } |
| 1322 | 1317 |
| 1323 ASSERT(result != NULL); | 1318 ASSERT(result != NULL); |
| 1324 return result; | 1319 return result; |
| 1325 } | 1320 } |
| 1326 | 1321 |
| 1327 | 1322 |
| 1328 Statement* Parser::ParseBlockElement(ZoneStringList* labels, | 1323 Statement* Parser::ParseBlockElement(ZoneStringList* labels, |
| 1329 bool* ok) { | 1324 bool* ok) { |
| 1330 // (Ecma 262 5th Edition, clause 14): | 1325 // (Ecma 262 5th Edition, clause 14): |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 // (Ecma 262 5th Edition, clause 14): | 1431 // (Ecma 262 5th Edition, clause 14): |
| 1437 // SourceElement: | 1432 // SourceElement: |
| 1438 // Statement | 1433 // Statement |
| 1439 // FunctionDeclaration | 1434 // FunctionDeclaration |
| 1440 // Common language extension is to allow function declaration in place | 1435 // Common language extension is to allow function declaration in place |
| 1441 // of any statement. This language extension is disabled in strict mode. | 1436 // of any statement. This language extension is disabled in strict mode. |
| 1442 // | 1437 // |
| 1443 // In Harmony mode, this case also handles the extension: | 1438 // In Harmony mode, this case also handles the extension: |
| 1444 // Statement: | 1439 // Statement: |
| 1445 // GeneratorDeclaration | 1440 // GeneratorDeclaration |
| 1446 if (!scope_->is_classic_mode()) { | 1441 if (!top_scope_->is_classic_mode()) { |
| 1447 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1442 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1443 Vector<const char*>::empty()); |
| 1448 *ok = false; | 1444 *ok = false; |
| 1449 return NULL; | 1445 return NULL; |
| 1450 } | 1446 } |
| 1451 return ParseFunctionDeclaration(NULL, ok); | 1447 return ParseFunctionDeclaration(NULL, ok); |
| 1452 } | 1448 } |
| 1453 | 1449 |
| 1454 case Token::DEBUGGER: | 1450 case Token::DEBUGGER: |
| 1455 return ParseDebuggerStatement(ok); | 1451 return ParseDebuggerStatement(ok); |
| 1456 | 1452 |
| 1457 default: | 1453 default: |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 if (!ok) { | 1612 if (!ok) { |
| 1617 #ifdef DEBUG | 1613 #ifdef DEBUG |
| 1618 if (FLAG_print_interfaces) { | 1614 if (FLAG_print_interfaces) { |
| 1619 PrintF("DECLARE TYPE ERROR\n"); | 1615 PrintF("DECLARE TYPE ERROR\n"); |
| 1620 PrintF("proxy: "); | 1616 PrintF("proxy: "); |
| 1621 proxy->interface()->Print(); | 1617 proxy->interface()->Print(); |
| 1622 PrintF("var: "); | 1618 PrintF("var: "); |
| 1623 var->interface()->Print(); | 1619 var->interface()->Print(); |
| 1624 } | 1620 } |
| 1625 #endif | 1621 #endif |
| 1626 ParserTraits::ReportMessage("module_type_error", | 1622 ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1)); |
| 1627 Vector<Handle<String> >(&name, 1)); | |
| 1628 } | 1623 } |
| 1629 } | 1624 } |
| 1630 } | 1625 } |
| 1631 } | 1626 } |
| 1632 | 1627 |
| 1633 | 1628 |
| 1634 // Language extension which is only enabled for source files loaded | 1629 // Language extension which is only enabled for source files loaded |
| 1635 // through the API's extension mechanism. A native function | 1630 // through the API's extension mechanism. A native function |
| 1636 // declaration is resolved by looking up the function through a | 1631 // declaration is resolved by looking up the function through a |
| 1637 // callback provided by the extension. | 1632 // callback provided by the extension. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1656 // isn't lazily compiled. The extension structures are only | 1651 // isn't lazily compiled. The extension structures are only |
| 1657 // accessible while parsing the first time not when reparsing | 1652 // accessible while parsing the first time not when reparsing |
| 1658 // because of lazy compilation. | 1653 // because of lazy compilation. |
| 1659 DeclarationScope(VAR)->ForceEagerCompilation(); | 1654 DeclarationScope(VAR)->ForceEagerCompilation(); |
| 1660 | 1655 |
| 1661 // TODO(1240846): It's weird that native function declarations are | 1656 // TODO(1240846): It's weird that native function declarations are |
| 1662 // introduced dynamically when we meet their declarations, whereas | 1657 // introduced dynamically when we meet their declarations, whereas |
| 1663 // other functions are set up when entering the surrounding scope. | 1658 // other functions are set up when entering the surrounding scope. |
| 1664 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); | 1659 VariableProxy* proxy = NewUnresolved(name, VAR, Interface::NewValue()); |
| 1665 Declaration* declaration = | 1660 Declaration* declaration = |
| 1666 factory()->NewVariableDeclaration(proxy, VAR, scope_, pos); | 1661 factory()->NewVariableDeclaration(proxy, VAR, top_scope_, pos); |
| 1667 Declare(declaration, true, CHECK_OK); | 1662 Declare(declaration, true, CHECK_OK); |
| 1668 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( | 1663 NativeFunctionLiteral* lit = factory()->NewNativeFunctionLiteral( |
| 1669 name, extension_, RelocInfo::kNoPosition); | 1664 name, extension_, RelocInfo::kNoPosition); |
| 1670 return factory()->NewExpressionStatement( | 1665 return factory()->NewExpressionStatement( |
| 1671 factory()->NewAssignment( | 1666 factory()->NewAssignment( |
| 1672 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), | 1667 Token::INIT_VAR, proxy, lit, RelocInfo::kNoPosition), |
| 1673 pos); | 1668 pos); |
| 1674 } | 1669 } |
| 1675 | 1670 |
| 1676 | 1671 |
| 1677 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { | 1672 Statement* Parser::ParseFunctionDeclaration(ZoneStringList* names, bool* ok) { |
| 1678 // FunctionDeclaration :: | 1673 // FunctionDeclaration :: |
| 1679 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' | 1674 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' |
| 1680 // GeneratorDeclaration :: | 1675 // GeneratorDeclaration :: |
| 1681 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1676 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1682 // '{' FunctionBody '}' | 1677 // '{' FunctionBody '}' |
| 1683 Expect(Token::FUNCTION, CHECK_OK); | 1678 Expect(Token::FUNCTION, CHECK_OK); |
| 1684 int pos = position(); | 1679 int pos = position(); |
| 1685 bool is_generator = allow_generators() && Check(Token::MUL); | 1680 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1686 bool is_strict_reserved = false; | 1681 bool is_strict_reserved = false; |
| 1687 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1682 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1688 &is_strict_reserved, CHECK_OK); | 1683 &is_strict_reserved, CHECK_OK); |
| 1689 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1684 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1690 scanner()->location(), | 1685 scanner().location(), |
| 1691 is_strict_reserved, | 1686 is_strict_reserved, |
| 1692 is_generator, | 1687 is_generator, |
| 1693 pos, | 1688 pos, |
| 1694 FunctionLiteral::DECLARATION, | 1689 FunctionLiteral::DECLARATION, |
| 1695 CHECK_OK); | 1690 CHECK_OK); |
| 1696 // Even if we're not at the top-level of the global or a function | 1691 // Even if we're not at the top-level of the global or a function |
| 1697 // scope, we treat it as such and introduce the function with its | 1692 // scope, we treat it as such and introduce the function with its |
| 1698 // initial value upon entering the corresponding scope. | 1693 // initial value upon entering the corresponding scope. |
| 1699 // In extended mode, a function behaves as a lexical binding, except in the | 1694 // In extended mode, a function behaves as a lexical binding, except in the |
| 1700 // global scope. | 1695 // global scope. |
| 1701 VariableMode mode = | 1696 VariableMode mode = |
| 1702 is_extended_mode() && !scope_->is_global_scope() ? LET : VAR; | 1697 is_extended_mode() && !top_scope_->is_global_scope() ? LET : VAR; |
| 1703 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1698 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1704 Declaration* declaration = | 1699 Declaration* declaration = |
| 1705 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1700 factory()->NewFunctionDeclaration(proxy, mode, fun, top_scope_, pos); |
| 1706 Declare(declaration, true, CHECK_OK); | 1701 Declare(declaration, true, CHECK_OK); |
| 1707 if (names) names->Add(name, zone()); | 1702 if (names) names->Add(name, zone()); |
| 1708 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1703 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1709 } | 1704 } |
| 1710 | 1705 |
| 1711 | 1706 |
| 1712 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1707 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1713 if (scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1708 if (top_scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); |
| 1714 | 1709 |
| 1715 // Block :: | 1710 // Block :: |
| 1716 // '{' Statement* '}' | 1711 // '{' Statement* '}' |
| 1717 | 1712 |
| 1718 // Note that a Block does not introduce a new execution scope! | 1713 // Note that a Block does not introduce a new execution scope! |
| 1719 // (ECMA-262, 3rd, 12.2) | 1714 // (ECMA-262, 3rd, 12.2) |
| 1720 // | 1715 // |
| 1721 // Construct block expecting 16 statements. | 1716 // Construct block expecting 16 statements. |
| 1722 Block* result = | 1717 Block* result = |
| 1723 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1718 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1736 | 1731 |
| 1737 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1732 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1738 // The harmony mode uses block elements instead of statements. | 1733 // The harmony mode uses block elements instead of statements. |
| 1739 // | 1734 // |
| 1740 // Block :: | 1735 // Block :: |
| 1741 // '{' BlockElement* '}' | 1736 // '{' BlockElement* '}' |
| 1742 | 1737 |
| 1743 // Construct block expecting 16 statements. | 1738 // Construct block expecting 16 statements. |
| 1744 Block* body = | 1739 Block* body = |
| 1745 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1740 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| 1746 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); | 1741 Scope* block_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 1747 | 1742 |
| 1748 // Parse the statements and collect escaping labels. | 1743 // Parse the statements and collect escaping labels. |
| 1749 Expect(Token::LBRACE, CHECK_OK); | 1744 Expect(Token::LBRACE, CHECK_OK); |
| 1750 block_scope->set_start_position(scanner()->location().beg_pos); | 1745 block_scope->set_start_position(scanner().location().beg_pos); |
| 1751 { BlockState block_state(&scope_, block_scope); | 1746 { BlockState block_state(this, block_scope); |
| 1752 TargetCollector collector(zone()); | 1747 TargetCollector collector(zone()); |
| 1753 Target target(&this->target_stack_, &collector); | 1748 Target target(&this->target_stack_, &collector); |
| 1754 Target target_body(&this->target_stack_, body); | 1749 Target target_body(&this->target_stack_, body); |
| 1755 | 1750 |
| 1756 while (peek() != Token::RBRACE) { | 1751 while (peek() != Token::RBRACE) { |
| 1757 Statement* stat = ParseBlockElement(NULL, CHECK_OK); | 1752 Statement* stat = ParseBlockElement(NULL, CHECK_OK); |
| 1758 if (stat && !stat->IsEmpty()) { | 1753 if (stat && !stat->IsEmpty()) { |
| 1759 body->AddStatement(stat, zone()); | 1754 body->AddStatement(stat, zone()); |
| 1760 } | 1755 } |
| 1761 } | 1756 } |
| 1762 } | 1757 } |
| 1763 Expect(Token::RBRACE, CHECK_OK); | 1758 Expect(Token::RBRACE, CHECK_OK); |
| 1764 block_scope->set_end_position(scanner()->location().end_pos); | 1759 block_scope->set_end_position(scanner().location().end_pos); |
| 1765 block_scope = block_scope->FinalizeBlockScope(); | 1760 block_scope = block_scope->FinalizeBlockScope(); |
| 1766 body->set_scope(block_scope); | 1761 body->set_scope(block_scope); |
| 1767 return body; | 1762 return body; |
| 1768 } | 1763 } |
| 1769 | 1764 |
| 1770 | 1765 |
| 1771 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, | 1766 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, |
| 1772 ZoneStringList* names, | 1767 ZoneStringList* names, |
| 1773 bool* ok) { | 1768 bool* ok) { |
| 1774 // VariableStatement :: | 1769 // VariableStatement :: |
| 1775 // VariableDeclarations ';' | 1770 // VariableDeclarations ';' |
| 1776 | 1771 |
| 1777 Handle<String> ignore; | 1772 Handle<String> ignore; |
| 1778 Block* result = | 1773 Block* result = |
| 1779 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); | 1774 ParseVariableDeclarations(var_context, NULL, names, &ignore, CHECK_OK); |
| 1780 ExpectSemicolon(CHECK_OK); | 1775 ExpectSemicolon(CHECK_OK); |
| 1781 return result; | 1776 return result; |
| 1782 } | 1777 } |
| 1783 | 1778 |
| 1784 | 1779 |
| 1780 bool Parser::IsEvalOrArguments(Handle<String> string) { |
| 1781 return string.is_identical_to(isolate()->factory()->eval_string()) || |
| 1782 string.is_identical_to(isolate()->factory()->arguments_string()); |
| 1783 } |
| 1784 |
| 1785 |
| 1785 // If the variable declaration declares exactly one non-const | 1786 // If the variable declaration declares exactly one non-const |
| 1786 // variable, then *out is set to that variable. In all other cases, | 1787 // variable, then *out is set to that variable. In all other cases, |
| 1787 // *out is untouched; in particular, it is the caller's responsibility | 1788 // *out is untouched; in particular, it is the caller's responsibility |
| 1788 // to initialize it properly. This mechanism is used for the parsing | 1789 // to initialize it properly. This mechanism is used for the parsing |
| 1789 // of 'for-in' loops. | 1790 // of 'for-in' loops. |
| 1790 Block* Parser::ParseVariableDeclarations( | 1791 Block* Parser::ParseVariableDeclarations( |
| 1791 VariableDeclarationContext var_context, | 1792 VariableDeclarationContext var_context, |
| 1792 VariableDeclarationProperties* decl_props, | 1793 VariableDeclarationProperties* decl_props, |
| 1793 ZoneStringList* names, | 1794 ZoneStringList* names, |
| 1794 Handle<String>* out, | 1795 Handle<String>* out, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1823 // | 1824 // |
| 1824 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 1825 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 1825 // | 1826 // |
| 1826 // * It is a Syntax Error if the code that matches this production is not | 1827 // * It is a Syntax Error if the code that matches this production is not |
| 1827 // contained in extended code. | 1828 // contained in extended code. |
| 1828 // | 1829 // |
| 1829 // However disallowing const in classic mode will break compatibility with | 1830 // However disallowing const in classic mode will break compatibility with |
| 1830 // existing pages. Therefore we keep allowing const with the old | 1831 // existing pages. Therefore we keep allowing const with the old |
| 1831 // non-harmony semantics in classic mode. | 1832 // non-harmony semantics in classic mode. |
| 1832 Consume(Token::CONST); | 1833 Consume(Token::CONST); |
| 1833 switch (scope_->language_mode()) { | 1834 switch (top_scope_->language_mode()) { |
| 1834 case CLASSIC_MODE: | 1835 case CLASSIC_MODE: |
| 1835 mode = CONST; | 1836 mode = CONST; |
| 1836 init_op = Token::INIT_CONST; | 1837 init_op = Token::INIT_CONST; |
| 1837 break; | 1838 break; |
| 1838 case STRICT_MODE: | 1839 case STRICT_MODE: |
| 1839 ReportMessage("strict_const", Vector<const char*>::empty()); | 1840 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1840 *ok = false; | 1841 *ok = false; |
| 1841 return NULL; | 1842 return NULL; |
| 1842 case EXTENDED_MODE: | 1843 case EXTENDED_MODE: |
| 1843 if (var_context == kStatement) { | 1844 if (var_context == kStatement) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1916 // If we have a const declaration, in an inner scope, the proxy is always | 1917 // If we have a const declaration, in an inner scope, the proxy is always |
| 1917 // bound to the declared variable (independent of possibly surrounding with | 1918 // bound to the declared variable (independent of possibly surrounding with |
| 1918 // statements). | 1919 // statements). |
| 1919 // For let/const declarations in harmony mode, we can also immediately | 1920 // For let/const declarations in harmony mode, we can also immediately |
| 1920 // pre-resolve the proxy because it resides in the same scope as the | 1921 // pre-resolve the proxy because it resides in the same scope as the |
| 1921 // declaration. | 1922 // declaration. |
| 1922 Interface* interface = | 1923 Interface* interface = |
| 1923 is_const ? Interface::NewConst() : Interface::NewValue(); | 1924 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 1924 VariableProxy* proxy = NewUnresolved(name, mode, interface); | 1925 VariableProxy* proxy = NewUnresolved(name, mode, interface); |
| 1925 Declaration* declaration = | 1926 Declaration* declaration = |
| 1926 factory()->NewVariableDeclaration(proxy, mode, scope_, pos); | 1927 factory()->NewVariableDeclaration(proxy, mode, top_scope_, pos); |
| 1927 Declare(declaration, mode != VAR, CHECK_OK); | 1928 Declare(declaration, mode != VAR, CHECK_OK); |
| 1928 nvars++; | 1929 nvars++; |
| 1929 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { | 1930 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) { |
| 1930 ReportMessageAt(scanner()->location(), "too_many_variables"); | 1931 ReportMessageAt(scanner().location(), "too_many_variables", |
| 1932 Vector<const char*>::empty()); |
| 1931 *ok = false; | 1933 *ok = false; |
| 1932 return NULL; | 1934 return NULL; |
| 1933 } | 1935 } |
| 1934 if (names) names->Add(name, zone()); | 1936 if (names) names->Add(name, zone()); |
| 1935 | 1937 |
| 1936 // Parse initialization expression if present and/or needed. A | 1938 // Parse initialization expression if present and/or needed. A |
| 1937 // declaration of the form: | 1939 // declaration of the form: |
| 1938 // | 1940 // |
| 1939 // var v = x; | 1941 // var v = x; |
| 1940 // | 1942 // |
| 1941 // is syntactic sugar for: | 1943 // is syntactic sugar for: |
| 1942 // | 1944 // |
| 1943 // var v; v = x; | 1945 // var v; v = x; |
| 1944 // | 1946 // |
| 1945 // In particular, we need to re-lookup 'v' (in scope_, not | 1947 // In particular, we need to re-lookup 'v' (in top_scope_, not |
| 1946 // declaration_scope) as it may be a different 'v' than the 'v' in the | 1948 // declaration_scope) as it may be a different 'v' than the 'v' in the |
| 1947 // declaration (e.g., if we are inside a 'with' statement or 'catch' | 1949 // declaration (e.g., if we are inside a 'with' statement or 'catch' |
| 1948 // block). | 1950 // block). |
| 1949 // | 1951 // |
| 1950 // However, note that const declarations are different! A const | 1952 // However, note that const declarations are different! A const |
| 1951 // declaration of the form: | 1953 // declaration of the form: |
| 1952 // | 1954 // |
| 1953 // const c = x; | 1955 // const c = x; |
| 1954 // | 1956 // |
| 1955 // is *not* syntactic sugar for: | 1957 // is *not* syntactic sugar for: |
| 1956 // | 1958 // |
| 1957 // const c; c = x; | 1959 // const c; c = x; |
| 1958 // | 1960 // |
| 1959 // The "variable" c initialized to x is the same as the declared | 1961 // The "variable" c initialized to x is the same as the declared |
| 1960 // one - there is no re-lookup (see the last parameter of the | 1962 // one - there is no re-lookup (see the last parameter of the |
| 1961 // Declare() call above). | 1963 // Declare() call above). |
| 1962 | 1964 |
| 1963 Scope* initialization_scope = is_const ? declaration_scope : scope_; | 1965 Scope* initialization_scope = is_const ? declaration_scope : top_scope_; |
| 1964 Expression* value = NULL; | 1966 Expression* value = NULL; |
| 1965 int pos = -1; | 1967 int pos = -1; |
| 1966 // Harmony consts have non-optional initializers. | 1968 // Harmony consts have non-optional initializers. |
| 1967 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 1969 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { |
| 1968 Expect(Token::ASSIGN, CHECK_OK); | 1970 Expect(Token::ASSIGN, CHECK_OK); |
| 1969 pos = position(); | 1971 pos = position(); |
| 1970 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 1972 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1971 // Don't infer if it is "a = function(){...}();"-like expression. | 1973 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1972 if (fni_ != NULL && | 1974 if (fni_ != NULL && |
| 1973 value->AsCall() == NULL && | 1975 value->AsCall() == NULL && |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 *ok = false; | 2146 *ok = false; |
| 2145 return NULL; | 2147 return NULL; |
| 2146 } | 2148 } |
| 2147 if (labels == NULL) { | 2149 if (labels == NULL) { |
| 2148 labels = new(zone()) ZoneStringList(4, zone()); | 2150 labels = new(zone()) ZoneStringList(4, zone()); |
| 2149 } | 2151 } |
| 2150 labels->Add(label, zone()); | 2152 labels->Add(label, zone()); |
| 2151 // Remove the "ghost" variable that turned out to be a label | 2153 // Remove the "ghost" variable that turned out to be a label |
| 2152 // from the top scope. This way, we don't try to resolve it | 2154 // from the top scope. This way, we don't try to resolve it |
| 2153 // during the scope processing. | 2155 // during the scope processing. |
| 2154 scope_->RemoveUnresolved(var); | 2156 top_scope_->RemoveUnresolved(var); |
| 2155 Expect(Token::COLON, CHECK_OK); | 2157 Expect(Token::COLON, CHECK_OK); |
| 2156 return ParseStatement(labels, ok); | 2158 return ParseStatement(labels, ok); |
| 2157 } | 2159 } |
| 2158 | 2160 |
| 2159 // If we have an extension, we allow a native function declaration. | 2161 // If we have an extension, we allow a native function declaration. |
| 2160 // A native function declaration starts with "native function" with | 2162 // A native function declaration starts with "native function" with |
| 2161 // no line-terminator between the two words. | 2163 // no line-terminator between the two words. |
| 2162 if (extension_ != NULL && | 2164 if (extension_ != NULL && |
| 2163 peek() == Token::FUNCTION && | 2165 peek() == Token::FUNCTION && |
| 2164 !scanner()->HasAnyLineTerminatorBeforeNext() && | 2166 !scanner().HasAnyLineTerminatorBeforeNext() && |
| 2165 expr != NULL && | 2167 expr != NULL && |
| 2166 expr->AsVariableProxy() != NULL && | 2168 expr->AsVariableProxy() != NULL && |
| 2167 expr->AsVariableProxy()->name()->Equals( | 2169 expr->AsVariableProxy()->name()->Equals( |
| 2168 isolate()->heap()->native_string()) && | 2170 isolate()->heap()->native_string()) && |
| 2169 !scanner()->literal_contains_escapes()) { | 2171 !scanner().literal_contains_escapes()) { |
| 2170 return ParseNativeDeclaration(ok); | 2172 return ParseNativeDeclaration(ok); |
| 2171 } | 2173 } |
| 2172 | 2174 |
| 2173 // Parsed expression statement, or the context-sensitive 'module' keyword. | 2175 // Parsed expression statement, or the context-sensitive 'module' keyword. |
| 2174 // Only expect semicolon in the former case. | 2176 // Only expect semicolon in the former case. |
| 2175 if (!FLAG_harmony_modules || | 2177 if (!FLAG_harmony_modules || |
| 2176 peek() != Token::IDENTIFIER || | 2178 peek() != Token::IDENTIFIER || |
| 2177 scanner()->HasAnyLineTerminatorBeforeNext() || | 2179 scanner().HasAnyLineTerminatorBeforeNext() || |
| 2178 expr->AsVariableProxy() == NULL || | 2180 expr->AsVariableProxy() == NULL || |
| 2179 !expr->AsVariableProxy()->name()->Equals( | 2181 !expr->AsVariableProxy()->name()->Equals( |
| 2180 isolate()->heap()->module_string()) || | 2182 isolate()->heap()->module_string()) || |
| 2181 scanner()->literal_contains_escapes()) { | 2183 scanner().literal_contains_escapes()) { |
| 2182 ExpectSemicolon(CHECK_OK); | 2184 ExpectSemicolon(CHECK_OK); |
| 2183 } | 2185 } |
| 2184 return factory()->NewExpressionStatement(expr, pos); | 2186 return factory()->NewExpressionStatement(expr, pos); |
| 2185 } | 2187 } |
| 2186 | 2188 |
| 2187 | 2189 |
| 2188 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { | 2190 IfStatement* Parser::ParseIfStatement(ZoneStringList* labels, bool* ok) { |
| 2189 // IfStatement :: | 2191 // IfStatement :: |
| 2190 // 'if' '(' Expression ')' Statement ('else' Statement)? | 2192 // 'if' '(' Expression ')' Statement ('else' Statement)? |
| 2191 | 2193 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2208 | 2210 |
| 2209 | 2211 |
| 2210 Statement* Parser::ParseContinueStatement(bool* ok) { | 2212 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2211 // ContinueStatement :: | 2213 // ContinueStatement :: |
| 2212 // 'continue' Identifier? ';' | 2214 // 'continue' Identifier? ';' |
| 2213 | 2215 |
| 2214 int pos = peek_position(); | 2216 int pos = peek_position(); |
| 2215 Expect(Token::CONTINUE, CHECK_OK); | 2217 Expect(Token::CONTINUE, CHECK_OK); |
| 2216 Handle<String> label = Handle<String>::null(); | 2218 Handle<String> label = Handle<String>::null(); |
| 2217 Token::Value tok = peek(); | 2219 Token::Value tok = peek(); |
| 2218 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2220 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2219 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2221 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2220 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2222 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2221 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2223 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2222 } | 2224 } |
| 2223 IterationStatement* target = NULL; | 2225 IterationStatement* target = NULL; |
| 2224 target = LookupContinueTarget(label, CHECK_OK); | 2226 target = LookupContinueTarget(label, CHECK_OK); |
| 2225 if (target == NULL) { | 2227 if (target == NULL) { |
| 2226 // Illegal continue statement. | 2228 // Illegal continue statement. |
| 2227 const char* message = "illegal_continue"; | 2229 const char* message = "illegal_continue"; |
| 2228 Vector<Handle<String> > args; | 2230 Vector<Handle<String> > args; |
| 2229 if (!label.is_null()) { | 2231 if (!label.is_null()) { |
| 2230 message = "unknown_label"; | 2232 message = "unknown_label"; |
| 2231 args = Vector<Handle<String> >(&label, 1); | 2233 args = Vector<Handle<String> >(&label, 1); |
| 2232 } | 2234 } |
| 2233 ParserTraits::ReportMessageAt(scanner()->location(), message, args); | 2235 ReportMessageAt(scanner().location(), message, args); |
| 2234 *ok = false; | 2236 *ok = false; |
| 2235 return NULL; | 2237 return NULL; |
| 2236 } | 2238 } |
| 2237 ExpectSemicolon(CHECK_OK); | 2239 ExpectSemicolon(CHECK_OK); |
| 2238 return factory()->NewContinueStatement(target, pos); | 2240 return factory()->NewContinueStatement(target, pos); |
| 2239 } | 2241 } |
| 2240 | 2242 |
| 2241 | 2243 |
| 2242 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2243 // BreakStatement :: | 2245 // BreakStatement :: |
| 2244 // 'break' Identifier? ';' | 2246 // 'break' Identifier? ';' |
| 2245 | 2247 |
| 2246 int pos = peek_position(); | 2248 int pos = peek_position(); |
| 2247 Expect(Token::BREAK, CHECK_OK); | 2249 Expect(Token::BREAK, CHECK_OK); |
| 2248 Handle<String> label; | 2250 Handle<String> label; |
| 2249 Token::Value tok = peek(); | 2251 Token::Value tok = peek(); |
| 2250 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 2252 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2251 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2253 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2252 // ECMA allows "eval" or "arguments" as labels even in strict mode. | 2254 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2253 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 2255 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2254 } | 2256 } |
| 2255 // Parse labeled break statements that target themselves into | 2257 // Parse labeled break statements that target themselves into |
| 2256 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2258 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2257 if (!label.is_null() && ContainsLabel(labels, label)) { | 2259 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2258 ExpectSemicolon(CHECK_OK); | 2260 ExpectSemicolon(CHECK_OK); |
| 2259 return factory()->NewEmptyStatement(pos); | 2261 return factory()->NewEmptyStatement(pos); |
| 2260 } | 2262 } |
| 2261 BreakableStatement* target = NULL; | 2263 BreakableStatement* target = NULL; |
| 2262 target = LookupBreakTarget(label, CHECK_OK); | 2264 target = LookupBreakTarget(label, CHECK_OK); |
| 2263 if (target == NULL) { | 2265 if (target == NULL) { |
| 2264 // Illegal break statement. | 2266 // Illegal break statement. |
| 2265 const char* message = "illegal_break"; | 2267 const char* message = "illegal_break"; |
| 2266 Vector<Handle<String> > args; | 2268 Vector<Handle<String> > args; |
| 2267 if (!label.is_null()) { | 2269 if (!label.is_null()) { |
| 2268 message = "unknown_label"; | 2270 message = "unknown_label"; |
| 2269 args = Vector<Handle<String> >(&label, 1); | 2271 args = Vector<Handle<String> >(&label, 1); |
| 2270 } | 2272 } |
| 2271 ParserTraits::ReportMessageAt(scanner()->location(), message, args); | 2273 ReportMessageAt(scanner().location(), message, args); |
| 2272 *ok = false; | 2274 *ok = false; |
| 2273 return NULL; | 2275 return NULL; |
| 2274 } | 2276 } |
| 2275 ExpectSemicolon(CHECK_OK); | 2277 ExpectSemicolon(CHECK_OK); |
| 2276 return factory()->NewBreakStatement(target, pos); | 2278 return factory()->NewBreakStatement(target, pos); |
| 2277 } | 2279 } |
| 2278 | 2280 |
| 2279 | 2281 |
| 2280 Statement* Parser::ParseReturnStatement(bool* ok) { | 2282 Statement* Parser::ParseReturnStatement(bool* ok) { |
| 2281 // ReturnStatement :: | 2283 // ReturnStatement :: |
| 2282 // 'return' Expression? ';' | 2284 // 'return' Expression? ';' |
| 2283 | 2285 |
| 2284 // Consume the return token. It is necessary to do that before | 2286 // Consume the return token. It is necessary to do that before |
| 2285 // reporting any errors on it, because of the way errors are | 2287 // reporting any errors on it, because of the way errors are |
| 2286 // reported (underlining). | 2288 // reported (underlining). |
| 2287 Expect(Token::RETURN, CHECK_OK); | 2289 Expect(Token::RETURN, CHECK_OK); |
| 2288 int pos = position(); | 2290 int pos = position(); |
| 2289 | 2291 |
| 2290 Token::Value tok = peek(); | 2292 Token::Value tok = peek(); |
| 2291 Statement* result; | 2293 Statement* result; |
| 2292 Expression* return_value; | 2294 Expression* return_value; |
| 2293 if (scanner()->HasAnyLineTerminatorBeforeNext() || | 2295 if (scanner().HasAnyLineTerminatorBeforeNext() || |
| 2294 tok == Token::SEMICOLON || | 2296 tok == Token::SEMICOLON || |
| 2295 tok == Token::RBRACE || | 2297 tok == Token::RBRACE || |
| 2296 tok == Token::EOS) { | 2298 tok == Token::EOS) { |
| 2297 return_value = GetLiteralUndefined(position()); | 2299 return_value = GetLiteralUndefined(position()); |
| 2298 } else { | 2300 } else { |
| 2299 return_value = ParseExpression(true, CHECK_OK); | 2301 return_value = ParseExpression(true, CHECK_OK); |
| 2300 } | 2302 } |
| 2301 ExpectSemicolon(CHECK_OK); | 2303 ExpectSemicolon(CHECK_OK); |
| 2302 if (is_generator()) { | 2304 if (is_generator()) { |
| 2303 Expression* generator = factory()->NewVariableProxy( | 2305 Expression* generator = factory()->NewVariableProxy( |
| 2304 function_state_->generator_object_variable()); | 2306 current_function_state_->generator_object_variable()); |
| 2305 Expression* yield = factory()->NewYield( | 2307 Expression* yield = factory()->NewYield( |
| 2306 generator, return_value, Yield::FINAL, pos); | 2308 generator, return_value, Yield::FINAL, pos); |
| 2307 result = factory()->NewExpressionStatement(yield, pos); | 2309 result = factory()->NewExpressionStatement(yield, pos); |
| 2308 } else { | 2310 } else { |
| 2309 result = factory()->NewReturnStatement(return_value, pos); | 2311 result = factory()->NewReturnStatement(return_value, pos); |
| 2310 } | 2312 } |
| 2311 | 2313 |
| 2312 // An ECMAScript program is considered syntactically incorrect if it | 2314 // An ECMAScript program is considered syntactically incorrect if it |
| 2313 // contains a return statement that is not within the body of a | 2315 // contains a return statement that is not within the body of a |
| 2314 // function. See ECMA-262, section 12.9, page 67. | 2316 // function. See ECMA-262, section 12.9, page 67. |
| 2315 // | 2317 // |
| 2316 // To be consistent with KJS we report the syntax error at runtime. | 2318 // To be consistent with KJS we report the syntax error at runtime. |
| 2317 Scope* declaration_scope = scope_->DeclarationScope(); | 2319 Scope* declaration_scope = top_scope_->DeclarationScope(); |
| 2318 if (declaration_scope->is_global_scope() || | 2320 if (declaration_scope->is_global_scope() || |
| 2319 declaration_scope->is_eval_scope()) { | 2321 declaration_scope->is_eval_scope()) { |
| 2320 Handle<String> message = isolate()->factory()->illegal_return_string(); | 2322 Handle<String> message = isolate()->factory()->illegal_return_string(); |
| 2321 Expression* throw_error = | 2323 Expression* throw_error = |
| 2322 NewThrowSyntaxError(message, Handle<Object>::null()); | 2324 NewThrowSyntaxError(message, Handle<Object>::null()); |
| 2323 return factory()->NewExpressionStatement(throw_error, pos); | 2325 return factory()->NewExpressionStatement(throw_error, pos); |
| 2324 } | 2326 } |
| 2325 return result; | 2327 return result; |
| 2326 } | 2328 } |
| 2327 | 2329 |
| 2328 | 2330 |
| 2329 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2331 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2330 // WithStatement :: | 2332 // WithStatement :: |
| 2331 // 'with' '(' Expression ')' Statement | 2333 // 'with' '(' Expression ')' Statement |
| 2332 | 2334 |
| 2333 Expect(Token::WITH, CHECK_OK); | 2335 Expect(Token::WITH, CHECK_OK); |
| 2334 int pos = position(); | 2336 int pos = position(); |
| 2335 | 2337 |
| 2336 if (!scope_->is_classic_mode()) { | 2338 if (!top_scope_->is_classic_mode()) { |
| 2337 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2339 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2338 *ok = false; | 2340 *ok = false; |
| 2339 return NULL; | 2341 return NULL; |
| 2340 } | 2342 } |
| 2341 | 2343 |
| 2342 Expect(Token::LPAREN, CHECK_OK); | 2344 Expect(Token::LPAREN, CHECK_OK); |
| 2343 Expression* expr = ParseExpression(true, CHECK_OK); | 2345 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2344 Expect(Token::RPAREN, CHECK_OK); | 2346 Expect(Token::RPAREN, CHECK_OK); |
| 2345 | 2347 |
| 2346 scope_->DeclarationScope()->RecordWithStatement(); | 2348 top_scope_->DeclarationScope()->RecordWithStatement(); |
| 2347 Scope* with_scope = NewScope(scope_, WITH_SCOPE); | 2349 Scope* with_scope = NewScope(top_scope_, WITH_SCOPE); |
| 2348 Statement* stmt; | 2350 Statement* stmt; |
| 2349 { BlockState block_state(&scope_, with_scope); | 2351 { BlockState block_state(this, with_scope); |
| 2350 with_scope->set_start_position(scanner()->peek_location().beg_pos); | 2352 with_scope->set_start_position(scanner().peek_location().beg_pos); |
| 2351 stmt = ParseStatement(labels, CHECK_OK); | 2353 stmt = ParseStatement(labels, CHECK_OK); |
| 2352 with_scope->set_end_position(scanner()->location().end_pos); | 2354 with_scope->set_end_position(scanner().location().end_pos); |
| 2353 } | 2355 } |
| 2354 return factory()->NewWithStatement(with_scope, expr, stmt, pos); | 2356 return factory()->NewWithStatement(with_scope, expr, stmt, pos); |
| 2355 } | 2357 } |
| 2356 | 2358 |
| 2357 | 2359 |
| 2358 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { | 2360 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { |
| 2359 // CaseClause :: | 2361 // CaseClause :: |
| 2360 // 'case' Expression ':' Statement* | 2362 // 'case' Expression ':' Statement* |
| 2361 // 'default' ':' Statement* | 2363 // 'default' ':' Statement* |
| 2362 | 2364 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2416 return statement; | 2418 return statement; |
| 2417 } | 2419 } |
| 2418 | 2420 |
| 2419 | 2421 |
| 2420 Statement* Parser::ParseThrowStatement(bool* ok) { | 2422 Statement* Parser::ParseThrowStatement(bool* ok) { |
| 2421 // ThrowStatement :: | 2423 // ThrowStatement :: |
| 2422 // 'throw' Expression ';' | 2424 // 'throw' Expression ';' |
| 2423 | 2425 |
| 2424 Expect(Token::THROW, CHECK_OK); | 2426 Expect(Token::THROW, CHECK_OK); |
| 2425 int pos = position(); | 2427 int pos = position(); |
| 2426 if (scanner()->HasAnyLineTerminatorBeforeNext()) { | 2428 if (scanner().HasAnyLineTerminatorBeforeNext()) { |
| 2427 ReportMessage("newline_after_throw", Vector<const char*>::empty()); | 2429 ReportMessage("newline_after_throw", Vector<const char*>::empty()); |
| 2428 *ok = false; | 2430 *ok = false; |
| 2429 return NULL; | 2431 return NULL; |
| 2430 } | 2432 } |
| 2431 Expression* exception = ParseExpression(true, CHECK_OK); | 2433 Expression* exception = ParseExpression(true, CHECK_OK); |
| 2432 ExpectSemicolon(CHECK_OK); | 2434 ExpectSemicolon(CHECK_OK); |
| 2433 | 2435 |
| 2434 return factory()->NewExpressionStatement( | 2436 return factory()->NewExpressionStatement( |
| 2435 factory()->NewThrow(exception, pos), pos); | 2437 factory()->NewThrow(exception, pos), pos); |
| 2436 } | 2438 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2471 // always collect the targets. | 2473 // always collect the targets. |
| 2472 TargetCollector catch_collector(zone()); | 2474 TargetCollector catch_collector(zone()); |
| 2473 Scope* catch_scope = NULL; | 2475 Scope* catch_scope = NULL; |
| 2474 Variable* catch_variable = NULL; | 2476 Variable* catch_variable = NULL; |
| 2475 Block* catch_block = NULL; | 2477 Block* catch_block = NULL; |
| 2476 Handle<String> name; | 2478 Handle<String> name; |
| 2477 if (tok == Token::CATCH) { | 2479 if (tok == Token::CATCH) { |
| 2478 Consume(Token::CATCH); | 2480 Consume(Token::CATCH); |
| 2479 | 2481 |
| 2480 Expect(Token::LPAREN, CHECK_OK); | 2482 Expect(Token::LPAREN, CHECK_OK); |
| 2481 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2483 catch_scope = NewScope(top_scope_, CATCH_SCOPE); |
| 2482 catch_scope->set_start_position(scanner()->location().beg_pos); | 2484 catch_scope->set_start_position(scanner().location().beg_pos); |
| 2483 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2485 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2484 | 2486 |
| 2485 Expect(Token::RPAREN, CHECK_OK); | 2487 Expect(Token::RPAREN, CHECK_OK); |
| 2486 | 2488 |
| 2487 Target target(&this->target_stack_, &catch_collector); | 2489 Target target(&this->target_stack_, &catch_collector); |
| 2488 VariableMode mode = is_extended_mode() ? LET : VAR; | 2490 VariableMode mode = is_extended_mode() ? LET : VAR; |
| 2489 catch_variable = | 2491 catch_variable = |
| 2490 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2492 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2491 | 2493 |
| 2492 BlockState block_state(&scope_, catch_scope); | 2494 BlockState block_state(this, catch_scope); |
| 2493 catch_block = ParseBlock(NULL, CHECK_OK); | 2495 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2494 | 2496 |
| 2495 catch_scope->set_end_position(scanner()->location().end_pos); | 2497 catch_scope->set_end_position(scanner().location().end_pos); |
| 2496 tok = peek(); | 2498 tok = peek(); |
| 2497 } | 2499 } |
| 2498 | 2500 |
| 2499 Block* finally_block = NULL; | 2501 Block* finally_block = NULL; |
| 2500 ASSERT(tok == Token::FINALLY || catch_block != NULL); | 2502 ASSERT(tok == Token::FINALLY || catch_block != NULL); |
| 2501 if (tok == Token::FINALLY) { | 2503 if (tok == Token::FINALLY) { |
| 2502 Consume(Token::FINALLY); | 2504 Consume(Token::FINALLY); |
| 2503 finally_block = ParseBlock(NULL, CHECK_OK); | 2505 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2504 } | 2506 } |
| 2505 | 2507 |
| 2506 // Simplify the AST nodes by converting: | 2508 // Simplify the AST nodes by converting: |
| 2507 // 'try B0 catch B1 finally B2' | 2509 // 'try B0 catch B1 finally B2' |
| 2508 // to: | 2510 // to: |
| 2509 // 'try { try B0 catch B1 } finally B2' | 2511 // 'try { try B0 catch B1 } finally B2' |
| 2510 | 2512 |
| 2511 if (catch_block != NULL && finally_block != NULL) { | 2513 if (catch_block != NULL && finally_block != NULL) { |
| 2512 // If we have both, create an inner try/catch. | 2514 // If we have both, create an inner try/catch. |
| 2513 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2515 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2514 int index = function_state_->NextHandlerIndex(); | 2516 int index = current_function_state_->NextHandlerIndex(); |
| 2515 TryCatchStatement* statement = factory()->NewTryCatchStatement( | 2517 TryCatchStatement* statement = factory()->NewTryCatchStatement( |
| 2516 index, try_block, catch_scope, catch_variable, catch_block, | 2518 index, try_block, catch_scope, catch_variable, catch_block, |
| 2517 RelocInfo::kNoPosition); | 2519 RelocInfo::kNoPosition); |
| 2518 statement->set_escaping_targets(try_collector.targets()); | 2520 statement->set_escaping_targets(try_collector.targets()); |
| 2519 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); | 2521 try_block = factory()->NewBlock(NULL, 1, false, RelocInfo::kNoPosition); |
| 2520 try_block->AddStatement(statement, zone()); | 2522 try_block->AddStatement(statement, zone()); |
| 2521 catch_block = NULL; // Clear to indicate it's been handled. | 2523 catch_block = NULL; // Clear to indicate it's been handled. |
| 2522 } | 2524 } |
| 2523 | 2525 |
| 2524 TryStatement* result = NULL; | 2526 TryStatement* result = NULL; |
| 2525 if (catch_block != NULL) { | 2527 if (catch_block != NULL) { |
| 2526 ASSERT(finally_block == NULL); | 2528 ASSERT(finally_block == NULL); |
| 2527 ASSERT(catch_scope != NULL && catch_variable != NULL); | 2529 ASSERT(catch_scope != NULL && catch_variable != NULL); |
| 2528 int index = function_state_->NextHandlerIndex(); | 2530 int index = current_function_state_->NextHandlerIndex(); |
| 2529 result = factory()->NewTryCatchStatement( | 2531 result = factory()->NewTryCatchStatement( |
| 2530 index, try_block, catch_scope, catch_variable, catch_block, pos); | 2532 index, try_block, catch_scope, catch_variable, catch_block, pos); |
| 2531 } else { | 2533 } else { |
| 2532 ASSERT(finally_block != NULL); | 2534 ASSERT(finally_block != NULL); |
| 2533 int index = function_state_->NextHandlerIndex(); | 2535 int index = current_function_state_->NextHandlerIndex(); |
| 2534 result = factory()->NewTryFinallyStatement( | 2536 result = factory()->NewTryFinallyStatement( |
| 2535 index, try_block, finally_block, pos); | 2537 index, try_block, finally_block, pos); |
| 2536 // Combine the jump targets of the try block and the possible catch block. | 2538 // Combine the jump targets of the try block and the possible catch block. |
| 2537 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); | 2539 try_collector.targets()->AddAll(*catch_collector.targets(), zone()); |
| 2538 } | 2540 } |
| 2539 | 2541 |
| 2540 result->set_escaping_targets(try_collector.targets()); | 2542 result->set_escaping_targets(try_collector.targets()); |
| 2541 return result; | 2543 return result; |
| 2542 } | 2544 } |
| 2543 | 2545 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2603 | 2605 |
| 2604 | 2606 |
| 2605 void Parser::InitializeForEachStatement(ForEachStatement* stmt, | 2607 void Parser::InitializeForEachStatement(ForEachStatement* stmt, |
| 2606 Expression* each, | 2608 Expression* each, |
| 2607 Expression* subject, | 2609 Expression* subject, |
| 2608 Statement* body) { | 2610 Statement* body) { |
| 2609 ForOfStatement* for_of = stmt->AsForOfStatement(); | 2611 ForOfStatement* for_of = stmt->AsForOfStatement(); |
| 2610 | 2612 |
| 2611 if (for_of != NULL) { | 2613 if (for_of != NULL) { |
| 2612 Factory* heap_factory = isolate()->factory(); | 2614 Factory* heap_factory = isolate()->factory(); |
| 2613 Variable* iterator = scope_->DeclarationScope()->NewTemporary( | 2615 Variable* iterator = top_scope_->DeclarationScope()->NewTemporary( |
| 2614 heap_factory->dot_iterator_string()); | 2616 heap_factory->dot_iterator_string()); |
| 2615 Variable* result = scope_->DeclarationScope()->NewTemporary( | 2617 Variable* result = top_scope_->DeclarationScope()->NewTemporary( |
| 2616 heap_factory->dot_result_string()); | 2618 heap_factory->dot_result_string()); |
| 2617 | 2619 |
| 2618 Expression* assign_iterator; | 2620 Expression* assign_iterator; |
| 2619 Expression* next_result; | 2621 Expression* next_result; |
| 2620 Expression* result_done; | 2622 Expression* result_done; |
| 2621 Expression* assign_each; | 2623 Expression* assign_each; |
| 2622 | 2624 |
| 2623 // var iterator = iterable; | 2625 // var iterator = iterable; |
| 2624 { | 2626 { |
| 2625 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | 2627 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2672 | 2674 |
| 2673 | 2675 |
| 2674 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2676 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2675 // ForStatement :: | 2677 // ForStatement :: |
| 2676 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2678 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2677 | 2679 |
| 2678 int pos = peek_position(); | 2680 int pos = peek_position(); |
| 2679 Statement* init = NULL; | 2681 Statement* init = NULL; |
| 2680 | 2682 |
| 2681 // Create an in-between scope for let-bound iteration variables. | 2683 // Create an in-between scope for let-bound iteration variables. |
| 2682 Scope* saved_scope = scope_; | 2684 Scope* saved_scope = top_scope_; |
| 2683 Scope* for_scope = NewScope(scope_, BLOCK_SCOPE); | 2685 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
| 2684 scope_ = for_scope; | 2686 top_scope_ = for_scope; |
| 2685 | 2687 |
| 2686 Expect(Token::FOR, CHECK_OK); | 2688 Expect(Token::FOR, CHECK_OK); |
| 2687 Expect(Token::LPAREN, CHECK_OK); | 2689 Expect(Token::LPAREN, CHECK_OK); |
| 2688 for_scope->set_start_position(scanner()->location().beg_pos); | 2690 for_scope->set_start_position(scanner().location().beg_pos); |
| 2689 if (peek() != Token::SEMICOLON) { | 2691 if (peek() != Token::SEMICOLON) { |
| 2690 if (peek() == Token::VAR || peek() == Token::CONST) { | 2692 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2691 bool is_const = peek() == Token::CONST; | 2693 bool is_const = peek() == Token::CONST; |
| 2692 Handle<String> name; | 2694 Handle<String> name; |
| 2693 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2695 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| 2694 Block* variable_statement = | 2696 Block* variable_statement = |
| 2695 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2697 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
| 2696 CHECK_OK); | 2698 CHECK_OK); |
| 2697 bool accept_OF = decl_props == kHasNoInitializers; | 2699 bool accept_OF = decl_props == kHasNoInitializers; |
| 2698 ForEachStatement::VisitMode mode; | 2700 ForEachStatement::VisitMode mode; |
| 2699 | 2701 |
| 2700 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { | 2702 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) { |
| 2701 Interface* interface = | 2703 Interface* interface = |
| 2702 is_const ? Interface::NewConst() : Interface::NewValue(); | 2704 is_const ? Interface::NewConst() : Interface::NewValue(); |
| 2703 ForEachStatement* loop = | 2705 ForEachStatement* loop = |
| 2704 factory()->NewForEachStatement(mode, labels, pos); | 2706 factory()->NewForEachStatement(mode, labels, pos); |
| 2705 Target target(&this->target_stack_, loop); | 2707 Target target(&this->target_stack_, loop); |
| 2706 | 2708 |
| 2707 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2709 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2708 Expect(Token::RPAREN, CHECK_OK); | 2710 Expect(Token::RPAREN, CHECK_OK); |
| 2709 | 2711 |
| 2710 VariableProxy* each = | 2712 VariableProxy* each = |
| 2711 scope_->NewUnresolved(factory(), name, interface); | 2713 top_scope_->NewUnresolved(factory(), name, interface); |
| 2712 Statement* body = ParseStatement(NULL, CHECK_OK); | 2714 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2713 InitializeForEachStatement(loop, each, enumerable, body); | 2715 InitializeForEachStatement(loop, each, enumerable, body); |
| 2714 Block* result = | 2716 Block* result = |
| 2715 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2717 factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2716 result->AddStatement(variable_statement, zone()); | 2718 result->AddStatement(variable_statement, zone()); |
| 2717 result->AddStatement(loop, zone()); | 2719 result->AddStatement(loop, zone()); |
| 2718 scope_ = saved_scope; | 2720 top_scope_ = saved_scope; |
| 2719 for_scope->set_end_position(scanner()->location().end_pos); | 2721 for_scope->set_end_position(scanner().location().end_pos); |
| 2720 for_scope = for_scope->FinalizeBlockScope(); | 2722 for_scope = for_scope->FinalizeBlockScope(); |
| 2721 ASSERT(for_scope == NULL); | 2723 ASSERT(for_scope == NULL); |
| 2722 // Parsed for-in loop w/ variable/const declaration. | 2724 // Parsed for-in loop w/ variable/const declaration. |
| 2723 return result; | 2725 return result; |
| 2724 } else { | 2726 } else { |
| 2725 init = variable_statement; | 2727 init = variable_statement; |
| 2726 } | 2728 } |
| 2727 } else if (peek() == Token::LET) { | 2729 } else if (peek() == Token::LET) { |
| 2728 Handle<String> name; | 2730 Handle<String> name; |
| 2729 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2731 VariableDeclarationProperties decl_props = kHasNoInitializers; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2747 // x = x'; | 2749 // x = x'; |
| 2748 // b; | 2750 // b; |
| 2749 // } | 2751 // } |
| 2750 | 2752 |
| 2751 // TODO(keuchel): Move the temporary variable to the block scope, after | 2753 // TODO(keuchel): Move the temporary variable to the block scope, after |
| 2752 // implementing stack allocated block scoped variables. | 2754 // implementing stack allocated block scoped variables. |
| 2753 Factory* heap_factory = isolate()->factory(); | 2755 Factory* heap_factory = isolate()->factory(); |
| 2754 Handle<String> tempstr = | 2756 Handle<String> tempstr = |
| 2755 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2757 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
| 2756 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2758 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
| 2757 Variable* temp = scope_->DeclarationScope()->NewTemporary(tempname); | 2759 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
| 2758 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2760 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
| 2759 ForEachStatement* loop = | 2761 ForEachStatement* loop = |
| 2760 factory()->NewForEachStatement(mode, labels, pos); | 2762 factory()->NewForEachStatement(mode, labels, pos); |
| 2761 Target target(&this->target_stack_, loop); | 2763 Target target(&this->target_stack_, loop); |
| 2762 | 2764 |
| 2763 // The expression does not see the loop variable. | 2765 // The expression does not see the loop variable. |
| 2764 scope_ = saved_scope; | 2766 top_scope_ = saved_scope; |
| 2765 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2767 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2766 scope_ = for_scope; | 2768 top_scope_ = for_scope; |
| 2767 Expect(Token::RPAREN, CHECK_OK); | 2769 Expect(Token::RPAREN, CHECK_OK); |
| 2768 | 2770 |
| 2769 VariableProxy* each = | 2771 VariableProxy* each = |
| 2770 scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2772 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
| 2771 Statement* body = ParseStatement(NULL, CHECK_OK); | 2773 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2772 Block* body_block = | 2774 Block* body_block = |
| 2773 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); | 2775 factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition); |
| 2774 Assignment* assignment = factory()->NewAssignment( | 2776 Assignment* assignment = factory()->NewAssignment( |
| 2775 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2777 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
| 2776 Statement* assignment_statement = factory()->NewExpressionStatement( | 2778 Statement* assignment_statement = factory()->NewExpressionStatement( |
| 2777 assignment, RelocInfo::kNoPosition); | 2779 assignment, RelocInfo::kNoPosition); |
| 2778 body_block->AddStatement(variable_statement, zone()); | 2780 body_block->AddStatement(variable_statement, zone()); |
| 2779 body_block->AddStatement(assignment_statement, zone()); | 2781 body_block->AddStatement(assignment_statement, zone()); |
| 2780 body_block->AddStatement(body, zone()); | 2782 body_block->AddStatement(body, zone()); |
| 2781 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); | 2783 InitializeForEachStatement(loop, temp_proxy, enumerable, body_block); |
| 2782 scope_ = saved_scope; | 2784 top_scope_ = saved_scope; |
| 2783 for_scope->set_end_position(scanner()->location().end_pos); | 2785 for_scope->set_end_position(scanner().location().end_pos); |
| 2784 for_scope = for_scope->FinalizeBlockScope(); | 2786 for_scope = for_scope->FinalizeBlockScope(); |
| 2785 body_block->set_scope(for_scope); | 2787 body_block->set_scope(for_scope); |
| 2786 // Parsed for-in loop w/ let declaration. | 2788 // Parsed for-in loop w/ let declaration. |
| 2787 return loop; | 2789 return loop; |
| 2788 | 2790 |
| 2789 } else { | 2791 } else { |
| 2790 init = variable_statement; | 2792 init = variable_statement; |
| 2791 } | 2793 } |
| 2792 } else { | 2794 } else { |
| 2793 Expression* expression = ParseExpression(false, CHECK_OK); | 2795 Expression* expression = ParseExpression(false, CHECK_OK); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2806 } | 2808 } |
| 2807 ForEachStatement* loop = | 2809 ForEachStatement* loop = |
| 2808 factory()->NewForEachStatement(mode, labels, pos); | 2810 factory()->NewForEachStatement(mode, labels, pos); |
| 2809 Target target(&this->target_stack_, loop); | 2811 Target target(&this->target_stack_, loop); |
| 2810 | 2812 |
| 2811 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2813 Expression* enumerable = ParseExpression(true, CHECK_OK); |
| 2812 Expect(Token::RPAREN, CHECK_OK); | 2814 Expect(Token::RPAREN, CHECK_OK); |
| 2813 | 2815 |
| 2814 Statement* body = ParseStatement(NULL, CHECK_OK); | 2816 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2815 InitializeForEachStatement(loop, expression, enumerable, body); | 2817 InitializeForEachStatement(loop, expression, enumerable, body); |
| 2816 scope_ = saved_scope; | 2818 top_scope_ = saved_scope; |
| 2817 for_scope->set_end_position(scanner()->location().end_pos); | 2819 for_scope->set_end_position(scanner().location().end_pos); |
| 2818 for_scope = for_scope->FinalizeBlockScope(); | 2820 for_scope = for_scope->FinalizeBlockScope(); |
| 2819 ASSERT(for_scope == NULL); | 2821 ASSERT(for_scope == NULL); |
| 2820 // Parsed for-in loop. | 2822 // Parsed for-in loop. |
| 2821 return loop; | 2823 return loop; |
| 2822 | 2824 |
| 2823 } else { | 2825 } else { |
| 2824 init = factory()->NewExpressionStatement( | 2826 init = factory()->NewExpressionStatement( |
| 2825 expression, RelocInfo::kNoPosition); | 2827 expression, RelocInfo::kNoPosition); |
| 2826 } | 2828 } |
| 2827 } | 2829 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2841 Expect(Token::SEMICOLON, CHECK_OK); | 2843 Expect(Token::SEMICOLON, CHECK_OK); |
| 2842 | 2844 |
| 2843 Statement* next = NULL; | 2845 Statement* next = NULL; |
| 2844 if (peek() != Token::RPAREN) { | 2846 if (peek() != Token::RPAREN) { |
| 2845 Expression* exp = ParseExpression(true, CHECK_OK); | 2847 Expression* exp = ParseExpression(true, CHECK_OK); |
| 2846 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); | 2848 next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition); |
| 2847 } | 2849 } |
| 2848 Expect(Token::RPAREN, CHECK_OK); | 2850 Expect(Token::RPAREN, CHECK_OK); |
| 2849 | 2851 |
| 2850 Statement* body = ParseStatement(NULL, CHECK_OK); | 2852 Statement* body = ParseStatement(NULL, CHECK_OK); |
| 2851 scope_ = saved_scope; | 2853 top_scope_ = saved_scope; |
| 2852 for_scope->set_end_position(scanner()->location().end_pos); | 2854 for_scope->set_end_position(scanner().location().end_pos); |
| 2853 for_scope = for_scope->FinalizeBlockScope(); | 2855 for_scope = for_scope->FinalizeBlockScope(); |
| 2854 if (for_scope != NULL) { | 2856 if (for_scope != NULL) { |
| 2855 // Rewrite a for statement of the form | 2857 // Rewrite a for statement of the form |
| 2856 // | 2858 // |
| 2857 // for (let x = i; c; n) b | 2859 // for (let x = i; c; n) b |
| 2858 // | 2860 // |
| 2859 // into | 2861 // into |
| 2860 // | 2862 // |
| 2861 // { | 2863 // { |
| 2862 // let x = i; | 2864 // let x = i; |
| 2863 // for (; c; n) b | 2865 // for (; c; n) b |
| 2864 // } | 2866 // } |
| 2865 ASSERT(init != NULL); | 2867 ASSERT(init != NULL); |
| 2866 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 2868 Block* result = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); |
| 2867 result->AddStatement(init, zone()); | 2869 result->AddStatement(init, zone()); |
| 2868 result->AddStatement(loop, zone()); | 2870 result->AddStatement(loop, zone()); |
| 2869 result->set_scope(for_scope); | 2871 result->set_scope(for_scope); |
| 2870 loop->Initialize(NULL, cond, next, body); | 2872 loop->Initialize(NULL, cond, next, body); |
| 2871 return result; | 2873 return result; |
| 2872 } else { | 2874 } else { |
| 2873 loop->Initialize(init, cond, next, body); | 2875 loop->Initialize(init, cond, next, body); |
| 2874 return loop; | 2876 return loop; |
| 2875 } | 2877 } |
| 2876 } | 2878 } |
| 2877 | 2879 |
| 2878 | 2880 |
| 2881 // Precedence = 1 |
| 2882 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
| 2883 // Expression :: |
| 2884 // AssignmentExpression |
| 2885 // Expression ',' AssignmentExpression |
| 2886 |
| 2887 Expression* result = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2888 while (peek() == Token::COMMA) { |
| 2889 Expect(Token::COMMA, CHECK_OK); |
| 2890 int pos = position(); |
| 2891 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2892 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
| 2893 } |
| 2894 return result; |
| 2895 } |
| 2896 |
| 2897 |
| 2879 // Precedence = 2 | 2898 // Precedence = 2 |
| 2880 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2899 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2881 // AssignmentExpression :: | 2900 // AssignmentExpression :: |
| 2882 // ConditionalExpression | 2901 // ConditionalExpression |
| 2883 // YieldExpression | 2902 // YieldExpression |
| 2884 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2903 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
| 2885 | 2904 |
| 2886 if (peek() == Token::YIELD && is_generator()) { | 2905 if (peek() == Token::YIELD && is_generator()) { |
| 2887 return ParseYieldExpression(ok); | 2906 return ParseYieldExpression(ok); |
| 2888 } | 2907 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2900 // side expression. We could report this as a syntax error here but | 2919 // side expression. We could report this as a syntax error here but |
| 2901 // for compatibility with JSC we choose to report the error at | 2920 // for compatibility with JSC we choose to report the error at |
| 2902 // runtime. | 2921 // runtime. |
| 2903 // TODO(ES5): Should change parsing for spec conformance. | 2922 // TODO(ES5): Should change parsing for spec conformance. |
| 2904 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2923 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2905 Handle<String> message = | 2924 Handle<String> message = |
| 2906 isolate()->factory()->invalid_lhs_in_assignment_string(); | 2925 isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 2907 expression = NewThrowReferenceError(message); | 2926 expression = NewThrowReferenceError(message); |
| 2908 } | 2927 } |
| 2909 | 2928 |
| 2910 if (!scope_->is_classic_mode()) { | 2929 if (!top_scope_->is_classic_mode()) { |
| 2911 // Assignment to eval or arguments is disallowed in strict mode. | 2930 // Assignment to eval or arguments is disallowed in strict mode. |
| 2912 CheckStrictModeLValue(expression, CHECK_OK); | 2931 CheckStrictModeLValue(expression, CHECK_OK); |
| 2913 } | 2932 } |
| 2914 MarkAsLValue(expression); | 2933 MarkAsLValue(expression); |
| 2915 | 2934 |
| 2916 Token::Value op = Next(); // Get assignment operator. | 2935 Token::Value op = Next(); // Get assignment operator. |
| 2917 int pos = position(); | 2936 int pos = position(); |
| 2918 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2937 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2919 | 2938 |
| 2920 // TODO(1231235): We try to estimate the set of properties set by | 2939 // TODO(1231235): We try to estimate the set of properties set by |
| 2921 // constructors. We define a new property whenever there is an | 2940 // constructors. We define a new property whenever there is an |
| 2922 // assignment to a property of 'this'. We should probably only add | 2941 // assignment to a property of 'this'. We should probably only add |
| 2923 // properties if we haven't seen them before. Otherwise we'll | 2942 // properties if we haven't seen them before. Otherwise we'll |
| 2924 // probably overestimate the number of properties. | 2943 // probably overestimate the number of properties. |
| 2925 Property* property = expression ? expression->AsProperty() : NULL; | 2944 Property* property = expression ? expression->AsProperty() : NULL; |
| 2926 if (op == Token::ASSIGN && | 2945 if (op == Token::ASSIGN && |
| 2927 property != NULL && | 2946 property != NULL && |
| 2928 property->obj()->AsVariableProxy() != NULL && | 2947 property->obj()->AsVariableProxy() != NULL && |
| 2929 property->obj()->AsVariableProxy()->is_this()) { | 2948 property->obj()->AsVariableProxy()->is_this()) { |
| 2930 function_state_->AddProperty(); | 2949 current_function_state_->AddProperty(); |
| 2931 } | 2950 } |
| 2932 | 2951 |
| 2933 // If we assign a function literal to a property we pretenure the | 2952 // If we assign a function literal to a property we pretenure the |
| 2934 // literal so it can be added as a constant function property. | 2953 // literal so it can be added as a constant function property. |
| 2935 if (property != NULL && right->AsFunctionLiteral() != NULL) { | 2954 if (property != NULL && right->AsFunctionLiteral() != NULL) { |
| 2936 right->AsFunctionLiteral()->set_pretenure(); | 2955 right->AsFunctionLiteral()->set_pretenure(); |
| 2937 } | 2956 } |
| 2938 | 2957 |
| 2939 if (fni_ != NULL) { | 2958 if (fni_ != NULL) { |
| 2940 // Check if the right hand side is a call to avoid inferring a | 2959 // Check if the right hand side is a call to avoid inferring a |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2956 | 2975 |
| 2957 | 2976 |
| 2958 Expression* Parser::ParseYieldExpression(bool* ok) { | 2977 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 2959 // YieldExpression :: | 2978 // YieldExpression :: |
| 2960 // 'yield' '*'? AssignmentExpression | 2979 // 'yield' '*'? AssignmentExpression |
| 2961 int pos = peek_position(); | 2980 int pos = peek_position(); |
| 2962 Expect(Token::YIELD, CHECK_OK); | 2981 Expect(Token::YIELD, CHECK_OK); |
| 2963 Yield::Kind kind = | 2982 Yield::Kind kind = |
| 2964 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2983 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 2965 Expression* generator_object = factory()->NewVariableProxy( | 2984 Expression* generator_object = factory()->NewVariableProxy( |
| 2966 function_state_->generator_object_variable()); | 2985 current_function_state_->generator_object_variable()); |
| 2967 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 2986 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| 2968 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); | 2987 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); |
| 2969 if (kind == Yield::DELEGATING) { | 2988 if (kind == Yield::DELEGATING) { |
| 2970 yield->set_index(function_state_->NextHandlerIndex()); | 2989 yield->set_index(current_function_state_->NextHandlerIndex()); |
| 2971 } | 2990 } |
| 2972 return yield; | 2991 return yield; |
| 2973 } | 2992 } |
| 2974 | 2993 |
| 2975 | 2994 |
| 2976 // Precedence = 3 | 2995 // Precedence = 3 |
| 2977 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2996 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 2978 // ConditionalExpression :: | 2997 // ConditionalExpression :: |
| 2979 // LogicalOrExpression | 2998 // LogicalOrExpression |
| 2980 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2999 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2981 | 3000 |
| 2982 int pos = peek_position(); | 3001 int pos = peek_position(); |
| 2983 // We start using the binary expression parser for prec >= 4 only! | 3002 // We start using the binary expression parser for prec >= 4 only! |
| 2984 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 3003 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2985 if (peek() != Token::CONDITIONAL) return expression; | 3004 if (peek() != Token::CONDITIONAL) return expression; |
| 2986 Consume(Token::CONDITIONAL); | 3005 Consume(Token::CONDITIONAL); |
| 2987 // In parsing the first assignment expression in conditional | 3006 // In parsing the first assignment expression in conditional |
| 2988 // expressions we always accept the 'in' keyword; see ECMA-262, | 3007 // expressions we always accept the 'in' keyword; see ECMA-262, |
| 2989 // section 11.12, page 58. | 3008 // section 11.12, page 58. |
| 2990 Expression* left = ParseAssignmentExpression(true, CHECK_OK); | 3009 Expression* left = ParseAssignmentExpression(true, CHECK_OK); |
| 2991 Expect(Token::COLON, CHECK_OK); | 3010 Expect(Token::COLON, CHECK_OK); |
| 2992 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 3011 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2993 return factory()->NewConditional(expression, left, right, pos); | 3012 return factory()->NewConditional(expression, left, right, pos); |
| 2994 } | 3013 } |
| 2995 | 3014 |
| 2996 | 3015 |
| 3016 int ParserBase::Precedence(Token::Value tok, bool accept_IN) { |
| 3017 if (tok == Token::IN && !accept_IN) |
| 3018 return 0; // 0 precedence will terminate binary expression parsing |
| 3019 |
| 3020 return Token::Precedence(tok); |
| 3021 } |
| 3022 |
| 3023 |
| 2997 // Precedence >= 4 | 3024 // Precedence >= 4 |
| 2998 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 3025 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 2999 ASSERT(prec >= 4); | 3026 ASSERT(prec >= 4); |
| 3000 Expression* x = ParseUnaryExpression(CHECK_OK); | 3027 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 3001 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 3028 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 3002 // prec1 >= 4 | 3029 // prec1 >= 4 |
| 3003 while (Precedence(peek(), accept_IN) == prec1) { | 3030 while (Precedence(peek(), accept_IN) == prec1) { |
| 3004 Token::Value op = Next(); | 3031 Token::Value op = Next(); |
| 3005 int pos = position(); | 3032 int pos = position(); |
| 3006 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 3033 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3124 return factory()->NewNumberLiteral(-value, pos); | 3151 return factory()->NewNumberLiteral(-value, pos); |
| 3125 case Token::BIT_NOT: | 3152 case Token::BIT_NOT: |
| 3126 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); | 3153 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 3127 default: | 3154 default: |
| 3128 break; | 3155 break; |
| 3129 } | 3156 } |
| 3130 } | 3157 } |
| 3131 } | 3158 } |
| 3132 | 3159 |
| 3133 // "delete identifier" is a syntax error in strict mode. | 3160 // "delete identifier" is a syntax error in strict mode. |
| 3134 if (op == Token::DELETE && !scope_->is_classic_mode()) { | 3161 if (op == Token::DELETE && !top_scope_->is_classic_mode()) { |
| 3135 VariableProxy* operand = expression->AsVariableProxy(); | 3162 VariableProxy* operand = expression->AsVariableProxy(); |
| 3136 if (operand != NULL && !operand->is_this()) { | 3163 if (operand != NULL && !operand->is_this()) { |
| 3137 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3164 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 3138 *ok = false; | 3165 *ok = false; |
| 3139 return NULL; | 3166 return NULL; |
| 3140 } | 3167 } |
| 3141 } | 3168 } |
| 3142 | 3169 |
| 3143 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3170 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
| 3144 // without any special stub and the multiplication is removed later in | 3171 // without any special stub and the multiplication is removed later in |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3172 // Signal a reference error if the expression is an invalid | 3199 // Signal a reference error if the expression is an invalid |
| 3173 // left-hand side expression. We could report this as a syntax | 3200 // left-hand side expression. We could report this as a syntax |
| 3174 // error here but for compatibility with JSC we choose to report the | 3201 // error here but for compatibility with JSC we choose to report the |
| 3175 // error at runtime. | 3202 // error at runtime. |
| 3176 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3203 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3177 Handle<String> message = | 3204 Handle<String> message = |
| 3178 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3205 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3179 expression = NewThrowReferenceError(message); | 3206 expression = NewThrowReferenceError(message); |
| 3180 } | 3207 } |
| 3181 | 3208 |
| 3182 if (!scope_->is_classic_mode()) { | 3209 if (!top_scope_->is_classic_mode()) { |
| 3183 // Prefix expression operand in strict mode may not be eval or arguments. | 3210 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3184 CheckStrictModeLValue(expression, CHECK_OK); | 3211 CheckStrictModeLValue(expression, CHECK_OK); |
| 3185 } | 3212 } |
| 3186 MarkAsLValue(expression); | 3213 MarkAsLValue(expression); |
| 3187 | 3214 |
| 3188 return factory()->NewCountOperation(op, | 3215 return factory()->NewCountOperation(op, |
| 3189 true /* prefix */, | 3216 true /* prefix */, |
| 3190 expression, | 3217 expression, |
| 3191 position()); | 3218 position()); |
| 3192 | 3219 |
| 3193 } else { | 3220 } else { |
| 3194 return ParsePostfixExpression(ok); | 3221 return ParsePostfixExpression(ok); |
| 3195 } | 3222 } |
| 3196 } | 3223 } |
| 3197 | 3224 |
| 3198 | 3225 |
| 3199 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3226 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 3200 // PostfixExpression :: | 3227 // PostfixExpression :: |
| 3201 // LeftHandSideExpression ('++' | '--')? | 3228 // LeftHandSideExpression ('++' | '--')? |
| 3202 | 3229 |
| 3203 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 3230 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 3204 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3231 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 3205 Token::IsCountOp(peek())) { | 3232 Token::IsCountOp(peek())) { |
| 3206 // Signal a reference error if the expression is an invalid | 3233 // Signal a reference error if the expression is an invalid |
| 3207 // left-hand side expression. We could report this as a syntax | 3234 // left-hand side expression. We could report this as a syntax |
| 3208 // error here but for compatibility with JSC we choose to report the | 3235 // error here but for compatibility with JSC we choose to report the |
| 3209 // error at runtime. | 3236 // error at runtime. |
| 3210 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3237 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3211 Handle<String> message = | 3238 Handle<String> message = |
| 3212 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3239 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3213 expression = NewThrowReferenceError(message); | 3240 expression = NewThrowReferenceError(message); |
| 3214 } | 3241 } |
| 3215 | 3242 |
| 3216 if (!scope_->is_classic_mode()) { | 3243 if (!top_scope_->is_classic_mode()) { |
| 3217 // Postfix expression operand in strict mode may not be eval or arguments. | 3244 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3218 CheckStrictModeLValue(expression, CHECK_OK); | 3245 CheckStrictModeLValue(expression, CHECK_OK); |
| 3219 } | 3246 } |
| 3220 MarkAsLValue(expression); | 3247 MarkAsLValue(expression); |
| 3221 | 3248 |
| 3222 Token::Value next = Next(); | 3249 Token::Value next = Next(); |
| 3223 expression = | 3250 expression = |
| 3224 factory()->NewCountOperation(next, | 3251 factory()->NewCountOperation(next, |
| 3225 false /* postfix */, | 3252 false /* postfix */, |
| 3226 expression, | 3253 expression, |
| 3227 position()); | 3254 position()); |
| 3228 } | 3255 } |
| 3229 return expression; | 3256 return expression; |
| 3230 } | 3257 } |
| 3231 | 3258 |
| 3232 | 3259 |
| 3233 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 3260 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
| 3234 // LeftHandSideExpression :: | 3261 // LeftHandSideExpression :: |
| 3235 // (NewExpression | MemberExpression) ... | 3262 // (NewExpression | MemberExpression) ... |
| 3236 | 3263 |
| 3237 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); | 3264 Expression* result; |
| 3265 if (peek() == Token::NEW) { |
| 3266 result = ParseNewExpression(CHECK_OK); |
| 3267 } else { |
| 3268 result = ParseMemberExpression(CHECK_OK); |
| 3269 } |
| 3238 | 3270 |
| 3239 while (true) { | 3271 while (true) { |
| 3240 switch (peek()) { | 3272 switch (peek()) { |
| 3241 case Token::LBRACK: { | 3273 case Token::LBRACK: { |
| 3242 Consume(Token::LBRACK); | 3274 Consume(Token::LBRACK); |
| 3243 int pos = position(); | 3275 int pos = position(); |
| 3244 Expression* index = ParseExpression(true, CHECK_OK); | 3276 Expression* index = ParseExpression(true, CHECK_OK); |
| 3245 result = factory()->NewProperty(result, index, pos); | 3277 result = factory()->NewProperty(result, index, pos); |
| 3246 Expect(Token::RBRACK, CHECK_OK); | 3278 Expect(Token::RBRACK, CHECK_OK); |
| 3247 break; | 3279 break; |
| 3248 } | 3280 } |
| 3249 | 3281 |
| 3250 case Token::LPAREN: { | 3282 case Token::LPAREN: { |
| 3251 int pos; | 3283 int pos; |
| 3252 if (scanner()->current_token() == Token::IDENTIFIER) { | 3284 if (scanner().current_token() == Token::IDENTIFIER) { |
| 3253 // For call of an identifier we want to report position of | 3285 // For call of an identifier we want to report position of |
| 3254 // the identifier as position of the call in the stack trace. | 3286 // the identifier as position of the call in the stack trace. |
| 3255 pos = position(); | 3287 pos = position(); |
| 3256 } else { | 3288 } else { |
| 3257 // For other kinds of calls we record position of the parenthesis as | 3289 // For other kinds of calls we record position of the parenthesis as |
| 3258 // position of the call. Note that this is extremely important for | 3290 // position of the call. Note that this is extremely important for |
| 3259 // expressions of the form function(){...}() for which call position | 3291 // expressions of the form function(){...}() for which call position |
| 3260 // should not point to the closing brace otherwise it will intersect | 3292 // should not point to the closing brace otherwise it will intersect |
| 3261 // with positions recorded for function literal and confuse debugger. | 3293 // with positions recorded for function literal and confuse debugger. |
| 3262 pos = peek_position(); | 3294 pos = peek_position(); |
| 3263 // Also the trailing parenthesis are a hint that the function will | 3295 // Also the trailing parenthesis are a hint that the function will |
| 3264 // be called immediately. If we happen to have parsed a preceding | 3296 // be called immediately. If we happen to have parsed a preceding |
| 3265 // function literal eagerly, we can also compile it eagerly. | 3297 // function literal eagerly, we can also compile it eagerly. |
| 3266 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 3298 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 3267 result->AsFunctionLiteral()->set_parenthesized(); | 3299 result->AsFunctionLiteral()->set_parenthesized(); |
| 3268 } | 3300 } |
| 3269 } | 3301 } |
| 3270 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3302 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3271 | 3303 |
| 3272 // Keep track of eval() calls since they disable all local variable | 3304 // Keep track of eval() calls since they disable all local variable |
| 3273 // optimizations. | 3305 // optimizations. |
| 3274 // The calls that need special treatment are the | 3306 // The calls that need special treatment are the |
| 3275 // direct eval calls. These calls are all of the form eval(...), with | 3307 // direct eval calls. These calls are all of the form eval(...), with |
| 3276 // no explicit receiver. | 3308 // no explicit receiver. |
| 3277 // These calls are marked as potentially direct eval calls. Whether | 3309 // These calls are marked as potentially direct eval calls. Whether |
| 3278 // they are actually direct calls to eval is determined at run time. | 3310 // they are actually direct calls to eval is determined at run time. |
| 3279 VariableProxy* callee = result->AsVariableProxy(); | 3311 VariableProxy* callee = result->AsVariableProxy(); |
| 3280 if (callee != NULL && | 3312 if (callee != NULL && |
| 3281 callee->IsVariable(isolate()->factory()->eval_string())) { | 3313 callee->IsVariable(isolate()->factory()->eval_string())) { |
| 3282 scope_->DeclarationScope()->RecordEvalCall(); | 3314 top_scope_->DeclarationScope()->RecordEvalCall(); |
| 3283 } | 3315 } |
| 3284 result = factory()->NewCall(result, args, pos); | 3316 result = factory()->NewCall(result, args, pos); |
| 3285 if (fni_ != NULL) fni_->RemoveLastFunction(); | 3317 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 3286 break; | 3318 break; |
| 3287 } | 3319 } |
| 3288 | 3320 |
| 3289 case Token::PERIOD: { | 3321 case Token::PERIOD: { |
| 3290 Consume(Token::PERIOD); | 3322 Consume(Token::PERIOD); |
| 3291 int pos = position(); | 3323 int pos = position(); |
| 3292 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3324 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3293 result = factory()->NewProperty( | 3325 result = factory()->NewProperty( |
| 3294 result, factory()->NewLiteral(name, pos), pos); | 3326 result, factory()->NewLiteral(name, pos), pos); |
| 3295 if (fni_ != NULL) fni_->PushLiteralName(name); | 3327 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3296 break; | 3328 break; |
| 3297 } | 3329 } |
| 3298 | 3330 |
| 3299 default: | 3331 default: |
| 3300 return result; | 3332 return result; |
| 3301 } | 3333 } |
| 3302 } | 3334 } |
| 3303 } | 3335 } |
| 3304 | 3336 |
| 3305 | 3337 |
| 3306 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) { | 3338 Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) { |
| 3307 // NewExpression :: | 3339 // NewExpression :: |
| 3308 // ('new')+ MemberExpression | 3340 // ('new')+ MemberExpression |
| 3309 | 3341 |
| 3310 // The grammar for new expressions is pretty warped. We can have several 'new' | 3342 // The grammar for new expressions is pretty warped. The keyword |
| 3311 // keywords following each other, and then a MemberExpression. When we see '(' | 3343 // 'new' can either be a part of the new expression (where it isn't |
| 3312 // after the MemberExpression, it's associated with the rightmost unassociated | 3344 // followed by an argument list) or a part of the member expression, |
| 3313 // 'new' to create a NewExpression with arguments. However, a NewExpression | 3345 // where it must be followed by an argument list. To accommodate |
| 3314 // can also occur without arguments. | 3346 // this, we parse the 'new' keywords greedily and keep track of how |
| 3347 // many we have parsed. This information is then passed on to the |
| 3348 // member expression parser, which is only allowed to match argument |
| 3349 // lists as long as it has 'new' prefixes left |
| 3350 Expect(Token::NEW, CHECK_OK); |
| 3351 PositionStack::Element pos(stack, position()); |
| 3315 | 3352 |
| 3316 // Examples of new expression: | 3353 Expression* result; |
| 3317 // new foo.bar().baz means (new (foo.bar)()).baz | 3354 if (peek() == Token::NEW) { |
| 3318 // new foo()() means (new foo())() | 3355 result = ParseNewPrefix(stack, CHECK_OK); |
| 3319 // new new foo()() means (new (new foo())()) | 3356 } else { |
| 3320 // new new foo means new (new foo) | 3357 result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK); |
| 3321 // new new foo() means new (new foo()) | 3358 } |
| 3322 // new new foo().bar().baz means (new (new foo()).bar()).baz | |
| 3323 | 3359 |
| 3324 if (peek() == Token::NEW) { | 3360 if (!stack->is_empty()) { |
| 3325 Consume(Token::NEW); | 3361 int last = stack->pop(); |
| 3326 int new_pos = position(); | 3362 result = factory()->NewCallNew( |
| 3327 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); | 3363 result, new(zone()) ZoneList<Expression*>(0, zone()), last); |
| 3328 if (peek() == Token::LPAREN) { | |
| 3329 // NewExpression with arguments. | |
| 3330 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | |
| 3331 result = factory()->NewCallNew(result, args, new_pos); | |
| 3332 // The expression can still continue with . or [ after the arguments. | |
| 3333 result = ParseMemberExpressionContinuation(result, CHECK_OK); | |
| 3334 return result; | |
| 3335 } | |
| 3336 // NewExpression without arguments. | |
| 3337 return factory()->NewCallNew( | |
| 3338 result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos); | |
| 3339 } | 3364 } |
| 3340 // No 'new' keyword. | 3365 return result; |
| 3341 return ParseMemberExpression(ok); | 3366 } |
| 3367 |
| 3368 |
| 3369 Expression* Parser::ParseNewExpression(bool* ok) { |
| 3370 PositionStack stack(ok); |
| 3371 return ParseNewPrefix(&stack, ok); |
| 3342 } | 3372 } |
| 3343 | 3373 |
| 3344 | 3374 |
| 3345 Expression* Parser::ParseMemberExpression(bool* ok) { | 3375 Expression* Parser::ParseMemberExpression(bool* ok) { |
| 3376 return ParseMemberWithNewPrefixesExpression(NULL, ok); |
| 3377 } |
| 3378 |
| 3379 |
| 3380 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
| 3381 bool* ok) { |
| 3346 // MemberExpression :: | 3382 // MemberExpression :: |
| 3347 // (PrimaryExpression | FunctionLiteral) | 3383 // (PrimaryExpression | FunctionLiteral) |
| 3348 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3384 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3349 | 3385 |
| 3350 // The '[' Expression ']' and '.' Identifier parts are parsed by | |
| 3351 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | |
| 3352 // caller. | |
| 3353 | |
| 3354 // Parse the initial primary or function expression. | 3386 // Parse the initial primary or function expression. |
| 3355 Expression* result = NULL; | 3387 Expression* result = NULL; |
| 3356 if (peek() == Token::FUNCTION) { | 3388 if (peek() == Token::FUNCTION) { |
| 3357 Consume(Token::FUNCTION); | 3389 Consume(Token::FUNCTION); |
| 3358 int function_token_position = position(); | 3390 int function_token_position = position(); |
| 3359 bool is_generator = allow_generators() && Check(Token::MUL); | 3391 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3360 Handle<String> name; | 3392 Handle<String> name; |
| 3361 bool is_strict_reserved_name = false; | 3393 bool is_strict_reserved_name = false; |
| 3362 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3394 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3363 if (peek_any_identifier()) { | 3395 if (peek_any_identifier()) { |
| 3364 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3396 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3365 CHECK_OK); | 3397 CHECK_OK); |
| 3366 function_name_location = scanner()->location(); | 3398 function_name_location = scanner().location(); |
| 3367 } | 3399 } |
| 3368 FunctionLiteral::FunctionType function_type = name.is_null() | 3400 FunctionLiteral::FunctionType function_type = name.is_null() |
| 3369 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3401 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3370 : FunctionLiteral::NAMED_EXPRESSION; | 3402 : FunctionLiteral::NAMED_EXPRESSION; |
| 3371 result = ParseFunctionLiteral(name, | 3403 result = ParseFunctionLiteral(name, |
| 3372 function_name_location, | 3404 function_name_location, |
| 3373 is_strict_reserved_name, | 3405 is_strict_reserved_name, |
| 3374 is_generator, | 3406 is_generator, |
| 3375 function_token_position, | 3407 function_token_position, |
| 3376 function_type, | 3408 function_type, |
| 3377 CHECK_OK); | 3409 CHECK_OK); |
| 3378 } else { | 3410 } else { |
| 3379 result = ParsePrimaryExpression(CHECK_OK); | 3411 result = ParsePrimaryExpression(CHECK_OK); |
| 3380 } | 3412 } |
| 3381 | 3413 |
| 3382 result = ParseMemberExpressionContinuation(result, CHECK_OK); | |
| 3383 return result; | |
| 3384 } | |
| 3385 | |
| 3386 | |
| 3387 Expression* Parser::ParseMemberExpressionContinuation(Expression* expression, | |
| 3388 bool* ok) { | |
| 3389 // Parses this part of MemberExpression: | |
| 3390 // ('[' Expression ']' | '.' Identifier)* | |
| 3391 while (true) { | 3414 while (true) { |
| 3392 switch (peek()) { | 3415 switch (peek()) { |
| 3393 case Token::LBRACK: { | 3416 case Token::LBRACK: { |
| 3394 Consume(Token::LBRACK); | 3417 Consume(Token::LBRACK); |
| 3395 int pos = position(); | 3418 int pos = position(); |
| 3396 Expression* index = ParseExpression(true, CHECK_OK); | 3419 Expression* index = ParseExpression(true, CHECK_OK); |
| 3397 expression = factory()->NewProperty(expression, index, pos); | 3420 result = factory()->NewProperty(result, index, pos); |
| 3398 if (fni_ != NULL) { | 3421 if (fni_ != NULL) { |
| 3399 if (index->IsPropertyName()) { | 3422 if (index->IsPropertyName()) { |
| 3400 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | 3423 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); |
| 3401 } else { | 3424 } else { |
| 3402 fni_->PushLiteralName( | 3425 fni_->PushLiteralName( |
| 3403 isolate()->factory()->anonymous_function_string()); | 3426 isolate()->factory()->anonymous_function_string()); |
| 3404 } | 3427 } |
| 3405 } | 3428 } |
| 3406 Expect(Token::RBRACK, CHECK_OK); | 3429 Expect(Token::RBRACK, CHECK_OK); |
| 3407 break; | 3430 break; |
| 3408 } | 3431 } |
| 3409 case Token::PERIOD: { | 3432 case Token::PERIOD: { |
| 3410 Consume(Token::PERIOD); | 3433 Consume(Token::PERIOD); |
| 3411 int pos = position(); | 3434 int pos = position(); |
| 3412 Handle<String> name = ParseIdentifierName(CHECK_OK); | 3435 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3413 expression = factory()->NewProperty( | 3436 result = factory()->NewProperty( |
| 3414 expression, factory()->NewLiteral(name, pos), pos); | 3437 result, factory()->NewLiteral(name, pos), pos); |
| 3415 if (fni_ != NULL) fni_->PushLiteralName(name); | 3438 if (fni_ != NULL) fni_->PushLiteralName(name); |
| 3416 break; | 3439 break; |
| 3417 } | 3440 } |
| 3441 case Token::LPAREN: { |
| 3442 if ((stack == NULL) || stack->is_empty()) return result; |
| 3443 // Consume one of the new prefixes (already parsed). |
| 3444 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3445 int pos = stack->pop(); |
| 3446 result = factory()->NewCallNew(result, args, pos); |
| 3447 break; |
| 3448 } |
| 3418 default: | 3449 default: |
| 3419 return expression; | 3450 return result; |
| 3420 } | 3451 } |
| 3421 } | 3452 } |
| 3422 ASSERT(false); | |
| 3423 return NULL; | |
| 3424 } | 3453 } |
| 3425 | 3454 |
| 3426 | 3455 |
| 3427 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3456 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
| 3428 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3457 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
| 3429 // contexts this is used as a statement which invokes the debugger as i a | 3458 // contexts this is used as a statement which invokes the debugger as i a |
| 3430 // break point is present. | 3459 // break point is present. |
| 3431 // DebuggerStatement :: | 3460 // DebuggerStatement :: |
| 3432 // 'debugger' ';' | 3461 // 'debugger' ';' |
| 3433 | 3462 |
| 3434 int pos = peek_position(); | 3463 int pos = peek_position(); |
| 3435 Expect(Token::DEBUGGER, CHECK_OK); | 3464 Expect(Token::DEBUGGER, CHECK_OK); |
| 3436 ExpectSemicolon(CHECK_OK); | 3465 ExpectSemicolon(CHECK_OK); |
| 3437 return factory()->NewDebuggerStatement(pos); | 3466 return factory()->NewDebuggerStatement(pos); |
| 3438 } | 3467 } |
| 3439 | 3468 |
| 3440 | 3469 |
| 3441 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 3470 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
| 3442 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 3471 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
| 3443 const char* element[1] = { name_string.get() }; | 3472 const char* element[1] = { name_string.get() }; |
| 3444 ReportMessage("invalid_preparser_data", | 3473 ReportMessage("invalid_preparser_data", |
| 3445 Vector<const char*>(element, 1)); | 3474 Vector<const char*>(element, 1)); |
| 3446 *ok = false; | 3475 *ok = false; |
| 3447 } | 3476 } |
| 3448 | 3477 |
| 3449 | 3478 |
| 3479 Expression* Parser::ParsePrimaryExpression(bool* ok) { |
| 3480 // PrimaryExpression :: |
| 3481 // 'this' |
| 3482 // 'null' |
| 3483 // 'true' |
| 3484 // 'false' |
| 3485 // Identifier |
| 3486 // Number |
| 3487 // String |
| 3488 // ArrayLiteral |
| 3489 // ObjectLiteral |
| 3490 // RegExpLiteral |
| 3491 // '(' Expression ')' |
| 3492 |
| 3493 int pos = peek_position(); |
| 3494 Expression* result = NULL; |
| 3495 switch (peek()) { |
| 3496 case Token::THIS: { |
| 3497 Consume(Token::THIS); |
| 3498 result = factory()->NewVariableProxy(top_scope_->receiver()); |
| 3499 break; |
| 3500 } |
| 3501 |
| 3502 case Token::NULL_LITERAL: |
| 3503 Consume(Token::NULL_LITERAL); |
| 3504 result = factory()->NewLiteral(isolate()->factory()->null_value(), pos); |
| 3505 break; |
| 3506 |
| 3507 case Token::TRUE_LITERAL: |
| 3508 Consume(Token::TRUE_LITERAL); |
| 3509 result = factory()->NewLiteral(isolate()->factory()->true_value(), pos); |
| 3510 break; |
| 3511 |
| 3512 case Token::FALSE_LITERAL: |
| 3513 Consume(Token::FALSE_LITERAL); |
| 3514 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
| 3515 break; |
| 3516 |
| 3517 case Token::IDENTIFIER: |
| 3518 case Token::YIELD: |
| 3519 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3520 // Using eval or arguments in this context is OK even in strict mode. |
| 3521 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3522 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3523 // The name may refer to a module instance object, so its type is unknown. |
| 3524 #ifdef DEBUG |
| 3525 if (FLAG_print_interface_details) |
| 3526 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 3527 #endif |
| 3528 Interface* interface = Interface::NewUnknown(zone()); |
| 3529 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
| 3530 break; |
| 3531 } |
| 3532 |
| 3533 case Token::NUMBER: { |
| 3534 Consume(Token::NUMBER); |
| 3535 ASSERT(scanner().is_literal_ascii()); |
| 3536 double value = StringToDouble(isolate()->unicode_cache(), |
| 3537 scanner().literal_ascii_string(), |
| 3538 ALLOW_HEX | ALLOW_OCTAL | |
| 3539 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3540 result = factory()->NewNumberLiteral(value, pos); |
| 3541 break; |
| 3542 } |
| 3543 |
| 3544 case Token::STRING: { |
| 3545 Consume(Token::STRING); |
| 3546 Handle<String> symbol = GetSymbol(); |
| 3547 result = factory()->NewLiteral(symbol, pos); |
| 3548 if (fni_ != NULL) fni_->PushLiteralName(symbol); |
| 3549 break; |
| 3550 } |
| 3551 |
| 3552 case Token::ASSIGN_DIV: |
| 3553 result = ParseRegExpLiteral(true, CHECK_OK); |
| 3554 break; |
| 3555 |
| 3556 case Token::DIV: |
| 3557 result = ParseRegExpLiteral(false, CHECK_OK); |
| 3558 break; |
| 3559 |
| 3560 case Token::LBRACK: |
| 3561 result = ParseArrayLiteral(CHECK_OK); |
| 3562 break; |
| 3563 |
| 3564 case Token::LBRACE: |
| 3565 result = ParseObjectLiteral(CHECK_OK); |
| 3566 break; |
| 3567 |
| 3568 case Token::LPAREN: |
| 3569 Consume(Token::LPAREN); |
| 3570 // Heuristically try to detect immediately called functions before |
| 3571 // seeing the call parentheses. |
| 3572 parenthesized_function_ = (peek() == Token::FUNCTION); |
| 3573 result = ParseExpression(true, CHECK_OK); |
| 3574 Expect(Token::RPAREN, CHECK_OK); |
| 3575 break; |
| 3576 |
| 3577 case Token::MOD: |
| 3578 if (allow_natives_syntax() || extension_ != NULL) { |
| 3579 result = ParseV8Intrinsic(CHECK_OK); |
| 3580 break; |
| 3581 } |
| 3582 // If we're not allowing special syntax we fall-through to the |
| 3583 // default case. |
| 3584 |
| 3585 default: { |
| 3586 Token::Value tok = Next(); |
| 3587 ReportUnexpectedToken(tok); |
| 3588 *ok = false; |
| 3589 return NULL; |
| 3590 } |
| 3591 } |
| 3592 |
| 3593 return result; |
| 3594 } |
| 3595 |
| 3596 |
| 3597 Expression* Parser::ParseArrayLiteral(bool* ok) { |
| 3598 // ArrayLiteral :: |
| 3599 // '[' Expression? (',' Expression?)* ']' |
| 3600 |
| 3601 int pos = peek_position(); |
| 3602 ZoneList<Expression*>* values = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3603 Expect(Token::LBRACK, CHECK_OK); |
| 3604 while (peek() != Token::RBRACK) { |
| 3605 Expression* elem; |
| 3606 if (peek() == Token::COMMA) { |
| 3607 elem = GetLiteralTheHole(peek_position()); |
| 3608 } else { |
| 3609 elem = ParseAssignmentExpression(true, CHECK_OK); |
| 3610 } |
| 3611 values->Add(elem, zone()); |
| 3612 if (peek() != Token::RBRACK) { |
| 3613 Expect(Token::COMMA, CHECK_OK); |
| 3614 } |
| 3615 } |
| 3616 Expect(Token::RBRACK, CHECK_OK); |
| 3617 |
| 3618 // Update the scope information before the pre-parsing bailout. |
| 3619 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3620 |
| 3621 return factory()->NewArrayLiteral(values, literal_index, pos); |
| 3622 } |
| 3623 |
| 3624 |
| 3450 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3625 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
| 3451 if (expression->AsLiteral() != NULL) return true; | 3626 if (expression->AsLiteral() != NULL) return true; |
| 3452 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3627 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
| 3453 return lit != NULL && lit->is_simple(); | 3628 return lit != NULL && lit->is_simple(); |
| 3454 } | 3629 } |
| 3455 | 3630 |
| 3456 | 3631 |
| 3457 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, | 3632 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, |
| 3458 Expression* expression) { | 3633 Expression* expression) { |
| 3459 Factory* factory = isolate->factory(); | 3634 Factory* factory = isolate->factory(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3496 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3671 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3497 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3672 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3498 // )*[','] '}' | 3673 // )*[','] '}' |
| 3499 | 3674 |
| 3500 int pos = peek_position(); | 3675 int pos = peek_position(); |
| 3501 ZoneList<ObjectLiteral::Property*>* properties = | 3676 ZoneList<ObjectLiteral::Property*>* properties = |
| 3502 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | 3677 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); |
| 3503 int number_of_boilerplate_properties = 0; | 3678 int number_of_boilerplate_properties = 0; |
| 3504 bool has_function = false; | 3679 bool has_function = false; |
| 3505 | 3680 |
| 3506 ObjectLiteralChecker checker(this, scope_->language_mode()); | 3681 ObjectLiteralChecker checker(this, top_scope_->language_mode()); |
| 3507 | 3682 |
| 3508 Expect(Token::LBRACE, CHECK_OK); | 3683 Expect(Token::LBRACE, CHECK_OK); |
| 3509 | 3684 |
| 3510 while (peek() != Token::RBRACE) { | 3685 while (peek() != Token::RBRACE) { |
| 3511 if (fni_ != NULL) fni_->Enter(); | 3686 if (fni_ != NULL) fni_->Enter(); |
| 3512 | 3687 |
| 3513 Literal* key = NULL; | 3688 Literal* key = NULL; |
| 3514 Token::Value next = peek(); | 3689 Token::Value next = peek(); |
| 3515 int next_pos = peek_position(); | 3690 int next_pos = peek_position(); |
| 3516 | 3691 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3542 return NULL; | 3717 return NULL; |
| 3543 } | 3718 } |
| 3544 // Validate the property. | 3719 // Validate the property. |
| 3545 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 3720 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 3546 checker.CheckProperty(next, type, CHECK_OK); | 3721 checker.CheckProperty(next, type, CHECK_OK); |
| 3547 Handle<String> name = is_keyword | 3722 Handle<String> name = is_keyword |
| 3548 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) | 3723 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) |
| 3549 : GetSymbol(); | 3724 : GetSymbol(); |
| 3550 FunctionLiteral* value = | 3725 FunctionLiteral* value = |
| 3551 ParseFunctionLiteral(name, | 3726 ParseFunctionLiteral(name, |
| 3552 scanner()->location(), | 3727 scanner().location(), |
| 3553 false, // reserved words are allowed here | 3728 false, // reserved words are allowed here |
| 3554 false, // not a generator | 3729 false, // not a generator |
| 3555 RelocInfo::kNoPosition, | 3730 RelocInfo::kNoPosition, |
| 3556 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3731 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3557 CHECK_OK); | 3732 CHECK_OK); |
| 3558 // Allow any number of parameters for compatibilty with JSC. | 3733 // Allow any number of parameters for compatibilty with JSC. |
| 3559 // Specification only allows zero parameters for get and one for set. | 3734 // Specification only allows zero parameters for get and one for set. |
| 3560 ObjectLiteral::Property* property = | 3735 ObjectLiteral::Property* property = |
| 3561 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | 3736 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 3562 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3737 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3583 uint32_t index; | 3758 uint32_t index; |
| 3584 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3759 if (!string.is_null() && string->AsArrayIndex(&index)) { |
| 3585 key = factory()->NewNumberLiteral(index, next_pos); | 3760 key = factory()->NewNumberLiteral(index, next_pos); |
| 3586 break; | 3761 break; |
| 3587 } | 3762 } |
| 3588 key = factory()->NewLiteral(string, next_pos); | 3763 key = factory()->NewLiteral(string, next_pos); |
| 3589 break; | 3764 break; |
| 3590 } | 3765 } |
| 3591 case Token::NUMBER: { | 3766 case Token::NUMBER: { |
| 3592 Consume(Token::NUMBER); | 3767 Consume(Token::NUMBER); |
| 3593 ASSERT(scanner()->is_literal_ascii()); | 3768 ASSERT(scanner().is_literal_ascii()); |
| 3594 double value = StringToDouble(isolate()->unicode_cache(), | 3769 double value = StringToDouble(isolate()->unicode_cache(), |
| 3595 scanner()->literal_ascii_string(), | 3770 scanner().literal_ascii_string(), |
| 3596 ALLOW_HEX | ALLOW_OCTAL | | 3771 ALLOW_HEX | ALLOW_OCTAL | |
| 3597 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | 3772 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); |
| 3598 key = factory()->NewNumberLiteral(value, next_pos); | 3773 key = factory()->NewNumberLiteral(value, next_pos); |
| 3599 break; | 3774 break; |
| 3600 } | 3775 } |
| 3601 default: | 3776 default: |
| 3602 if (Token::IsKeyword(next)) { | 3777 if (Token::IsKeyword(next)) { |
| 3603 Consume(next); | 3778 Consume(next); |
| 3604 Handle<String> string = GetSymbol(); | 3779 Handle<String> string = GetSymbol(); |
| 3605 key = factory()->NewLiteral(string, next_pos); | 3780 key = factory()->NewLiteral(string, next_pos); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3617 | 3792 |
| 3618 Expect(Token::COLON, CHECK_OK); | 3793 Expect(Token::COLON, CHECK_OK); |
| 3619 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3794 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
| 3620 | 3795 |
| 3621 ObjectLiteral::Property* property = | 3796 ObjectLiteral::Property* property = |
| 3622 factory()->NewObjectLiteralProperty(key, value); | 3797 factory()->NewObjectLiteralProperty(key, value); |
| 3623 | 3798 |
| 3624 // Mark top-level object literals that contain function literals and | 3799 // Mark top-level object literals that contain function literals and |
| 3625 // pretenure the literal so it can be added as a constant function | 3800 // pretenure the literal so it can be added as a constant function |
| 3626 // property. | 3801 // property. |
| 3627 if (scope_->DeclarationScope()->is_global_scope() && | 3802 if (top_scope_->DeclarationScope()->is_global_scope() && |
| 3628 value->AsFunctionLiteral() != NULL) { | 3803 value->AsFunctionLiteral() != NULL) { |
| 3629 has_function = true; | 3804 has_function = true; |
| 3630 value->AsFunctionLiteral()->set_pretenure(); | 3805 value->AsFunctionLiteral()->set_pretenure(); |
| 3631 } | 3806 } |
| 3632 | 3807 |
| 3633 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3808 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
| 3634 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3809 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
| 3635 number_of_boilerplate_properties++; | 3810 number_of_boilerplate_properties++; |
| 3636 } | 3811 } |
| 3637 properties->Add(property, zone()); | 3812 properties->Add(property, zone()); |
| 3638 | 3813 |
| 3639 // TODO(1240767): Consider allowing trailing comma. | 3814 // TODO(1240767): Consider allowing trailing comma. |
| 3640 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3815 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3641 | 3816 |
| 3642 if (fni_ != NULL) { | 3817 if (fni_ != NULL) { |
| 3643 fni_->Infer(); | 3818 fni_->Infer(); |
| 3644 fni_->Leave(); | 3819 fni_->Leave(); |
| 3645 } | 3820 } |
| 3646 } | 3821 } |
| 3647 Expect(Token::RBRACE, CHECK_OK); | 3822 Expect(Token::RBRACE, CHECK_OK); |
| 3648 | 3823 |
| 3649 // Computation of literal_index must happen before pre parse bailout. | 3824 // Computation of literal_index must happen before pre parse bailout. |
| 3650 int literal_index = function_state_->NextMaterializedLiteralIndex(); | 3825 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3651 | 3826 |
| 3652 return factory()->NewObjectLiteral(properties, | 3827 return factory()->NewObjectLiteral(properties, |
| 3653 literal_index, | 3828 literal_index, |
| 3654 number_of_boilerplate_properties, | 3829 number_of_boilerplate_properties, |
| 3655 has_function, | 3830 has_function, |
| 3656 pos); | 3831 pos); |
| 3657 } | 3832 } |
| 3658 | 3833 |
| 3659 | 3834 |
| 3835 Expression* Parser::ParseRegExpLiteral(bool seen_equal, bool* ok) { |
| 3836 int pos = peek_position(); |
| 3837 if (!scanner().ScanRegExpPattern(seen_equal)) { |
| 3838 Next(); |
| 3839 ReportMessage("unterminated_regexp", Vector<const char*>::empty()); |
| 3840 *ok = false; |
| 3841 return NULL; |
| 3842 } |
| 3843 |
| 3844 int literal_index = current_function_state_->NextMaterializedLiteralIndex(); |
| 3845 |
| 3846 Handle<String> js_pattern = NextLiteralString(TENURED); |
| 3847 scanner().ScanRegExpFlags(); |
| 3848 Handle<String> js_flags = NextLiteralString(TENURED); |
| 3849 Next(); |
| 3850 |
| 3851 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); |
| 3852 } |
| 3853 |
| 3854 |
| 3660 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | 3855 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { |
| 3661 // Arguments :: | 3856 // Arguments :: |
| 3662 // '(' (AssignmentExpression)*[','] ')' | 3857 // '(' (AssignmentExpression)*[','] ')' |
| 3663 | 3858 |
| 3664 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | 3859 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); |
| 3665 Expect(Token::LPAREN, CHECK_OK); | 3860 Expect(Token::LPAREN, CHECK_OK); |
| 3666 bool done = (peek() == Token::RPAREN); | 3861 bool done = (peek() == Token::RPAREN); |
| 3667 while (!done) { | 3862 while (!done) { |
| 3668 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | 3863 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); |
| 3669 result->Add(argument, zone()); | 3864 result->Add(argument, zone()); |
| 3670 if (result->length() > Code::kMaxArguments) { | 3865 if (result->length() > Code::kMaxArguments) { |
| 3671 ReportMessageAt(scanner()->location(), "too_many_arguments"); | 3866 ReportMessageAt(scanner().location(), "too_many_arguments", |
| 3867 Vector<const char*>::empty()); |
| 3672 *ok = false; | 3868 *ok = false; |
| 3673 return NULL; | 3869 return NULL; |
| 3674 } | 3870 } |
| 3675 done = (peek() == Token::RPAREN); | 3871 done = (peek() == Token::RPAREN); |
| 3676 if (!done) Expect(Token::COMMA, CHECK_OK); | 3872 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3677 } | 3873 } |
| 3678 Expect(Token::RPAREN, CHECK_OK); | 3874 Expect(Token::RPAREN, CHECK_OK); |
| 3679 return result; | 3875 return result; |
| 3680 } | 3876 } |
| 3681 | 3877 |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3818 // either information available directly, especially not when lazily compiling | 4014 // either information available directly, especially not when lazily compiling |
| 3819 // a function like 'g'. We hence rely on the following invariants: | 4015 // a function like 'g'. We hence rely on the following invariants: |
| 3820 // - (1) is the case iff the innermost scope of the deserialized scope chain | 4016 // - (1) is the case iff the innermost scope of the deserialized scope chain |
| 3821 // under which we compile is _not_ a declaration scope. This holds because | 4017 // under which we compile is _not_ a declaration scope. This holds because |
| 3822 // in all normal cases, function declarations are fully hoisted to a | 4018 // in all normal cases, function declarations are fully hoisted to a |
| 3823 // declaration scope and compiled relative to that. | 4019 // declaration scope and compiled relative to that. |
| 3824 // - (2) is the case iff the current declaration scope is still the original | 4020 // - (2) is the case iff the current declaration scope is still the original |
| 3825 // one relative to the deserialized scope chain. Otherwise we must be | 4021 // one relative to the deserialized scope chain. Otherwise we must be |
| 3826 // compiling a function in an inner declaration scope in the eval, e.g. a | 4022 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 3827 // nested function, and hoisting works normally relative to that. | 4023 // nested function, and hoisting works normally relative to that. |
| 3828 Scope* declaration_scope = scope_->DeclarationScope(); | 4024 Scope* declaration_scope = top_scope_->DeclarationScope(); |
| 3829 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 4025 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 3830 Scope* scope = | 4026 Scope* scope = |
| 3831 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && | 4027 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && |
| 3832 (original_scope_ == original_declaration_scope || | 4028 (original_scope_ == original_declaration_scope || |
| 3833 declaration_scope != original_declaration_scope) | 4029 declaration_scope != original_declaration_scope) |
| 3834 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 4030 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 3835 : NewScope(scope_, FUNCTION_SCOPE); | 4031 : NewScope(top_scope_, FUNCTION_SCOPE); |
| 3836 ZoneList<Statement*>* body = NULL; | 4032 ZoneList<Statement*>* body = NULL; |
| 3837 int materialized_literal_count = -1; | 4033 int materialized_literal_count = -1; |
| 3838 int expected_property_count = -1; | 4034 int expected_property_count = -1; |
| 3839 int handler_count = 0; | 4035 int handler_count = 0; |
| 3840 FunctionLiteral::ParameterFlag duplicate_parameters = | 4036 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3841 FunctionLiteral::kNoDuplicateParameters; | 4037 FunctionLiteral::kNoDuplicateParameters; |
| 3842 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4038 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 3843 ? FunctionLiteral::kIsParenthesized | 4039 ? FunctionLiteral::kIsParenthesized |
| 3844 : FunctionLiteral::kNotParenthesized; | 4040 : FunctionLiteral::kNotParenthesized; |
| 3845 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4041 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| 3846 ? FunctionLiteral::kIsGenerator | 4042 ? FunctionLiteral::kIsGenerator |
| 3847 : FunctionLiteral::kNotGenerator; | 4043 : FunctionLiteral::kNotGenerator; |
| 3848 DeferredFeedbackSlotProcessor* slot_processor; | |
| 3849 AstProperties ast_properties; | 4044 AstProperties ast_properties; |
| 3850 BailoutReason dont_optimize_reason = kNoReason; | 4045 BailoutReason dont_optimize_reason = kNoReason; |
| 3851 // Parse function body. | 4046 // Parse function body. |
| 3852 { FunctionState function_state(&function_state_, &scope_, scope, zone()); | 4047 { FunctionState function_state(this, scope); |
| 3853 scope_->SetScopeName(function_name); | 4048 top_scope_->SetScopeName(function_name); |
| 3854 | 4049 |
| 3855 if (is_generator) { | 4050 if (is_generator) { |
| 3856 // For generators, allocating variables in contexts is currently a win | 4051 // For generators, allocating variables in contexts is currently a win |
| 3857 // because it minimizes the work needed to suspend and resume an | 4052 // because it minimizes the work needed to suspend and resume an |
| 3858 // activation. | 4053 // activation. |
| 3859 scope_->ForceContextAllocation(); | 4054 top_scope_->ForceContextAllocation(); |
| 3860 | 4055 |
| 3861 // Calling a generator returns a generator object. That object is stored | 4056 // Calling a generator returns a generator object. That object is stored |
| 3862 // in a temporary variable, a definition that is used by "yield" | 4057 // in a temporary variable, a definition that is used by "yield" |
| 3863 // expressions. This also marks the FunctionState as a generator. | 4058 // expressions. Presence of a variable for the generator object in the |
| 3864 Variable* temp = scope_->DeclarationScope()->NewTemporary( | 4059 // FunctionState indicates that this function is a generator. |
| 4060 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( |
| 3865 isolate()->factory()->dot_generator_object_string()); | 4061 isolate()->factory()->dot_generator_object_string()); |
| 3866 function_state.set_generator_object_variable(temp); | 4062 function_state.set_generator_object_variable(temp); |
| 3867 } | 4063 } |
| 3868 | 4064 |
| 3869 // FormalParameterList :: | 4065 // FormalParameterList :: |
| 3870 // '(' (Identifier)*[','] ')' | 4066 // '(' (Identifier)*[','] ')' |
| 3871 Expect(Token::LPAREN, CHECK_OK); | 4067 Expect(Token::LPAREN, CHECK_OK); |
| 3872 scope->set_start_position(scanner()->location().beg_pos); | 4068 scope->set_start_position(scanner().location().beg_pos); |
| 3873 | 4069 |
| 3874 // We don't yet know if the function will be strict, so we cannot yet | 4070 // We don't yet know if the function will be strict, so we cannot yet |
| 3875 // produce errors for parameter names or duplicates. However, we remember | 4071 // produce errors for parameter names or duplicates. However, we remember |
| 3876 // the locations of these errors if they occur and produce the errors later. | 4072 // the locations of these errors if they occur and produce the errors later. |
| 3877 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); | 4073 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 3878 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | 4074 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 3879 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 4075 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 3880 | 4076 |
| 3881 bool done = (peek() == Token::RPAREN); | 4077 bool done = (peek() == Token::RPAREN); |
| 3882 while (!done) { | 4078 while (!done) { |
| 3883 bool is_strict_reserved = false; | 4079 bool is_strict_reserved = false; |
| 3884 Handle<String> param_name = | 4080 Handle<String> param_name = |
| 3885 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 4081 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 3886 | 4082 |
| 3887 // Store locations for possible future error reports. | 4083 // Store locations for possible future error reports. |
| 3888 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { | 4084 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 3889 eval_args_error_log = scanner()->location(); | 4085 eval_args_error_log = scanner().location(); |
| 3890 } | 4086 } |
| 3891 if (!reserved_loc.IsValid() && is_strict_reserved) { | 4087 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3892 reserved_loc = scanner()->location(); | 4088 reserved_loc = scanner().location(); |
| 3893 } | 4089 } |
| 3894 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | 4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 3895 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | 4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 3896 dupe_error_loc = scanner()->location(); | 4092 dupe_error_loc = scanner().location(); |
| 3897 } | 4093 } |
| 3898 | 4094 |
| 3899 scope_->DeclareParameter(param_name, VAR); | 4095 top_scope_->DeclareParameter(param_name, VAR); |
| 3900 num_parameters++; | 4096 num_parameters++; |
| 3901 if (num_parameters > Code::kMaxArguments) { | 4097 if (num_parameters > Code::kMaxArguments) { |
| 3902 ReportMessageAt(scanner()->location(), "too_many_parameters"); | 4098 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 4099 Vector<const char*>::empty()); |
| 3903 *ok = false; | 4100 *ok = false; |
| 3904 return NULL; | 4101 return NULL; |
| 3905 } | 4102 } |
| 3906 done = (peek() == Token::RPAREN); | 4103 done = (peek() == Token::RPAREN); |
| 3907 if (!done) Expect(Token::COMMA, CHECK_OK); | 4104 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3908 } | 4105 } |
| 3909 Expect(Token::RPAREN, CHECK_OK); | 4106 Expect(Token::RPAREN, CHECK_OK); |
| 3910 | 4107 |
| 3911 Expect(Token::LBRACE, CHECK_OK); | 4108 Expect(Token::LBRACE, CHECK_OK); |
| 3912 | 4109 |
| 3913 // If we have a named function expression, we add a local variable | 4110 // If we have a named function expression, we add a local variable |
| 3914 // declaration to the body of the function with the name of the | 4111 // declaration to the body of the function with the name of the |
| 3915 // function and let it refer to the function itself (closure). | 4112 // function and let it refer to the function itself (closure). |
| 3916 // NOTE: We create a proxy and resolve it here so that in the | 4113 // NOTE: We create a proxy and resolve it here so that in the |
| 3917 // future we can change the AST to only refer to VariableProxies | 4114 // future we can change the AST to only refer to VariableProxies |
| 3918 // instead of Variables and Proxis as is the case now. | 4115 // instead of Variables and Proxis as is the case now. |
| 3919 Variable* fvar = NULL; | 4116 Variable* fvar = NULL; |
| 3920 Token::Value fvar_init_op = Token::INIT_CONST; | 4117 Token::Value fvar_init_op = Token::INIT_CONST; |
| 3921 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 4118 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3922 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 4119 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; |
| 3923 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 4120 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; |
| 3924 fvar = new(zone()) Variable(scope_, | 4121 fvar = new(zone()) Variable(top_scope_, |
| 3925 function_name, fvar_mode, true /* is valid LHS */, | 4122 function_name, fvar_mode, true /* is valid LHS */, |
| 3926 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 4123 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3927 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 4124 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3928 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 4125 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3929 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 4126 proxy, fvar_mode, top_scope_, RelocInfo::kNoPosition); |
| 3930 scope_->DeclareFunctionVar(fvar_declaration); | 4127 top_scope_->DeclareFunctionVar(fvar_declaration); |
| 3931 } | 4128 } |
| 3932 | 4129 |
| 3933 // Determine if the function can be parsed lazily. Lazy parsing is different | 4130 // Determine whether the function will be lazily compiled. |
| 3934 // from lazy compilation; we need to parse more eagerly than we compile. | 4131 // The heuristics are: |
| 3935 | |
| 3936 // We can only parse lazily if we also compile lazily. The heuristics for | |
| 3937 // lazy compilation are: | |
| 3938 // - It must not have been prohibited by the caller to Parse (some callers | 4132 // - It must not have been prohibited by the caller to Parse (some callers |
| 3939 // need a full AST). | 4133 // need a full AST). |
| 3940 // - The outer scope must allow lazy compilation of inner functions. | 4134 // - The outer scope must allow lazy compilation of inner functions. |
| 3941 // - The function mustn't be a function expression with an open parenthesis | 4135 // - The function mustn't be a function expression with an open parenthesis |
| 3942 // before; we consider that a hint that the function will be called | 4136 // before; we consider that a hint that the function will be called |
| 3943 // immediately, and it would be a waste of time to make it lazily | 4137 // immediately, and it would be a waste of time to make it lazily |
| 3944 // compiled. | 4138 // compiled. |
| 3945 // These are all things we can know at this point, without looking at the | 4139 // These are all things we can know at this point, without looking at the |
| 3946 // function itself. | 4140 // function itself. |
| 3947 | 4141 bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| 3948 // In addition, we need to distinguish between these cases: | 4142 top_scope_->AllowsLazyCompilation() && |
| 3949 // (function foo() { | 4143 !parenthesized_function_); |
| 3950 // bar = function() { return 1; } | |
| 3951 // })(); | |
| 3952 // and | |
| 3953 // (function foo() { | |
| 3954 // var a = 1; | |
| 3955 // bar = function() { return a; } | |
| 3956 // })(); | |
| 3957 | |
| 3958 // Now foo will be parsed eagerly and compiled eagerly (optimization: assume | |
| 3959 // parenthesis before the function means that it will be called | |
| 3960 // immediately). The inner function *must* be parsed eagerly to resolve the | |
| 3961 // possible reference to the variable in foo's scope. However, it's possible | |
| 3962 // that it will be compiled lazily. | |
| 3963 | |
| 3964 // To make this additional case work, both Parser and PreParser implement a | |
| 3965 // logic where only top-level functions will be parsed lazily. | |
| 3966 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
| 3967 scope_->AllowsLazyCompilation() && | |
| 3968 !parenthesized_function_); | |
| 3969 parenthesized_function_ = false; // The bit was set for this function only. | 4144 parenthesized_function_ = false; // The bit was set for this function only. |
| 3970 | 4145 |
| 3971 if (is_lazily_parsed) { | 4146 if (is_lazily_compiled) { |
| 3972 int function_block_pos = position(); | 4147 int function_block_pos = position(); |
| 3973 FunctionEntry entry; | 4148 FunctionEntry entry; |
| 3974 if (pre_parse_data_ != NULL) { | 4149 if (pre_parse_data_ != NULL) { |
| 3975 // If we have pre_parse_data_, we use it to skip parsing the function | 4150 // If we have pre_parse_data_, we use it to skip parsing the function |
| 3976 // body. The preparser data contains the information we need to | 4151 // body. The preparser data contains the information we need to |
| 3977 // construct the lazy function. | 4152 // construct the lazy function. |
| 3978 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 4153 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); |
| 3979 if (entry.is_valid()) { | 4154 if (entry.is_valid()) { |
| 3980 if (entry.end_pos() <= function_block_pos) { | 4155 if (entry.end_pos() <= function_block_pos) { |
| 3981 // End position greater than end of stream is safe, and hard | 4156 // End position greater than end of stream is safe, and hard |
| 3982 // to check. | 4157 // to check. |
| 3983 ReportInvalidPreparseData(function_name, CHECK_OK); | 4158 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 3984 } | 4159 } |
| 3985 scanner()->SeekForward(entry.end_pos() - 1); | 4160 scanner().SeekForward(entry.end_pos() - 1); |
| 3986 | 4161 |
| 3987 scope->set_end_position(entry.end_pos()); | 4162 scope->set_end_position(entry.end_pos()); |
| 3988 Expect(Token::RBRACE, CHECK_OK); | 4163 Expect(Token::RBRACE, CHECK_OK); |
| 3989 isolate()->counters()->total_preparse_skipped()->Increment( | 4164 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3990 scope->end_position() - function_block_pos); | 4165 scope->end_position() - function_block_pos); |
| 3991 materialized_literal_count = entry.literal_count(); | 4166 materialized_literal_count = entry.literal_count(); |
| 3992 expected_property_count = entry.property_count(); | 4167 expected_property_count = entry.property_count(); |
| 3993 scope_->SetLanguageMode(entry.language_mode()); | 4168 top_scope_->SetLanguageMode(entry.language_mode()); |
| 3994 } else { | 4169 } else { |
| 3995 // This case happens when we have preparse data but it doesn't contain | 4170 is_lazily_compiled = false; |
| 3996 // an entry for the function. As a safety net, fall back to eager | |
| 3997 // parsing. It is unclear whether PreParser's laziness analysis can | |
| 3998 // produce different results than the Parser's laziness analysis (see | |
| 3999 // https://codereview.chromium.org/7565003 ). This safety net is | |
| 4000 // guarding against the case where Parser thinks a function should be | |
| 4001 // lazily parsed, but PreParser thinks it should be eagerly parsed -- | |
| 4002 // in that case we fall back to eager parsing in Parser, too. Note | |
| 4003 // that the opposite case is worse: if PreParser thinks a function | |
| 4004 // should be lazily parsed, but Parser thinks it should be eagerly | |
| 4005 // parsed, it will never advance the preparse data beyond that | |
| 4006 // function and all further laziness will fail (all functions will be | |
| 4007 // parsed eagerly). | |
| 4008 is_lazily_parsed = false; | |
| 4009 } | 4171 } |
| 4010 } else { | 4172 } else { |
| 4011 // With no preparser data, we partially parse the function, without | 4173 // With no preparser data, we partially parse the function, without |
| 4012 // building an AST. This gathers the data needed to build a lazy | 4174 // building an AST. This gathers the data needed to build a lazy |
| 4013 // function. | 4175 // function. |
| 4014 SingletonLogger logger; | 4176 SingletonLogger logger; |
| 4015 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); | 4177 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
| 4016 if (result == PreParser::kPreParseStackOverflow) { | 4178 if (result == PreParser::kPreParseStackOverflow) { |
| 4017 // Propagate stack overflow. | 4179 // Propagate stack overflow. |
| 4018 set_stack_overflow(); | 4180 set_stack_overflow(); |
| 4019 *ok = false; | 4181 *ok = false; |
| 4020 return NULL; | 4182 return NULL; |
| 4021 } | 4183 } |
| 4022 if (logger.has_error()) { | 4184 if (logger.has_error()) { |
| 4023 const char* arg = logger.argument_opt(); | 4185 const char* arg = logger.argument_opt(); |
| 4024 Vector<const char*> args; | 4186 Vector<const char*> args; |
| 4025 if (arg != NULL) { | 4187 if (arg != NULL) { |
| 4026 args = Vector<const char*>(&arg, 1); | 4188 args = Vector<const char*>(&arg, 1); |
| 4027 } | 4189 } |
| 4028 ParserTraits::ReportMessageAt( | 4190 ReportMessageAt(Scanner::Location(logger.start(), logger.end()), |
| 4029 Scanner::Location(logger.start(), logger.end()), | 4191 logger.message(), args); |
| 4030 logger.message(), | |
| 4031 args); | |
| 4032 *ok = false; | 4192 *ok = false; |
| 4033 return NULL; | 4193 return NULL; |
| 4034 } | 4194 } |
| 4035 scope->set_end_position(logger.end()); | 4195 scope->set_end_position(logger.end()); |
| 4036 Expect(Token::RBRACE, CHECK_OK); | 4196 Expect(Token::RBRACE, CHECK_OK); |
| 4037 isolate()->counters()->total_preparse_skipped()->Increment( | 4197 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4038 scope->end_position() - function_block_pos); | 4198 scope->end_position() - function_block_pos); |
| 4039 materialized_literal_count = logger.literals(); | 4199 materialized_literal_count = logger.literals(); |
| 4040 expected_property_count = logger.properties(); | 4200 expected_property_count = logger.properties(); |
| 4041 scope_->SetLanguageMode(logger.language_mode()); | 4201 top_scope_->SetLanguageMode(logger.language_mode()); |
| 4042 } | 4202 } |
| 4043 } | 4203 } |
| 4044 | 4204 |
| 4045 if (!is_lazily_parsed) { | 4205 if (!is_lazily_compiled) { |
| 4046 // Everything inside an eagerly parsed function will be parsed eagerly | |
| 4047 // (see comment above). | |
| 4048 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 4206 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 4049 body = new(zone()) ZoneList<Statement*>(8, zone()); | 4207 body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 4050 if (fvar != NULL) { | 4208 if (fvar != NULL) { |
| 4051 VariableProxy* fproxy = scope_->NewUnresolved( | 4209 VariableProxy* fproxy = top_scope_->NewUnresolved( |
| 4052 factory(), function_name, Interface::NewConst()); | 4210 factory(), function_name, Interface::NewConst()); |
| 4053 fproxy->BindTo(fvar); | 4211 fproxy->BindTo(fvar); |
| 4054 body->Add(factory()->NewExpressionStatement( | 4212 body->Add(factory()->NewExpressionStatement( |
| 4055 factory()->NewAssignment(fvar_init_op, | 4213 factory()->NewAssignment(fvar_init_op, |
| 4056 fproxy, | 4214 fproxy, |
| 4057 factory()->NewThisFunction(pos), | 4215 factory()->NewThisFunction(pos), |
| 4058 RelocInfo::kNoPosition), | 4216 RelocInfo::kNoPosition), |
| 4059 RelocInfo::kNoPosition), zone()); | 4217 RelocInfo::kNoPosition), zone()); |
| 4060 } | 4218 } |
| 4061 | 4219 |
| 4062 // For generators, allocate and yield an iterator on function entry. | 4220 // For generators, allocate and yield an iterator on function entry. |
| 4063 if (is_generator) { | 4221 if (is_generator) { |
| 4064 ZoneList<Expression*>* arguments = | 4222 ZoneList<Expression*>* arguments = |
| 4065 new(zone()) ZoneList<Expression*>(0, zone()); | 4223 new(zone()) ZoneList<Expression*>(0, zone()); |
| 4066 CallRuntime* allocation = factory()->NewCallRuntime( | 4224 CallRuntime* allocation = factory()->NewCallRuntime( |
| 4067 isolate()->factory()->empty_string(), | 4225 isolate()->factory()->empty_string(), |
| 4068 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), | 4226 Runtime::FunctionForId(Runtime::kCreateJSGeneratorObject), |
| 4069 arguments, pos); | 4227 arguments, pos); |
| 4070 VariableProxy* init_proxy = factory()->NewVariableProxy( | 4228 VariableProxy* init_proxy = factory()->NewVariableProxy( |
| 4071 function_state_->generator_object_variable()); | 4229 current_function_state_->generator_object_variable()); |
| 4072 Assignment* assignment = factory()->NewAssignment( | 4230 Assignment* assignment = factory()->NewAssignment( |
| 4073 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); | 4231 Token::INIT_VAR, init_proxy, allocation, RelocInfo::kNoPosition); |
| 4074 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4232 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4075 function_state_->generator_object_variable()); | 4233 current_function_state_->generator_object_variable()); |
| 4076 Yield* yield = factory()->NewYield( | 4234 Yield* yield = factory()->NewYield( |
| 4077 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); | 4235 get_proxy, assignment, Yield::INITIAL, RelocInfo::kNoPosition); |
| 4078 body->Add(factory()->NewExpressionStatement( | 4236 body->Add(factory()->NewExpressionStatement( |
| 4079 yield, RelocInfo::kNoPosition), zone()); | 4237 yield, RelocInfo::kNoPosition), zone()); |
| 4080 } | 4238 } |
| 4081 | 4239 |
| 4082 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); | 4240 ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
| 4083 | 4241 |
| 4084 if (is_generator) { | 4242 if (is_generator) { |
| 4085 VariableProxy* get_proxy = factory()->NewVariableProxy( | 4243 VariableProxy* get_proxy = factory()->NewVariableProxy( |
| 4086 function_state_->generator_object_variable()); | 4244 current_function_state_->generator_object_variable()); |
| 4087 Expression *undefined = factory()->NewLiteral( | 4245 Expression *undefined = factory()->NewLiteral( |
| 4088 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); | 4246 isolate()->factory()->undefined_value(), RelocInfo::kNoPosition); |
| 4089 Yield* yield = factory()->NewYield( | 4247 Yield* yield = factory()->NewYield( |
| 4090 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); | 4248 get_proxy, undefined, Yield::FINAL, RelocInfo::kNoPosition); |
| 4091 body->Add(factory()->NewExpressionStatement( | 4249 body->Add(factory()->NewExpressionStatement( |
| 4092 yield, RelocInfo::kNoPosition), zone()); | 4250 yield, RelocInfo::kNoPosition), zone()); |
| 4093 } | 4251 } |
| 4094 | 4252 |
| 4095 materialized_literal_count = function_state.materialized_literal_count(); | 4253 materialized_literal_count = function_state.materialized_literal_count(); |
| 4096 expected_property_count = function_state.expected_property_count(); | 4254 expected_property_count = function_state.expected_property_count(); |
| 4097 handler_count = function_state.handler_count(); | 4255 handler_count = function_state.handler_count(); |
| 4098 | 4256 |
| 4099 Expect(Token::RBRACE, CHECK_OK); | 4257 Expect(Token::RBRACE, CHECK_OK); |
| 4100 scope->set_end_position(scanner()->location().end_pos); | 4258 scope->set_end_position(scanner().location().end_pos); |
| 4101 } | 4259 } |
| 4102 | 4260 |
| 4103 // Validate strict mode. We can do this only after parsing the function, | 4261 // Validate strict mode. We can do this only after parsing the function, |
| 4104 // since the function can declare itself strict. | 4262 // since the function can declare itself strict. |
| 4105 if (!scope_->is_classic_mode()) { | 4263 if (!top_scope_->is_classic_mode()) { |
| 4106 if (IsEvalOrArguments(function_name)) { | 4264 if (IsEvalOrArguments(function_name)) { |
| 4107 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 4265 ReportMessageAt(function_name_location, |
| 4266 "strict_eval_arguments", |
| 4267 Vector<const char*>::empty()); |
| 4108 *ok = false; | 4268 *ok = false; |
| 4109 return NULL; | 4269 return NULL; |
| 4110 } | 4270 } |
| 4111 if (name_is_strict_reserved) { | 4271 if (name_is_strict_reserved) { |
| 4112 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 4272 ReportMessageAt(function_name_location, "unexpected_strict_reserved", |
| 4273 Vector<const char*>::empty()); |
| 4113 *ok = false; | 4274 *ok = false; |
| 4114 return NULL; | 4275 return NULL; |
| 4115 } | 4276 } |
| 4116 if (eval_args_error_log.IsValid()) { | 4277 if (eval_args_error_log.IsValid()) { |
| 4117 ReportMessageAt(eval_args_error_log, "strict_eval_arguments"); | 4278 ReportMessageAt(eval_args_error_log, "strict_eval_arguments", |
| 4279 Vector<const char*>::empty()); |
| 4118 *ok = false; | 4280 *ok = false; |
| 4119 return NULL; | 4281 return NULL; |
| 4120 } | 4282 } |
| 4121 if (dupe_error_loc.IsValid()) { | 4283 if (dupe_error_loc.IsValid()) { |
| 4122 ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | 4284 ReportMessageAt(dupe_error_loc, "strict_param_dupe", |
| 4285 Vector<const char*>::empty()); |
| 4123 *ok = false; | 4286 *ok = false; |
| 4124 return NULL; | 4287 return NULL; |
| 4125 } | 4288 } |
| 4126 if (reserved_loc.IsValid()) { | 4289 if (reserved_loc.IsValid()) { |
| 4127 ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | 4290 ReportMessageAt(reserved_loc, "unexpected_strict_reserved", |
| 4291 Vector<const char*>::empty()); |
| 4128 *ok = false; | 4292 *ok = false; |
| 4129 return NULL; | 4293 return NULL; |
| 4130 } | 4294 } |
| 4131 CheckOctalLiteral(scope->start_position(), | 4295 CheckOctalLiteral(scope->start_position(), |
| 4132 scope->end_position(), | 4296 scope->end_position(), |
| 4133 CHECK_OK); | 4297 CHECK_OK); |
| 4134 } | 4298 } |
| 4135 ast_properties = *factory()->visitor()->ast_properties(); | 4299 ast_properties = *factory()->visitor()->ast_properties(); |
| 4136 slot_processor = factory()->visitor()->slot_processor(); | |
| 4137 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 4300 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| 4138 } | 4301 } |
| 4139 | 4302 |
| 4140 if (is_extended_mode()) { | 4303 if (is_extended_mode()) { |
| 4141 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4304 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4142 } | 4305 } |
| 4143 | 4306 |
| 4144 FunctionLiteral* function_literal = | 4307 FunctionLiteral* function_literal = |
| 4145 factory()->NewFunctionLiteral(function_name, | 4308 factory()->NewFunctionLiteral(function_name, |
| 4146 scope, | 4309 scope, |
| 4147 body, | 4310 body, |
| 4148 materialized_literal_count, | 4311 materialized_literal_count, |
| 4149 expected_property_count, | 4312 expected_property_count, |
| 4150 handler_count, | 4313 handler_count, |
| 4151 num_parameters, | 4314 num_parameters, |
| 4152 duplicate_parameters, | 4315 duplicate_parameters, |
| 4153 function_type, | 4316 function_type, |
| 4154 FunctionLiteral::kIsFunction, | 4317 FunctionLiteral::kIsFunction, |
| 4155 parenthesized, | 4318 parenthesized, |
| 4156 generator, | 4319 generator, |
| 4157 pos); | 4320 pos); |
| 4158 function_literal->set_function_token_position(function_token_pos); | 4321 function_literal->set_function_token_position(function_token_pos); |
| 4159 function_literal->set_ast_properties(&ast_properties); | 4322 function_literal->set_ast_properties(&ast_properties); |
| 4160 function_literal->set_slot_processor(slot_processor); | |
| 4161 function_literal->set_dont_optimize_reason(dont_optimize_reason); | 4323 function_literal->set_dont_optimize_reason(dont_optimize_reason); |
| 4162 | 4324 |
| 4163 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 4325 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
| 4164 return function_literal; | 4326 return function_literal; |
| 4165 } | 4327 } |
| 4166 | 4328 |
| 4167 | 4329 |
| 4168 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( | 4330 PreParser::PreParseResult Parser::LazyParseFunctionLiteral( |
| 4169 SingletonLogger* logger) { | 4331 SingletonLogger* logger) { |
| 4170 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 4332 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
| 4171 ASSERT_EQ(Token::LBRACE, scanner()->current_token()); | 4333 ASSERT_EQ(Token::LBRACE, scanner().current_token()); |
| 4172 | 4334 |
| 4173 if (reusable_preparser_ == NULL) { | 4335 if (reusable_preparser_ == NULL) { |
| 4174 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4336 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
| 4175 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | 4337 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
| 4176 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4338 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4177 reusable_preparser_->set_allow_modules(allow_modules()); | 4339 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4178 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4340 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4179 reusable_preparser_->set_allow_lazy(true); | 4341 reusable_preparser_->set_allow_lazy(true); |
| 4180 reusable_preparser_->set_allow_generators(allow_generators()); | 4342 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4181 reusable_preparser_->set_allow_for_of(allow_for_of()); | 4343 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4182 reusable_preparser_->set_allow_harmony_numeric_literals( | 4344 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4183 allow_harmony_numeric_literals()); | 4345 allow_harmony_numeric_literals()); |
| 4184 } | 4346 } |
| 4185 PreParser::PreParseResult result = | 4347 PreParser::PreParseResult result = |
| 4186 reusable_preparser_->PreParseLazyFunction(scope_->language_mode(), | 4348 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
| 4187 is_generator(), | 4349 is_generator(), |
| 4188 logger); | 4350 logger); |
| 4189 return result; | 4351 return result; |
| 4190 } | 4352 } |
| 4191 | 4353 |
| 4192 | 4354 |
| 4193 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4355 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4194 // CallRuntime :: | 4356 // CallRuntime :: |
| 4195 // '%' Identifier Arguments | 4357 // '%' Identifier Arguments |
| 4196 | 4358 |
| 4197 int pos = peek_position(); | 4359 int pos = peek_position(); |
| 4198 Expect(Token::MOD, CHECK_OK); | 4360 Expect(Token::MOD, CHECK_OK); |
| 4199 // Allow "eval" or "arguments" for backward compatibility. | 4361 // Allow "eval" or "arguments" for backward compatibility. |
| 4200 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); | 4362 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 4201 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4363 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4202 | 4364 |
| 4203 if (extension_ != NULL) { | 4365 if (extension_ != NULL) { |
| 4204 // The extension structures are only accessible while parsing the | 4366 // The extension structures are only accessible while parsing the |
| 4205 // very first time not when reparsing because of lazy compilation. | 4367 // very first time not when reparsing because of lazy compilation. |
| 4206 scope_->DeclarationScope()->ForceEagerCompilation(); | 4368 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4207 } | 4369 } |
| 4208 | 4370 |
| 4209 const Runtime::Function* function = Runtime::FunctionForName(name); | 4371 const Runtime::Function* function = Runtime::FunctionForName(name); |
| 4210 | 4372 |
| 4211 // Check for built-in IS_VAR macro. | 4373 // Check for built-in IS_VAR macro. |
| 4212 if (function != NULL && | 4374 if (function != NULL && |
| 4213 function->intrinsic_type == Runtime::RUNTIME && | 4375 function->intrinsic_type == Runtime::RUNTIME && |
| 4214 function->function_id == Runtime::kIS_VAR) { | 4376 function->function_id == Runtime::kIS_VAR) { |
| 4215 // %IS_VAR(x) evaluates to x if x is a variable, | 4377 // %IS_VAR(x) evaluates to x if x is a variable, |
| 4216 // leads to a parse error otherwise. Could be implemented as an | 4378 // leads to a parse error otherwise. Could be implemented as an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4228 if (function != NULL && | 4390 if (function != NULL && |
| 4229 function->nargs != -1 && | 4391 function->nargs != -1 && |
| 4230 function->nargs != args->length()) { | 4392 function->nargs != args->length()) { |
| 4231 ReportMessage("illegal_access", Vector<const char*>::empty()); | 4393 ReportMessage("illegal_access", Vector<const char*>::empty()); |
| 4232 *ok = false; | 4394 *ok = false; |
| 4233 return NULL; | 4395 return NULL; |
| 4234 } | 4396 } |
| 4235 | 4397 |
| 4236 // Check that the function is defined if it's an inline runtime call. | 4398 // Check that the function is defined if it's an inline runtime call. |
| 4237 if (function == NULL && name->Get(0) == '_') { | 4399 if (function == NULL && name->Get(0) == '_') { |
| 4238 ParserTraits::ReportMessage("not_defined", | 4400 ReportMessage("not_defined", Vector<Handle<String> >(&name, 1)); |
| 4239 Vector<Handle<String> >(&name, 1)); | |
| 4240 *ok = false; | 4401 *ok = false; |
| 4241 return NULL; | 4402 return NULL; |
| 4242 } | 4403 } |
| 4243 | 4404 |
| 4244 // We have a valid intrinsics call or a call to a builtin. | 4405 // We have a valid intrinsics call or a call to a builtin. |
| 4245 return factory()->NewCallRuntime(name, function, args, pos); | 4406 return factory()->NewCallRuntime(name, function, args, pos); |
| 4246 } | 4407 } |
| 4247 | 4408 |
| 4248 | 4409 |
| 4410 bool ParserBase::peek_any_identifier() { |
| 4411 Token::Value next = peek(); |
| 4412 return next == Token::IDENTIFIER || |
| 4413 next == Token::FUTURE_RESERVED_WORD || |
| 4414 next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4415 next == Token::YIELD; |
| 4416 } |
| 4417 |
| 4418 |
| 4419 bool ParserBase::CheckContextualKeyword(Vector<const char> keyword) { |
| 4420 if (peek() == Token::IDENTIFIER && |
| 4421 scanner()->is_next_contextual_keyword(keyword)) { |
| 4422 Consume(Token::IDENTIFIER); |
| 4423 return true; |
| 4424 } |
| 4425 return false; |
| 4426 } |
| 4427 |
| 4428 |
| 4429 void ParserBase::ExpectSemicolon(bool* ok) { |
| 4430 // Check for automatic semicolon insertion according to |
| 4431 // the rules given in ECMA-262, section 7.9, page 21. |
| 4432 Token::Value tok = peek(); |
| 4433 if (tok == Token::SEMICOLON) { |
| 4434 Next(); |
| 4435 return; |
| 4436 } |
| 4437 if (scanner()->HasAnyLineTerminatorBeforeNext() || |
| 4438 tok == Token::RBRACE || |
| 4439 tok == Token::EOS) { |
| 4440 return; |
| 4441 } |
| 4442 Expect(Token::SEMICOLON, ok); |
| 4443 } |
| 4444 |
| 4445 |
| 4446 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 4447 Expect(Token::IDENTIFIER, ok); |
| 4448 if (!*ok) return; |
| 4449 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 4450 ReportUnexpectedToken(scanner()->current_token()); |
| 4451 *ok = false; |
| 4452 } |
| 4453 } |
| 4454 |
| 4455 |
| 4456 void ParserBase::ReportUnexpectedToken(Token::Value token) { |
| 4457 // We don't report stack overflows here, to avoid increasing the |
| 4458 // stack depth even further. Instead we report it after parsing is |
| 4459 // over, in ParseProgram. |
| 4460 if (token == Token::ILLEGAL && stack_overflow()) { |
| 4461 return; |
| 4462 } |
| 4463 Scanner::Location source_location = scanner()->location(); |
| 4464 |
| 4465 // Four of the tokens are treated specially |
| 4466 switch (token) { |
| 4467 case Token::EOS: |
| 4468 return ReportMessageAt(source_location, "unexpected_eos"); |
| 4469 case Token::NUMBER: |
| 4470 return ReportMessageAt(source_location, "unexpected_token_number"); |
| 4471 case Token::STRING: |
| 4472 return ReportMessageAt(source_location, "unexpected_token_string"); |
| 4473 case Token::IDENTIFIER: |
| 4474 return ReportMessageAt(source_location, |
| 4475 "unexpected_token_identifier"); |
| 4476 case Token::FUTURE_RESERVED_WORD: |
| 4477 return ReportMessageAt(source_location, "unexpected_reserved"); |
| 4478 case Token::YIELD: |
| 4479 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 4480 return ReportMessageAt(source_location, |
| 4481 is_classic_mode() ? "unexpected_token_identifier" |
| 4482 : "unexpected_strict_reserved"); |
| 4483 default: |
| 4484 const char* name = Token::String(token); |
| 4485 ASSERT(name != NULL); |
| 4486 ReportMessageAt( |
| 4487 source_location, "unexpected_token", Vector<const char*>(&name, 1)); |
| 4488 } |
| 4489 } |
| 4490 |
| 4491 |
| 4249 Literal* Parser::GetLiteralUndefined(int position) { | 4492 Literal* Parser::GetLiteralUndefined(int position) { |
| 4250 return factory()->NewLiteral( | 4493 return factory()->NewLiteral( |
| 4251 isolate()->factory()->undefined_value(), position); | 4494 isolate()->factory()->undefined_value(), position); |
| 4252 } | 4495 } |
| 4253 | 4496 |
| 4254 | 4497 |
| 4498 Literal* Parser::GetLiteralTheHole(int position) { |
| 4499 return factory()->NewLiteral( |
| 4500 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4501 } |
| 4502 |
| 4503 |
| 4504 // Parses an identifier that is valid for the current scope, in particular it |
| 4505 // fails on strict mode future reserved keywords in a strict scope. If |
| 4506 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 4507 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 4508 // "var foo = eval;"). |
| 4509 Handle<String> Parser::ParseIdentifier( |
| 4510 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 4511 bool* ok) { |
| 4512 Token::Value next = Next(); |
| 4513 if (next == Token::IDENTIFIER) { |
| 4514 Handle<String> name = GetSymbol(); |
| 4515 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
| 4516 !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { |
| 4517 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4518 *ok = false; |
| 4519 } |
| 4520 return name; |
| 4521 } else if (top_scope_->is_classic_mode() && |
| 4522 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4523 (next == Token::YIELD && !is_generator()))) { |
| 4524 return GetSymbol(); |
| 4525 } else { |
| 4526 ReportUnexpectedToken(next); |
| 4527 *ok = false; |
| 4528 return Handle<String>(); |
| 4529 } |
| 4530 } |
| 4531 |
| 4532 |
| 4533 // Parses and identifier or a strict mode future reserved word, and indicate |
| 4534 // whether it is strict mode future reserved. |
| 4535 Handle<String> Parser::ParseIdentifierOrStrictReservedWord( |
| 4536 bool* is_strict_reserved, bool* ok) { |
| 4537 Token::Value next = Next(); |
| 4538 if (next == Token::IDENTIFIER) { |
| 4539 *is_strict_reserved = false; |
| 4540 } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4541 (next == Token::YIELD && !is_generator())) { |
| 4542 *is_strict_reserved = true; |
| 4543 } else { |
| 4544 ReportUnexpectedToken(next); |
| 4545 *ok = false; |
| 4546 return Handle<String>(); |
| 4547 } |
| 4548 return GetSymbol(); |
| 4549 } |
| 4550 |
| 4551 |
| 4552 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
| 4553 Token::Value next = Next(); |
| 4554 if (next != Token::IDENTIFIER && |
| 4555 next != Token::FUTURE_RESERVED_WORD && |
| 4556 next != Token::FUTURE_STRICT_RESERVED_WORD && |
| 4557 !Token::IsKeyword(next)) { |
| 4558 ReportUnexpectedToken(next); |
| 4559 *ok = false; |
| 4560 return Handle<String>(); |
| 4561 } |
| 4562 return GetSymbol(); |
| 4563 } |
| 4564 |
| 4565 |
| 4255 void Parser::MarkAsLValue(Expression* expression) { | 4566 void Parser::MarkAsLValue(Expression* expression) { |
| 4256 VariableProxy* proxy = expression != NULL | 4567 VariableProxy* proxy = expression != NULL |
| 4257 ? expression->AsVariableProxy() | 4568 ? expression->AsVariableProxy() |
| 4258 : NULL; | 4569 : NULL; |
| 4259 | 4570 |
| 4260 if (proxy != NULL) proxy->MarkAsLValue(); | 4571 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4261 } | 4572 } |
| 4262 | 4573 |
| 4263 | 4574 |
| 4264 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4575 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 4265 // in strict mode. | 4576 // in strict mode. |
| 4266 void Parser::CheckStrictModeLValue(Expression* expression, | 4577 void Parser::CheckStrictModeLValue(Expression* expression, |
| 4267 bool* ok) { | 4578 bool* ok) { |
| 4268 ASSERT(!scope_->is_classic_mode()); | 4579 ASSERT(!top_scope_->is_classic_mode()); |
| 4269 VariableProxy* lhs = expression != NULL | 4580 VariableProxy* lhs = expression != NULL |
| 4270 ? expression->AsVariableProxy() | 4581 ? expression->AsVariableProxy() |
| 4271 : NULL; | 4582 : NULL; |
| 4272 | 4583 |
| 4273 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4584 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4274 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | 4585 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4275 *ok = false; | 4586 *ok = false; |
| 4276 } | 4587 } |
| 4277 } | 4588 } |
| 4278 | 4589 |
| 4279 | 4590 |
| 4591 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 4592 // If so, reports an error. Only called for strict mode. |
| 4593 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4594 Scanner::Location octal = scanner()->octal_position(); |
| 4595 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| 4596 ReportMessageAt(octal, "strict_octal_literal"); |
| 4597 scanner()->clear_octal_position(); |
| 4598 *ok = false; |
| 4599 } |
| 4600 } |
| 4601 |
| 4602 |
| 4280 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4603 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4281 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4604 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4282 if (decl != NULL) { | 4605 if (decl != NULL) { |
| 4283 // In harmony mode we treat conflicting variable bindinds as early | 4606 // In harmony mode we treat conflicting variable bindinds as early |
| 4284 // errors. See ES5 16 for a definition of early errors. | 4607 // errors. See ES5 16 for a definition of early errors. |
| 4285 Handle<String> name = decl->proxy()->name(); | 4608 Handle<String> name = decl->proxy()->name(); |
| 4286 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4609 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4287 const char* elms[2] = { "Variable", c_string.get() }; | 4610 const char* elms[2] = { "Variable", c_string.get() }; |
| 4288 Vector<const char*> args(elms, 2); | 4611 Vector<const char*> args(elms, 2); |
| 4289 int position = decl->proxy()->position(); | 4612 int position = decl->proxy()->position(); |
| 4290 Scanner::Location location = position == RelocInfo::kNoPosition | 4613 Scanner::Location location = position == RelocInfo::kNoPosition |
| 4291 ? Scanner::Location::invalid() | 4614 ? Scanner::Location::invalid() |
| 4292 : Scanner::Location(position, position + 1); | 4615 : Scanner::Location(position, position + 1); |
| 4293 ParserTraits::ReportMessageAt(location, "redeclaration", args); | 4616 ReportMessageAt(location, "redeclaration", args); |
| 4294 *ok = false; | 4617 *ok = false; |
| 4295 } | 4618 } |
| 4296 } | 4619 } |
| 4297 | 4620 |
| 4298 | 4621 |
| 4622 // This function reads an identifier name and determines whether or not it |
| 4623 // is 'get' or 'set'. |
| 4624 Handle<String> Parser::ParseIdentifierNameOrGetOrSet(bool* is_get, |
| 4625 bool* is_set, |
| 4626 bool* ok) { |
| 4627 Handle<String> result = ParseIdentifierName(ok); |
| 4628 if (!*ok) return Handle<String>(); |
| 4629 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { |
| 4630 const char* token = scanner().literal_ascii_string().start(); |
| 4631 *is_get = strncmp(token, "get", 3) == 0; |
| 4632 *is_set = !*is_get && strncmp(token, "set", 3) == 0; |
| 4633 } |
| 4634 return result; |
| 4635 } |
| 4636 |
| 4637 |
| 4299 // ---------------------------------------------------------------------------- | 4638 // ---------------------------------------------------------------------------- |
| 4300 // Parser support | 4639 // Parser support |
| 4301 | 4640 |
| 4302 | 4641 |
| 4303 bool Parser::TargetStackContainsLabel(Handle<String> label) { | 4642 bool Parser::TargetStackContainsLabel(Handle<String> label) { |
| 4304 for (Target* t = target_stack_; t != NULL; t = t->previous()) { | 4643 for (Target* t = target_stack_; t != NULL; t = t->previous()) { |
| 4305 BreakableStatement* stat = t->node()->AsBreakableStatement(); | 4644 BreakableStatement* stat = t->node()->AsBreakableStatement(); |
| 4306 if (stat != NULL && ContainsLabel(stat->labels(), label)) | 4645 if (stat != NULL && ContainsLabel(stat->labels(), label)) |
| 4307 return true; | 4646 return true; |
| 4308 } | 4647 } |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5337 } else { | 5676 } else { |
| 5338 result = ParseProgram(); | 5677 result = ParseProgram(); |
| 5339 } | 5678 } |
| 5340 } else { | 5679 } else { |
| 5341 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 5680 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); |
| 5342 set_pre_parse_data(pre_parse_data); | 5681 set_pre_parse_data(pre_parse_data); |
| 5343 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 5682 if (pre_parse_data != NULL && pre_parse_data->has_error()) { |
| 5344 Scanner::Location loc = pre_parse_data->MessageLocation(); | 5683 Scanner::Location loc = pre_parse_data->MessageLocation(); |
| 5345 const char* message = pre_parse_data->BuildMessage(); | 5684 const char* message = pre_parse_data->BuildMessage(); |
| 5346 Vector<const char*> args = pre_parse_data->BuildArgs(); | 5685 Vector<const char*> args = pre_parse_data->BuildArgs(); |
| 5347 ParserTraits::ReportMessageAt(loc, message, args); | 5686 ReportMessageAt(loc, message, args); |
| 5348 DeleteArray(message); | 5687 DeleteArray(message); |
| 5349 for (int i = 0; i < args.length(); i++) { | 5688 for (int i = 0; i < args.length(); i++) { |
| 5350 DeleteArray(args[i]); | 5689 DeleteArray(args[i]); |
| 5351 } | 5690 } |
| 5352 DeleteArray(args.start()); | 5691 DeleteArray(args.start()); |
| 5353 ASSERT(info()->isolate()->has_pending_exception()); | 5692 ASSERT(info()->isolate()->has_pending_exception()); |
| 5354 } else { | 5693 } else { |
| 5355 result = ParseProgram(); | 5694 result = ParseProgram(); |
| 5356 } | 5695 } |
| 5357 } | 5696 } |
| 5358 info()->SetFunction(result); | 5697 info()->SetFunction(result); |
| 5359 return (result != NULL); | 5698 return (result != NULL); |
| 5360 } | 5699 } |
| 5361 | 5700 |
| 5362 } } // namespace v8::internal | 5701 } } // namespace v8::internal |
| OLD | NEW |