| 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 15 matching lines...) Expand all Loading... |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "ast.h" | 31 #include "ast.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "char-predicates-inl.h" | 33 #include "char-predicates-inl.h" |
| 34 #include "codegen.h" | 34 #include "codegen.h" |
| 35 #include "compiler.h" | 35 #include "compiler.h" |
| 36 #include "func-name-inferrer.h" | |
| 37 #include "messages.h" | 36 #include "messages.h" |
| 38 #include "parser.h" | 37 #include "parser.h" |
| 39 #include "platform.h" | 38 #include "platform.h" |
| 40 #include "preparser.h" | 39 #include "preparser.h" |
| 41 #include "runtime.h" | 40 #include "runtime.h" |
| 42 #include "scanner-character-streams.h" | 41 #include "scanner-character-streams.h" |
| 43 #include "scopeinfo.h" | 42 #include "scopeinfo.h" |
| 44 #include "string-stream.h" | 43 #include "string-stream.h" |
| 45 | 44 |
| 46 namespace v8 { | 45 namespace v8 { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 } | 205 } |
| 207 | 206 |
| 208 | 207 |
| 209 Handle<String> Parser::LookupSymbol(int symbol_id) { | 208 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| 210 // If there is no preparser symbol data, a negative number will be passed. In | 209 // If there is no preparser symbol data, a negative number will be passed. In |
| 211 // that case, we'll just read the literal from Scanner. This also guards | 210 // that case, we'll just read the literal from Scanner. This also guards |
| 212 // against corrupt preparse data where the symbol id is larger than the symbol | 211 // against corrupt preparse data where the symbol id is larger than the symbol |
| 213 // count. | 212 // count. |
| 214 if (symbol_id < 0 || | 213 if (symbol_id < 0 || |
| 215 (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) { | 214 (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) { |
| 216 if (scanner()->is_literal_ascii()) { | 215 return scanner()->AllocateInternalizedString(isolate_); |
| 217 return isolate()->factory()->InternalizeOneByteString( | |
| 218 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); | |
| 219 } else { | |
| 220 return isolate()->factory()->InternalizeTwoByteString( | |
| 221 scanner()->literal_utf16_string()); | |
| 222 } | |
| 223 } | 216 } |
| 224 return LookupCachedSymbol(symbol_id); | 217 return LookupCachedSymbol(symbol_id); |
| 225 } | 218 } |
| 226 | 219 |
| 227 | 220 |
| 228 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { | 221 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { |
| 229 // Make sure the cache is large enough to hold the symbol identifier. | 222 // Make sure the cache is large enough to hold the symbol identifier. |
| 230 if (symbol_cache_.length() <= symbol_id) { | 223 if (symbol_cache_.length() <= symbol_id) { |
| 231 // Increase length to index + 1. | 224 // Increase length to index + 1. |
| 232 symbol_cache_.AddBlock(Handle<String>::null(), | 225 symbol_cache_.AddBlock(Handle<String>::null(), |
| 233 symbol_id + 1 - symbol_cache_.length(), zone()); | 226 symbol_id + 1 - symbol_cache_.length(), zone()); |
| 234 } | 227 } |
| 235 Handle<String> result = symbol_cache_.at(symbol_id); | 228 Handle<String> result = symbol_cache_.at(symbol_id); |
| 236 if (result.is_null()) { | 229 if (result.is_null()) { |
| 237 if (scanner()->is_literal_ascii()) { | 230 result = scanner()->AllocateInternalizedString(isolate_); |
| 238 result = isolate()->factory()->InternalizeOneByteString( | |
| 239 Vector<const uint8_t>::cast(scanner()->literal_ascii_string())); | |
| 240 } else { | |
| 241 result = isolate()->factory()->InternalizeTwoByteString( | |
| 242 scanner()->literal_utf16_string()); | |
| 243 } | |
| 244 symbol_cache_.at(symbol_id) = result; | 231 symbol_cache_.at(symbol_id) = result; |
| 245 return result; | 232 return result; |
| 246 } | 233 } |
| 247 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); | 234 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); |
| 248 return result; | 235 return result; |
| 249 } | 236 } |
| 250 | 237 |
| 251 | 238 |
| 252 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 239 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 253 // The current pre-data entry must be a FunctionEntry with the given | 240 // The current pre-data entry must be a FunctionEntry with the given |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 // Implementation of Parser | 430 // Implementation of Parser |
| 444 | 431 |
| 445 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 432 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 446 return identifier.is_identical_to( | 433 return identifier.is_identical_to( |
| 447 parser_->isolate()->factory()->eval_string()) || | 434 parser_->isolate()->factory()->eval_string()) || |
| 448 identifier.is_identical_to( | 435 identifier.is_identical_to( |
| 449 parser_->isolate()->factory()->arguments_string()); | 436 parser_->isolate()->factory()->arguments_string()); |
| 450 } | 437 } |
| 451 | 438 |
| 452 | 439 |
| 440 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 441 ASSERT(expression != NULL); |
| 442 Property* property = expression->AsProperty(); |
| 443 return property != NULL && |
| 444 property->obj()->AsVariableProxy() != NULL && |
| 445 property->obj()->AsVariableProxy()->is_this(); |
| 446 } |
| 447 |
| 448 |
| 449 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 450 Expression* right) { |
| 451 ASSERT(left != NULL); |
| 452 if (left->AsProperty() != NULL && |
| 453 right->AsFunctionLiteral() != NULL) { |
| 454 right->AsFunctionLiteral()->set_pretenure(); |
| 455 } |
| 456 } |
| 457 |
| 458 |
| 459 Expression* ParserTraits::ValidateAssignmentLeftHandSide( |
| 460 Expression* expression) const { |
| 461 ASSERT(expression != NULL); |
| 462 if (!expression->IsValidLeftHandSide()) { |
| 463 Handle<String> message = |
| 464 parser_->isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 465 expression = parser_->NewThrowReferenceError(message); |
| 466 } |
| 467 return expression; |
| 468 } |
| 469 |
| 470 |
| 471 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 472 VariableProxy* proxy = expression != NULL |
| 473 ? expression->AsVariableProxy() |
| 474 : NULL; |
| 475 if (proxy != NULL) proxy->MarkAsLValue(); |
| 476 return expression; |
| 477 } |
| 478 |
| 479 |
| 480 void ParserTraits::CheckStrictModeLValue(Expression* expression, |
| 481 bool* ok) { |
| 482 VariableProxy* lhs = expression != NULL |
| 483 ? expression->AsVariableProxy() |
| 484 : NULL; |
| 485 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 486 parser_->ReportMessage("strict_eval_arguments", |
| 487 Vector<const char*>::empty()); |
| 488 *ok = false; |
| 489 } |
| 490 } |
| 491 |
| 492 |
| 453 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 493 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 454 const char* message, | 494 const char* message, |
| 455 Vector<const char*> args) { | 495 Vector<const char*> args) { |
| 496 if (parser_->stack_overflow()) { |
| 497 // Suppress the error message (syntax error or such) in the presence of a |
| 498 // stack overflow. The isolate allows only one pending exception at at time |
| 499 // and we want to report the stack overflow later. |
| 500 return; |
| 501 } |
| 456 MessageLocation location(parser_->script_, | 502 MessageLocation location(parser_->script_, |
| 457 source_location.beg_pos, | 503 source_location.beg_pos, |
| 458 source_location.end_pos); | 504 source_location.end_pos); |
| 459 Factory* factory = parser_->isolate()->factory(); | 505 Factory* factory = parser_->isolate()->factory(); |
| 460 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 506 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 461 for (int i = 0; i < args.length(); i++) { | 507 for (int i = 0; i < args.length(); i++) { |
| 462 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); | 508 Handle<String> arg_string = factory->NewStringFromUtf8(CStrVector(args[i])); |
| 463 elements->set(i, *arg_string); | 509 elements->set(i, *arg_string); |
| 464 } | 510 } |
| 465 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 511 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 466 Handle<Object> result = factory->NewSyntaxError(message, array); | 512 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 467 parser_->isolate()->Throw(*result, &location); | 513 parser_->isolate()->Throw(*result, &location); |
| 468 } | 514 } |
| 469 | 515 |
| 470 | 516 |
| 471 void ParserTraits::ReportMessage(const char* message, | 517 void ParserTraits::ReportMessage(const char* message, |
| 472 Vector<Handle<String> > args) { | 518 Vector<Handle<String> > args) { |
| 473 Scanner::Location source_location = parser_->scanner()->location(); | 519 Scanner::Location source_location = parser_->scanner()->location(); |
| 474 ReportMessageAt(source_location, message, args); | 520 ReportMessageAt(source_location, message, args); |
| 475 } | 521 } |
| 476 | 522 |
| 477 | 523 |
| 478 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 524 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 479 const char* message, | 525 const char* message, |
| 480 Vector<Handle<String> > args) { | 526 Vector<Handle<String> > args) { |
| 527 if (parser_->stack_overflow()) { |
| 528 // Suppress the error message (syntax error or such) in the presence of a |
| 529 // stack overflow. The isolate allows only one pending exception at at time |
| 530 // and we want to report the stack overflow later. |
| 531 return; |
| 532 } |
| 481 MessageLocation location(parser_->script_, | 533 MessageLocation location(parser_->script_, |
| 482 source_location.beg_pos, | 534 source_location.beg_pos, |
| 483 source_location.end_pos); | 535 source_location.end_pos); |
| 484 Factory* factory = parser_->isolate()->factory(); | 536 Factory* factory = parser_->isolate()->factory(); |
| 485 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 537 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 486 for (int i = 0; i < args.length(); i++) { | 538 for (int i = 0; i < args.length(); i++) { |
| 487 elements->set(i, *args[i]); | 539 elements->set(i, *args[i]); |
| 488 } | 540 } |
| 489 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 541 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 490 Handle<Object> result = factory->NewSyntaxError(message, array); | 542 Handle<Object> result = factory->NewSyntaxError(message, array); |
| 491 parser_->isolate()->Throw(*result, &location); | 543 parser_->isolate()->Throw(*result, &location); |
| 492 } | 544 } |
| 493 | 545 |
| 494 | 546 |
| 495 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 547 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
| 496 int symbol_id = -1; | 548 int symbol_id = -1; |
| 497 if (parser_->pre_parse_data() != NULL) { | 549 if (parser_->pre_parse_data() != NULL) { |
| 498 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | 550 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); |
| 499 } | 551 } |
| 500 return parser_->LookupSymbol(symbol_id); | 552 return parser_->LookupSymbol(symbol_id); |
| 501 } | 553 } |
| 502 | 554 |
| 503 | 555 |
| 504 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 556 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
| 505 PretenureFlag tenured) { | 557 PretenureFlag tenured) { |
| 506 if (scanner->is_next_literal_ascii()) { | 558 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
| 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 } | 559 } |
| 514 | 560 |
| 515 | 561 |
| 516 Expression* ParserTraits::ThisExpression( | 562 Expression* ParserTraits::ThisExpression( |
| 517 Scope* scope, | 563 Scope* scope, |
| 518 AstNodeFactory<AstConstructionVisitor>* factory) { | 564 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 519 return factory->NewVariableProxy(scope->receiver()); | 565 return factory->NewVariableProxy(scope->receiver()); |
| 520 } | 566 } |
| 521 | 567 |
| 522 | 568 |
| 523 Expression* ParserTraits::ExpressionFromLiteral( | 569 Literal* ParserTraits::ExpressionFromLiteral( |
| 524 Token::Value token, int pos, | 570 Token::Value token, int pos, |
| 525 Scanner* scanner, | 571 Scanner* scanner, |
| 526 AstNodeFactory<AstConstructionVisitor>* factory) { | 572 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 527 Factory* isolate_factory = parser_->isolate()->factory(); | 573 Factory* isolate_factory = parser_->isolate()->factory(); |
| 528 switch (token) { | 574 switch (token) { |
| 529 case Token::NULL_LITERAL: | 575 case Token::NULL_LITERAL: |
| 530 return factory->NewLiteral(isolate_factory->null_value(), pos); | 576 return factory->NewLiteral(isolate_factory->null_value(), pos); |
| 531 case Token::TRUE_LITERAL: | 577 case Token::TRUE_LITERAL: |
| 532 return factory->NewLiteral(isolate_factory->true_value(), pos); | 578 return factory->NewLiteral(isolate_factory->true_value(), pos); |
| 533 case Token::FALSE_LITERAL: | 579 case Token::FALSE_LITERAL: |
| 534 return factory->NewLiteral(isolate_factory->false_value(), pos); | 580 return factory->NewLiteral(isolate_factory->false_value(), pos); |
| 535 case Token::NUMBER: { | 581 case Token::NUMBER: { |
| 536 ASSERT(scanner->is_literal_ascii()); | 582 double value = scanner->DoubleValue(); |
| 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); | 583 return factory->NewNumberLiteral(value, pos); |
| 542 } | 584 } |
| 543 default: | 585 default: |
| 544 ASSERT(false); | 586 ASSERT(false); |
| 545 } | 587 } |
| 546 return NULL; | 588 return NULL; |
| 547 } | 589 } |
| 548 | 590 |
| 549 | 591 |
| 550 Expression* ParserTraits::ExpressionFromIdentifier( | 592 Expression* ParserTraits::ExpressionFromIdentifier( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 570 } | 612 } |
| 571 | 613 |
| 572 | 614 |
| 573 Literal* ParserTraits::GetLiteralTheHole( | 615 Literal* ParserTraits::GetLiteralTheHole( |
| 574 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 616 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 575 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 617 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| 576 RelocInfo::kNoPosition); | 618 RelocInfo::kNoPosition); |
| 577 } | 619 } |
| 578 | 620 |
| 579 | 621 |
| 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) { | 622 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 591 return parser_->ParseV8Intrinsic(ok); | 623 return parser_->ParseV8Intrinsic(ok); |
| 592 } | 624 } |
| 593 | 625 |
| 594 | 626 |
| 627 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| 628 Handle<String> name, |
| 629 Scanner::Location function_name_location, |
| 630 bool name_is_strict_reserved, |
| 631 bool is_generator, |
| 632 int function_token_position, |
| 633 FunctionLiteral::FunctionType type, |
| 634 bool* ok) { |
| 635 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 636 name_is_strict_reserved, is_generator, |
| 637 function_token_position, type, ok); |
| 638 } |
| 639 |
| 640 |
| 641 Expression* ParserTraits::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 642 return parser_->ParseConditionalExpression(accept_IN, ok); |
| 643 } |
| 644 |
| 645 |
| 595 Parser::Parser(CompilationInfo* info) | 646 Parser::Parser(CompilationInfo* info) |
| 596 : ParserBase<ParserTraits>(&scanner_, | 647 : ParserBase<ParserTraits>(&scanner_, |
| 597 info->isolate()->stack_guard()->real_climit(), | 648 info->isolate()->stack_guard()->real_climit(), |
| 598 info->extension(), | 649 info->extension(), |
| 599 info->zone(), | 650 info->zone(), |
| 600 this), | 651 this), |
| 601 isolate_(info->isolate()), | 652 isolate_(info->isolate()), |
| 602 symbol_cache_(0, info->zone()), | 653 symbol_cache_(0, info->zone()), |
| 603 script_(info->script()), | 654 script_(info->script()), |
| 604 scanner_(isolate_->unicode_cache()), | 655 scanner_(isolate_->unicode_cache()), |
| 605 reusable_preparser_(NULL), | 656 reusable_preparser_(NULL), |
| 606 original_scope_(NULL), | 657 original_scope_(NULL), |
| 607 target_stack_(NULL), | 658 target_stack_(NULL), |
| 608 pre_parse_data_(NULL), | 659 pre_parse_data_(NULL), |
| 609 fni_(NULL), | |
| 610 info_(info) { | 660 info_(info) { |
| 611 ASSERT(!script_.is_null()); | 661 ASSERT(!script_.is_null()); |
| 612 isolate_->set_ast_node_id(0); | 662 isolate_->set_ast_node_id(0); |
| 613 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 663 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 614 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 664 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 615 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 665 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 616 set_allow_lazy(false); // Must be explicitly enabled. | 666 set_allow_lazy(false); // Must be explicitly enabled. |
| 617 set_allow_generators(FLAG_harmony_generators); | 667 set_allow_generators(FLAG_harmony_generators); |
| 618 set_allow_for_of(FLAG_harmony_iteration); | 668 set_allow_for_of(FLAG_harmony_iteration); |
| 619 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 669 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 Handle<String> no_name = isolate()->factory()->empty_string(); | 725 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 676 | 726 |
| 677 FunctionLiteral* result = NULL; | 727 FunctionLiteral* result = NULL; |
| 678 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 728 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 679 info->SetGlobalScope(scope); | 729 info->SetGlobalScope(scope); |
| 680 if (!info->context().is_null()) { | 730 if (!info->context().is_null()) { |
| 681 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 731 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 682 } | 732 } |
| 683 original_scope_ = scope; | 733 original_scope_ = scope; |
| 684 if (info->is_eval()) { | 734 if (info->is_eval()) { |
| 685 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 735 if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
| 686 scope = NewScope(scope, EVAL_SCOPE); | 736 scope = NewScope(scope, EVAL_SCOPE); |
| 687 } | 737 } |
| 688 } else if (info->is_global()) { | 738 } else if (info->is_global()) { |
| 689 scope = NewScope(scope, GLOBAL_SCOPE); | 739 scope = NewScope(scope, GLOBAL_SCOPE); |
| 690 } | 740 } |
| 691 scope->set_start_position(0); | 741 scope->set_start_position(0); |
| 692 scope->set_end_position(source->length()); | 742 scope->set_end_position(source->length()); |
| 693 | 743 |
| 694 // Compute the parsing mode. | 744 // Compute the parsing mode. |
| 695 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; | 745 Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
| 696 if (allow_natives_syntax() || | 746 if (allow_natives_syntax() || |
| 697 extension_ != NULL || | 747 extension_ != NULL || |
| 698 scope->is_eval_scope()) { | 748 scope->is_eval_scope()) { |
| 699 mode = PARSE_EAGERLY; | 749 mode = PARSE_EAGERLY; |
| 700 } | 750 } |
| 701 ParsingModeScope parsing_mode(this, mode); | 751 ParsingModeScope parsing_mode(this, mode); |
| 702 | 752 |
| 703 // Enters 'scope'. | 753 // Enters 'scope'. |
| 704 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 754 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 705 | 755 |
| 706 scope_->SetLanguageMode(info->language_mode()); | 756 scope_->SetStrictMode(info->strict_mode()); |
| 707 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 757 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 708 bool ok = true; | 758 bool ok = true; |
| 709 int beg_pos = scanner()->location().beg_pos; | 759 int beg_pos = scanner()->location().beg_pos; |
| 710 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 760 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 711 if (ok && !scope_->is_classic_mode()) { | 761 if (ok && strict_mode() == STRICT) { |
| 712 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 762 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 713 } | 763 } |
| 714 | 764 |
| 715 if (ok && is_extended_mode()) { | 765 if (ok && FLAG_harmony_scoping && strict_mode() == STRICT) { |
| 716 CheckConflictingVarDeclarations(scope_, &ok); | 766 CheckConflictingVarDeclarations(scope_, &ok); |
| 717 } | 767 } |
| 718 | 768 |
| 719 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 769 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 720 if (body->length() != 1 || | 770 if (body->length() != 1 || |
| 721 !body->at(0)->IsExpressionStatement() || | 771 !body->at(0)->IsExpressionStatement() || |
| 722 !body->at(0)->AsExpressionStatement()-> | 772 !body->at(0)->AsExpressionStatement()-> |
| 723 expression()->IsFunctionLiteral()) { | 773 expression()->IsFunctionLiteral()) { |
| 724 ReportMessage("single_function_literal", Vector<const char*>::empty()); | 774 ReportMessage("single_function_literal", Vector<const char*>::empty()); |
| 725 ok = false; | 775 ok = false; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 { | 860 { |
| 811 // Parse the function literal. | 861 // Parse the function literal. |
| 812 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 862 Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
| 813 info()->SetGlobalScope(scope); | 863 info()->SetGlobalScope(scope); |
| 814 if (!info()->closure().is_null()) { | 864 if (!info()->closure().is_null()) { |
| 815 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 865 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 816 zone()); | 866 zone()); |
| 817 } | 867 } |
| 818 original_scope_ = scope; | 868 original_scope_ = scope; |
| 819 FunctionState function_state(&function_state_, &scope_, scope, zone()); | 869 FunctionState function_state(&function_state_, &scope_, scope, zone()); |
| 820 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 870 ASSERT(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT); |
| 821 ASSERT(scope->language_mode() != EXTENDED_MODE || | 871 ASSERT(info()->strict_mode() == shared_info->strict_mode()); |
| 822 info()->is_extended_mode()); | 872 scope->SetStrictMode(shared_info->strict_mode()); |
| 823 ASSERT(info()->language_mode() == shared_info->language_mode()); | |
| 824 scope->SetLanguageMode(shared_info->language_mode()); | |
| 825 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 873 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 826 ? (shared_info->is_anonymous() | 874 ? (shared_info->is_anonymous() |
| 827 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 875 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 828 : FunctionLiteral::NAMED_EXPRESSION) | 876 : FunctionLiteral::NAMED_EXPRESSION) |
| 829 : FunctionLiteral::DECLARATION; | 877 : FunctionLiteral::DECLARATION; |
| 830 bool ok = true; | 878 bool ok = true; |
| 831 result = ParseFunctionLiteral(name, | 879 result = ParseFunctionLiteral(name, |
| 832 Scanner::Location::invalid(), | 880 Scanner::Location::invalid(), |
| 833 false, // Strict mode name already checked. | 881 false, // Strict mode name already checked. |
| 834 shared_info->is_generator(), | 882 shared_info->is_generator(), |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 // A shot at a directive. | 938 // A shot at a directive. |
| 891 ExpressionStatement* e_stat; | 939 ExpressionStatement* e_stat; |
| 892 Literal* literal; | 940 Literal* literal; |
| 893 // Still processing directive prologue? | 941 // Still processing directive prologue? |
| 894 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 942 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 895 (literal = e_stat->expression()->AsLiteral()) != NULL && | 943 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 896 literal->value()->IsString()) { | 944 literal->value()->IsString()) { |
| 897 Handle<String> directive = Handle<String>::cast(literal->value()); | 945 Handle<String> directive = Handle<String>::cast(literal->value()); |
| 898 | 946 |
| 899 // Check "use strict" directive (ES5 14.1). | 947 // Check "use strict" directive (ES5 14.1). |
| 900 if (scope_->is_classic_mode() && | 948 if (strict_mode() == SLOPPY && |
| 901 directive->Equals(isolate()->heap()->use_strict_string()) && | 949 directive->Equals(isolate()->heap()->use_strict_string()) && |
| 902 token_loc.end_pos - token_loc.beg_pos == | 950 token_loc.end_pos - token_loc.beg_pos == |
| 903 isolate()->heap()->use_strict_string()->length() + 2) { | 951 isolate()->heap()->use_strict_string()->length() + 2) { |
| 904 // TODO(mstarzinger): Global strict eval calls, need their own scope | 952 // 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 | 953 // 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 | 954 // add this scope in DoParseProgram(), but that requires adaptations |
| 907 // all over the code base, so we go with a quick-fix for now. | 955 // 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. | 956 // In the same manner, we have to patch the parsing mode. |
| 909 if (is_eval && !scope_->is_eval_scope()) { | 957 if (is_eval && !scope_->is_eval_scope()) { |
| 910 ASSERT(scope_->is_global_scope()); | 958 ASSERT(scope_->is_global_scope()); |
| 911 Scope* scope = NewScope(scope_, EVAL_SCOPE); | 959 Scope* scope = NewScope(scope_, EVAL_SCOPE); |
| 912 scope->set_start_position(scope_->start_position()); | 960 scope->set_start_position(scope_->start_position()); |
| 913 scope->set_end_position(scope_->end_position()); | 961 scope->set_end_position(scope_->end_position()); |
| 914 scope_ = scope; | 962 scope_ = scope; |
| 915 mode_ = PARSE_EAGERLY; | 963 mode_ = PARSE_EAGERLY; |
| 916 } | 964 } |
| 917 // TODO(ES6): Fix entering extended mode, once it is specified. | 965 scope_->SetStrictMode(STRICT); |
| 918 scope_->SetLanguageMode(allow_harmony_scoping() | |
| 919 ? EXTENDED_MODE : STRICT_MODE); | |
| 920 // "use strict" is the only directive for now. | 966 // "use strict" is the only directive for now. |
| 921 directive_prologue = false; | 967 directive_prologue = false; |
| 922 } | 968 } |
| 923 } else { | 969 } else { |
| 924 // End of the directive prologue. | 970 // End of the directive prologue. |
| 925 directive_prologue = false; | 971 directive_prologue = false; |
| 926 } | 972 } |
| 927 } | 973 } |
| 928 | 974 |
| 929 processor->Add(stat, zone()); | 975 processor->Add(stat, zone()); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 int pos = peek_position(); | 1097 int pos = peek_position(); |
| 1052 // Construct block expecting 16 statements. | 1098 // Construct block expecting 16 statements. |
| 1053 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); | 1099 Block* body = factory()->NewBlock(NULL, 16, false, RelocInfo::kNoPosition); |
| 1054 #ifdef DEBUG | 1100 #ifdef DEBUG |
| 1055 if (FLAG_print_interface_details) PrintF("# Literal "); | 1101 if (FLAG_print_interface_details) PrintF("# Literal "); |
| 1056 #endif | 1102 #endif |
| 1057 Scope* scope = NewScope(scope_, MODULE_SCOPE); | 1103 Scope* scope = NewScope(scope_, MODULE_SCOPE); |
| 1058 | 1104 |
| 1059 Expect(Token::LBRACE, CHECK_OK); | 1105 Expect(Token::LBRACE, CHECK_OK); |
| 1060 scope->set_start_position(scanner()->location().beg_pos); | 1106 scope->set_start_position(scanner()->location().beg_pos); |
| 1061 scope->SetLanguageMode(EXTENDED_MODE); | 1107 scope->SetStrictMode(STRICT); |
| 1062 | 1108 |
| 1063 { | 1109 { |
| 1064 BlockState block_state(&scope_, scope); | 1110 BlockState block_state(&scope_, scope); |
| 1065 TargetCollector collector(zone()); | 1111 TargetCollector collector(zone()); |
| 1066 Target target(&this->target_stack_, &collector); | 1112 Target target(&this->target_stack_, &collector); |
| 1067 Target target_body(&this->target_stack_, body); | 1113 Target target_body(&this->target_stack_, body); |
| 1068 | 1114 |
| 1069 while (peek() != Token::RBRACE) { | 1115 while (peek() != Token::RBRACE) { |
| 1070 Statement* stat = ParseModuleElement(NULL, CHECK_OK); | 1116 Statement* stat = ParseModuleElement(NULL, CHECK_OK); |
| 1071 if (stat && !stat->IsEmpty()) { | 1117 if (stat && !stat->IsEmpty()) { |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1436 // (Ecma 262 5th Edition, clause 14): | 1482 // (Ecma 262 5th Edition, clause 14): |
| 1437 // SourceElement: | 1483 // SourceElement: |
| 1438 // Statement | 1484 // Statement |
| 1439 // FunctionDeclaration | 1485 // FunctionDeclaration |
| 1440 // Common language extension is to allow function declaration in place | 1486 // Common language extension is to allow function declaration in place |
| 1441 // of any statement. This language extension is disabled in strict mode. | 1487 // of any statement. This language extension is disabled in strict mode. |
| 1442 // | 1488 // |
| 1443 // In Harmony mode, this case also handles the extension: | 1489 // In Harmony mode, this case also handles the extension: |
| 1444 // Statement: | 1490 // Statement: |
| 1445 // GeneratorDeclaration | 1491 // GeneratorDeclaration |
| 1446 if (!scope_->is_classic_mode()) { | 1492 if (strict_mode() == STRICT) { |
| 1447 ReportMessageAt(scanner()->peek_location(), "strict_function"); | 1493 ReportMessageAt(scanner()->peek_location(), "strict_function"); |
| 1448 *ok = false; | 1494 *ok = false; |
| 1449 return NULL; | 1495 return NULL; |
| 1450 } | 1496 } |
| 1451 return ParseFunctionDeclaration(NULL, ok); | 1497 return ParseFunctionDeclaration(NULL, ok); |
| 1452 } | 1498 } |
| 1453 | 1499 |
| 1454 case Token::DEBUGGER: | 1500 case Token::DEBUGGER: |
| 1455 return ParseDebuggerStatement(ok); | 1501 return ParseDebuggerStatement(ok); |
| 1456 | 1502 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1481 | 1527 |
| 1482 // If a suitable scope exists, then we can statically declare this | 1528 // If a suitable scope exists, then we can statically declare this |
| 1483 // variable and also set its mode. In any case, a Declaration node | 1529 // variable and also set its mode. In any case, a Declaration node |
| 1484 // will be added to the scope so that the declaration can be added | 1530 // will be added to the scope so that the declaration can be added |
| 1485 // to the corresponding activation frame at runtime if necessary. | 1531 // to the corresponding activation frame at runtime if necessary. |
| 1486 // For instance declarations inside an eval scope need to be added | 1532 // For instance declarations inside an eval scope need to be added |
| 1487 // to the calling function context. | 1533 // to the calling function context. |
| 1488 // Similarly, strict mode eval scope does not leak variable declarations to | 1534 // Similarly, strict mode eval scope does not leak variable declarations to |
| 1489 // the caller's scope so we declare all locals, too. | 1535 // the caller's scope so we declare all locals, too. |
| 1490 if (declaration_scope->is_function_scope() || | 1536 if (declaration_scope->is_function_scope() || |
| 1491 declaration_scope->is_strict_or_extended_eval_scope() || | 1537 declaration_scope->is_strict_eval_scope() || |
| 1492 declaration_scope->is_block_scope() || | 1538 declaration_scope->is_block_scope() || |
| 1493 declaration_scope->is_module_scope() || | 1539 declaration_scope->is_module_scope() || |
| 1494 declaration_scope->is_global_scope()) { | 1540 declaration_scope->is_global_scope()) { |
| 1495 // Declare the variable in the declaration scope. | 1541 // Declare the variable in the declaration scope. |
| 1496 // For the global scope, we have to check for collisions with earlier | 1542 // For the global scope, we have to check for collisions with earlier |
| 1497 // (i.e., enclosing) global scopes, to maintain the illusion of a single | 1543 // (i.e., enclosing) global scopes, to maintain the illusion of a single |
| 1498 // global scope. | 1544 // global scope. |
| 1499 var = declaration_scope->is_global_scope() | 1545 var = declaration_scope->is_global_scope() |
| 1500 ? declaration_scope->Lookup(name) | 1546 ? declaration_scope->Lookup(name) |
| 1501 : declaration_scope->LocalLookup(name); | 1547 : declaration_scope->LocalLookup(name); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1514 // functions. The function CheckNonConflictingScope checks for conflicting | 1560 // functions. The function CheckNonConflictingScope checks for conflicting |
| 1515 // var and let bindings from different scopes whereas this is a check for | 1561 // var and let bindings from different scopes whereas this is a check for |
| 1516 // conflicting declarations within the same scope. This check also covers | 1562 // conflicting declarations within the same scope. This check also covers |
| 1517 // the special case | 1563 // the special case |
| 1518 // | 1564 // |
| 1519 // function () { let x; { var x; } } | 1565 // function () { let x; { var x; } } |
| 1520 // | 1566 // |
| 1521 // because the var declaration is hoisted to the function scope where 'x' | 1567 // because the var declaration is hoisted to the function scope where 'x' |
| 1522 // is already bound. | 1568 // is already bound. |
| 1523 ASSERT(IsDeclaredVariableMode(var->mode())); | 1569 ASSERT(IsDeclaredVariableMode(var->mode())); |
| 1524 if (is_extended_mode()) { | 1570 if (FLAG_harmony_scoping && strict_mode() == STRICT) { |
| 1525 // In harmony mode we treat re-declarations as early errors. See | 1571 // In harmony we treat re-declarations as early errors. See |
| 1526 // ES5 16 for a definition of early errors. | 1572 // ES5 16 for a definition of early errors. |
| 1527 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1573 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1528 const char* elms[2] = { "Variable", c_string.get() }; | 1574 const char* elms[2] = { "Variable", c_string.get() }; |
| 1529 Vector<const char*> args(elms, 2); | 1575 Vector<const char*> args(elms, 2); |
| 1530 ReportMessage("redeclaration", args); | 1576 ReportMessage("redeclaration", args); |
| 1531 *ok = false; | 1577 *ok = false; |
| 1532 return; | 1578 return; |
| 1533 } | 1579 } |
| 1534 Handle<String> message_string = | 1580 Handle<String> message_string = |
| 1535 isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"), | 1581 isolate()->factory()->NewStringFromUtf8(CStrVector("Variable"), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1552 // bound during variable resolution time unless it was pre-bound | 1598 // bound during variable resolution time unless it was pre-bound |
| 1553 // below. | 1599 // below. |
| 1554 // | 1600 // |
| 1555 // WARNING: This will lead to multiple declaration nodes for the | 1601 // WARNING: This will lead to multiple declaration nodes for the |
| 1556 // same variable if it is declared several times. This is not a | 1602 // same variable if it is declared several times. This is not a |
| 1557 // semantic issue as long as we keep the source order, but it may be | 1603 // semantic issue as long as we keep the source order, but it may be |
| 1558 // a performance issue since it may lead to repeated | 1604 // a performance issue since it may lead to repeated |
| 1559 // Runtime::DeclareContextSlot() calls. | 1605 // Runtime::DeclareContextSlot() calls. |
| 1560 declaration_scope->AddDeclaration(declaration); | 1606 declaration_scope->AddDeclaration(declaration); |
| 1561 | 1607 |
| 1562 if (mode == CONST && declaration_scope->is_global_scope()) { | 1608 if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) { |
| 1563 // For global const variables we bind the proxy to a variable. | 1609 // For global const variables we bind the proxy to a variable. |
| 1564 ASSERT(resolve); // should be set by all callers | 1610 ASSERT(resolve); // should be set by all callers |
| 1565 Variable::Kind kind = Variable::NORMAL; | 1611 Variable::Kind kind = Variable::NORMAL; |
| 1566 var = new(zone()) Variable( | 1612 var = new(zone()) Variable( |
| 1567 declaration_scope, name, mode, true, kind, | 1613 declaration_scope, name, mode, true, kind, |
| 1568 kNeedsInitialization, proxy->interface()); | 1614 kNeedsInitialization, proxy->interface()); |
| 1569 } else if (declaration_scope->is_eval_scope() && | 1615 } else if (declaration_scope->is_eval_scope() && |
| 1570 declaration_scope->is_classic_mode()) { | 1616 declaration_scope->strict_mode() == SLOPPY) { |
| 1571 // For variable declarations in a non-strict eval scope the proxy is bound | 1617 // For variable declarations in a sloppy eval scope the proxy is bound |
| 1572 // to a lookup variable to force a dynamic declaration using the | 1618 // to a lookup variable to force a dynamic declaration using the |
| 1573 // DeclareContextSlot runtime function. | 1619 // DeclareContextSlot runtime function. |
| 1574 Variable::Kind kind = Variable::NORMAL; | 1620 Variable::Kind kind = Variable::NORMAL; |
| 1575 var = new(zone()) Variable( | 1621 var = new(zone()) Variable( |
| 1576 declaration_scope, name, mode, true, kind, | 1622 declaration_scope, name, mode, true, kind, |
| 1577 declaration->initialization(), proxy->interface()); | 1623 declaration->initialization(), proxy->interface()); |
| 1578 var->AllocateTo(Variable::LOOKUP, -1); | 1624 var->AllocateTo(Variable::LOOKUP, -1); |
| 1579 resolve = true; | 1625 resolve = true; |
| 1580 } | 1626 } |
| 1581 | 1627 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 is_generator, | 1738 is_generator, |
| 1693 pos, | 1739 pos, |
| 1694 FunctionLiteral::DECLARATION, | 1740 FunctionLiteral::DECLARATION, |
| 1695 CHECK_OK); | 1741 CHECK_OK); |
| 1696 // Even if we're not at the top-level of the global or a function | 1742 // 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 | 1743 // scope, we treat it as such and introduce the function with its |
| 1698 // initial value upon entering the corresponding scope. | 1744 // initial value upon entering the corresponding scope. |
| 1699 // In extended mode, a function behaves as a lexical binding, except in the | 1745 // In extended mode, a function behaves as a lexical binding, except in the |
| 1700 // global scope. | 1746 // global scope. |
| 1701 VariableMode mode = | 1747 VariableMode mode = |
| 1702 is_extended_mode() && !scope_->is_global_scope() ? LET : VAR; | 1748 FLAG_harmony_scoping && |
| 1749 strict_mode() == STRICT && !scope_->is_global_scope() ? LET : VAR; |
| 1703 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); | 1750 VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue()); |
| 1704 Declaration* declaration = | 1751 Declaration* declaration = |
| 1705 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); | 1752 factory()->NewFunctionDeclaration(proxy, mode, fun, scope_, pos); |
| 1706 Declare(declaration, true, CHECK_OK); | 1753 Declare(declaration, true, CHECK_OK); |
| 1707 if (names) names->Add(name, zone()); | 1754 if (names) names->Add(name, zone()); |
| 1708 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); | 1755 return factory()->NewEmptyStatement(RelocInfo::kNoPosition); |
| 1709 } | 1756 } |
| 1710 | 1757 |
| 1711 | 1758 |
| 1712 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1759 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1713 if (scope_->is_extended_mode()) return ParseScopedBlock(labels, ok); | 1760 if (FLAG_harmony_scoping && strict_mode() == STRICT) { |
| 1761 return ParseScopedBlock(labels, ok); |
| 1762 } |
| 1714 | 1763 |
| 1715 // Block :: | 1764 // Block :: |
| 1716 // '{' Statement* '}' | 1765 // '{' Statement* '}' |
| 1717 | 1766 |
| 1718 // Note that a Block does not introduce a new execution scope! | 1767 // Note that a Block does not introduce a new execution scope! |
| 1719 // (ECMA-262, 3rd, 12.2) | 1768 // (ECMA-262, 3rd, 12.2) |
| 1720 // | 1769 // |
| 1721 // Construct block expecting 16 statements. | 1770 // Construct block expecting 16 statements. |
| 1722 Block* result = | 1771 Block* result = |
| 1723 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); | 1772 factory()->NewBlock(labels, 16, false, RelocInfo::kNoPosition); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1819 if (peek() == Token::VAR) { | 1868 if (peek() == Token::VAR) { |
| 1820 Consume(Token::VAR); | 1869 Consume(Token::VAR); |
| 1821 } else if (peek() == Token::CONST) { | 1870 } else if (peek() == Token::CONST) { |
| 1822 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: | 1871 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
| 1823 // | 1872 // |
| 1824 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' | 1873 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 1825 // | 1874 // |
| 1826 // * It is a Syntax Error if the code that matches this production is not | 1875 // * It is a Syntax Error if the code that matches this production is not |
| 1827 // contained in extended code. | 1876 // contained in extended code. |
| 1828 // | 1877 // |
| 1829 // However disallowing const in classic mode will break compatibility with | 1878 // However disallowing const in sloppy mode will break compatibility with |
| 1830 // existing pages. Therefore we keep allowing const with the old | 1879 // existing pages. Therefore we keep allowing const with the old |
| 1831 // non-harmony semantics in classic mode. | 1880 // non-harmony semantics in sloppy mode. |
| 1832 Consume(Token::CONST); | 1881 Consume(Token::CONST); |
| 1833 switch (scope_->language_mode()) { | 1882 switch (strict_mode()) { |
| 1834 case CLASSIC_MODE: | 1883 case SLOPPY: |
| 1835 mode = CONST; | 1884 mode = CONST_LEGACY; |
| 1836 init_op = Token::INIT_CONST; | 1885 init_op = Token::INIT_CONST_LEGACY; |
| 1837 break; | 1886 break; |
| 1838 case STRICT_MODE: | 1887 case STRICT: |
| 1839 ReportMessage("strict_const", Vector<const char*>::empty()); | 1888 if (FLAG_harmony_scoping) { |
| 1840 *ok = false; | 1889 if (var_context == kStatement) { |
| 1841 return NULL; | 1890 // In strict mode 'const' declarations are only allowed in source |
| 1842 case EXTENDED_MODE: | 1891 // element positions. |
| 1843 if (var_context == kStatement) { | 1892 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
| 1844 // In extended mode 'const' declarations are only allowed in source | 1893 *ok = false; |
| 1845 // element positions. | 1894 return NULL; |
| 1846 ReportMessage("unprotected_const", Vector<const char*>::empty()); | 1895 } |
| 1896 mode = CONST; |
| 1897 init_op = Token::INIT_CONST; |
| 1898 } else { |
| 1899 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1847 *ok = false; | 1900 *ok = false; |
| 1848 return NULL; | 1901 return NULL; |
| 1849 } | 1902 } |
| 1850 mode = CONST_HARMONY; | |
| 1851 init_op = Token::INIT_CONST_HARMONY; | |
| 1852 } | 1903 } |
| 1853 is_const = true; | 1904 is_const = true; |
| 1854 needs_init = true; | 1905 needs_init = true; |
| 1855 } else if (peek() == Token::LET) { | 1906 } else if (peek() == Token::LET) { |
| 1856 // ES6 Draft Rev4 section 12.2.1: | 1907 // ES6 Draft Rev4 section 12.2.1: |
| 1857 // | 1908 // |
| 1858 // LetDeclaration : let LetBindingList ; | 1909 // LetDeclaration : let LetBindingList ; |
| 1859 // | 1910 // |
| 1860 // * It is a Syntax Error if the code that matches this production is not | 1911 // * It is a Syntax Error if the code that matches this production is not |
| 1861 // contained in extended code. | 1912 // contained in extended code. |
| 1862 if (!is_extended_mode()) { | 1913 // |
| 1914 // TODO(rossberg): make 'let' a legal identifier in sloppy mode. |
| 1915 if (!FLAG_harmony_scoping || strict_mode() == SLOPPY) { |
| 1863 ReportMessage("illegal_let", Vector<const char*>::empty()); | 1916 ReportMessage("illegal_let", Vector<const char*>::empty()); |
| 1864 *ok = false; | 1917 *ok = false; |
| 1865 return NULL; | 1918 return NULL; |
| 1866 } | 1919 } |
| 1867 Consume(Token::LET); | 1920 Consume(Token::LET); |
| 1868 if (var_context == kStatement) { | 1921 if (var_context == kStatement) { |
| 1869 // Let declarations are only allowed in source element positions. | 1922 // Let declarations are only allowed in source element positions. |
| 1870 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1923 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
| 1871 *ok = false; | 1924 *ok = false; |
| 1872 return NULL; | 1925 return NULL; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1957 // const c; c = x; | 2010 // const c; c = x; |
| 1958 // | 2011 // |
| 1959 // The "variable" c initialized to x is the same as the declared | 2012 // 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 | 2013 // one - there is no re-lookup (see the last parameter of the |
| 1961 // Declare() call above). | 2014 // Declare() call above). |
| 1962 | 2015 |
| 1963 Scope* initialization_scope = is_const ? declaration_scope : scope_; | 2016 Scope* initialization_scope = is_const ? declaration_scope : scope_; |
| 1964 Expression* value = NULL; | 2017 Expression* value = NULL; |
| 1965 int pos = -1; | 2018 int pos = -1; |
| 1966 // Harmony consts have non-optional initializers. | 2019 // Harmony consts have non-optional initializers. |
| 1967 if (peek() == Token::ASSIGN || mode == CONST_HARMONY) { | 2020 if (peek() == Token::ASSIGN || mode == CONST) { |
| 1968 Expect(Token::ASSIGN, CHECK_OK); | 2021 Expect(Token::ASSIGN, CHECK_OK); |
| 1969 pos = position(); | 2022 pos = position(); |
| 1970 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); | 2023 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK); |
| 1971 // Don't infer if it is "a = function(){...}();"-like expression. | 2024 // Don't infer if it is "a = function(){...}();"-like expression. |
| 1972 if (fni_ != NULL && | 2025 if (fni_ != NULL && |
| 1973 value->AsCall() == NULL && | 2026 value->AsCall() == NULL && |
| 1974 value->AsCallNew() == NULL) { | 2027 value->AsCallNew() == NULL) { |
| 1975 fni_->Infer(); | 2028 fni_->Infer(); |
| 1976 } else { | 2029 } else { |
| 1977 fni_->RemoveLastFunction(); | 2030 fni_->RemoveLastFunction(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2025 // and add it to the initialization statement block. | 2078 // and add it to the initialization statement block. |
| 2026 // Note that the function does different things depending on | 2079 // Note that the function does different things depending on |
| 2027 // the number of arguments (1 or 2). | 2080 // the number of arguments (1 or 2). |
| 2028 initialize = factory()->NewCallRuntime( | 2081 initialize = factory()->NewCallRuntime( |
| 2029 isolate()->factory()->InitializeConstGlobal_string(), | 2082 isolate()->factory()->InitializeConstGlobal_string(), |
| 2030 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 2083 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 2031 arguments, pos); | 2084 arguments, pos); |
| 2032 } else { | 2085 } else { |
| 2033 // Add strict mode. | 2086 // Add strict mode. |
| 2034 // We may want to pass singleton to avoid Literal allocations. | 2087 // We may want to pass singleton to avoid Literal allocations. |
| 2035 LanguageMode language_mode = initialization_scope->language_mode(); | 2088 StrictMode strict_mode = initialization_scope->strict_mode(); |
| 2036 arguments->Add(factory()->NewNumberLiteral(language_mode, pos), zone()); | 2089 arguments->Add(factory()->NewNumberLiteral(strict_mode, pos), zone()); |
| 2037 | 2090 |
| 2038 // Be careful not to assign a value to the global variable if | 2091 // Be careful not to assign a value to the global variable if |
| 2039 // we're in a with. The initialization value should not | 2092 // we're in a with. The initialization value should not |
| 2040 // necessarily be stored in the global object in that case, | 2093 // necessarily be stored in the global object in that case, |
| 2041 // which is why we need to generate a separate assignment node. | 2094 // which is why we need to generate a separate assignment node. |
| 2042 if (value != NULL && !inside_with()) { | 2095 if (value != NULL && !inside_with()) { |
| 2043 arguments->Add(value, zone()); | 2096 arguments->Add(value, zone()); |
| 2044 value = NULL; // zap the value to avoid the unnecessary assignment | 2097 value = NULL; // zap the value to avoid the unnecessary assignment |
| 2045 } | 2098 } |
| 2046 | 2099 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2326 } | 2379 } |
| 2327 | 2380 |
| 2328 | 2381 |
| 2329 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 2382 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 2330 // WithStatement :: | 2383 // WithStatement :: |
| 2331 // 'with' '(' Expression ')' Statement | 2384 // 'with' '(' Expression ')' Statement |
| 2332 | 2385 |
| 2333 Expect(Token::WITH, CHECK_OK); | 2386 Expect(Token::WITH, CHECK_OK); |
| 2334 int pos = position(); | 2387 int pos = position(); |
| 2335 | 2388 |
| 2336 if (!scope_->is_classic_mode()) { | 2389 if (strict_mode() == STRICT) { |
| 2337 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 2390 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 2338 *ok = false; | 2391 *ok = false; |
| 2339 return NULL; | 2392 return NULL; |
| 2340 } | 2393 } |
| 2341 | 2394 |
| 2342 Expect(Token::LPAREN, CHECK_OK); | 2395 Expect(Token::LPAREN, CHECK_OK); |
| 2343 Expression* expr = ParseExpression(true, CHECK_OK); | 2396 Expression* expr = ParseExpression(true, CHECK_OK); |
| 2344 Expect(Token::RPAREN, CHECK_OK); | 2397 Expect(Token::RPAREN, CHECK_OK); |
| 2345 | 2398 |
| 2346 scope_->DeclarationScope()->RecordWithStatement(); | 2399 scope_->DeclarationScope()->RecordWithStatement(); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 Consume(Token::CATCH); | 2531 Consume(Token::CATCH); |
| 2479 | 2532 |
| 2480 Expect(Token::LPAREN, CHECK_OK); | 2533 Expect(Token::LPAREN, CHECK_OK); |
| 2481 catch_scope = NewScope(scope_, CATCH_SCOPE); | 2534 catch_scope = NewScope(scope_, CATCH_SCOPE); |
| 2482 catch_scope->set_start_position(scanner()->location().beg_pos); | 2535 catch_scope->set_start_position(scanner()->location().beg_pos); |
| 2483 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); | 2536 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2484 | 2537 |
| 2485 Expect(Token::RPAREN, CHECK_OK); | 2538 Expect(Token::RPAREN, CHECK_OK); |
| 2486 | 2539 |
| 2487 Target target(&this->target_stack_, &catch_collector); | 2540 Target target(&this->target_stack_, &catch_collector); |
| 2488 VariableMode mode = is_extended_mode() ? LET : VAR; | 2541 VariableMode mode = |
| 2542 FLAG_harmony_scoping && strict_mode() == STRICT ? LET : VAR; |
| 2489 catch_variable = | 2543 catch_variable = |
| 2490 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2544 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2491 | 2545 |
| 2492 BlockState block_state(&scope_, catch_scope); | 2546 BlockState block_state(&scope_, catch_scope); |
| 2493 catch_block = ParseBlock(NULL, CHECK_OK); | 2547 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2494 | 2548 |
| 2495 catch_scope->set_end_position(scanner()->location().end_pos); | 2549 catch_scope->set_end_position(scanner()->location().end_pos); |
| 2496 tok = peek(); | 2550 tok = peek(); |
| 2497 } | 2551 } |
| 2498 | 2552 |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2869 result->set_scope(for_scope); | 2923 result->set_scope(for_scope); |
| 2870 loop->Initialize(NULL, cond, next, body); | 2924 loop->Initialize(NULL, cond, next, body); |
| 2871 return result; | 2925 return result; |
| 2872 } else { | 2926 } else { |
| 2873 loop->Initialize(init, cond, next, body); | 2927 loop->Initialize(init, cond, next, body); |
| 2874 return loop; | 2928 return loop; |
| 2875 } | 2929 } |
| 2876 } | 2930 } |
| 2877 | 2931 |
| 2878 | 2932 |
| 2879 // Precedence = 2 | |
| 2880 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | |
| 2881 // AssignmentExpression :: | |
| 2882 // ConditionalExpression | |
| 2883 // YieldExpression | |
| 2884 // LeftHandSideExpression AssignmentOperator AssignmentExpression | |
| 2885 | |
| 2886 if (peek() == Token::YIELD && is_generator()) { | |
| 2887 return ParseYieldExpression(ok); | |
| 2888 } | |
| 2889 | |
| 2890 if (fni_ != NULL) fni_->Enter(); | |
| 2891 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | |
| 2892 | |
| 2893 if (!Token::IsAssignmentOp(peek())) { | |
| 2894 if (fni_ != NULL) fni_->Leave(); | |
| 2895 // Parsed conditional expression only (no assignment). | |
| 2896 return expression; | |
| 2897 } | |
| 2898 | |
| 2899 // Signal a reference error if the expression is an invalid left-hand | |
| 2900 // side expression. We could report this as a syntax error here but | |
| 2901 // for compatibility with JSC we choose to report the error at | |
| 2902 // runtime. | |
| 2903 // TODO(ES5): Should change parsing for spec conformance. | |
| 2904 if (expression == NULL || !expression->IsValidLeftHandSide()) { | |
| 2905 Handle<String> message = | |
| 2906 isolate()->factory()->invalid_lhs_in_assignment_string(); | |
| 2907 expression = NewThrowReferenceError(message); | |
| 2908 } | |
| 2909 | |
| 2910 if (!scope_->is_classic_mode()) { | |
| 2911 // Assignment to eval or arguments is disallowed in strict mode. | |
| 2912 CheckStrictModeLValue(expression, CHECK_OK); | |
| 2913 } | |
| 2914 MarkAsLValue(expression); | |
| 2915 | |
| 2916 Token::Value op = Next(); // Get assignment operator. | |
| 2917 int pos = position(); | |
| 2918 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | |
| 2919 | |
| 2920 // TODO(1231235): We try to estimate the set of properties set by | |
| 2921 // constructors. We define a new property whenever there is an | |
| 2922 // assignment to a property of 'this'. We should probably only add | |
| 2923 // properties if we haven't seen them before. Otherwise we'll | |
| 2924 // probably overestimate the number of properties. | |
| 2925 Property* property = expression ? expression->AsProperty() : NULL; | |
| 2926 if (op == Token::ASSIGN && | |
| 2927 property != NULL && | |
| 2928 property->obj()->AsVariableProxy() != NULL && | |
| 2929 property->obj()->AsVariableProxy()->is_this()) { | |
| 2930 function_state_->AddProperty(); | |
| 2931 } | |
| 2932 | |
| 2933 // If we assign a function literal to a property we pretenure the | |
| 2934 // literal so it can be added as a constant function property. | |
| 2935 if (property != NULL && right->AsFunctionLiteral() != NULL) { | |
| 2936 right->AsFunctionLiteral()->set_pretenure(); | |
| 2937 } | |
| 2938 | |
| 2939 if (fni_ != NULL) { | |
| 2940 // Check if the right hand side is a call to avoid inferring a | |
| 2941 // name if we're dealing with "a = function(){...}();"-like | |
| 2942 // expression. | |
| 2943 if ((op == Token::INIT_VAR | |
| 2944 || op == Token::INIT_CONST | |
| 2945 || op == Token::ASSIGN) | |
| 2946 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { | |
| 2947 fni_->Infer(); | |
| 2948 } else { | |
| 2949 fni_->RemoveLastFunction(); | |
| 2950 } | |
| 2951 fni_->Leave(); | |
| 2952 } | |
| 2953 | |
| 2954 return factory()->NewAssignment(op, expression, right, pos); | |
| 2955 } | |
| 2956 | |
| 2957 | |
| 2958 Expression* Parser::ParseYieldExpression(bool* ok) { | |
| 2959 // YieldExpression :: | |
| 2960 // 'yield' '*'? AssignmentExpression | |
| 2961 int pos = peek_position(); | |
| 2962 Expect(Token::YIELD, CHECK_OK); | |
| 2963 Yield::Kind kind = | |
| 2964 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | |
| 2965 Expression* generator_object = factory()->NewVariableProxy( | |
| 2966 function_state_->generator_object_variable()); | |
| 2967 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | |
| 2968 Yield* yield = factory()->NewYield(generator_object, expression, kind, pos); | |
| 2969 if (kind == Yield::DELEGATING) { | |
| 2970 yield->set_index(function_state_->NextHandlerIndex()); | |
| 2971 } | |
| 2972 return yield; | |
| 2973 } | |
| 2974 | |
| 2975 | |
| 2976 // Precedence = 3 | 2933 // Precedence = 3 |
| 2977 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { | 2934 Expression* Parser::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 2978 // ConditionalExpression :: | 2935 // ConditionalExpression :: |
| 2979 // LogicalOrExpression | 2936 // LogicalOrExpression |
| 2980 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression | 2937 // LogicalOrExpression '?' AssignmentExpression ':' AssignmentExpression |
| 2981 | 2938 |
| 2982 int pos = peek_position(); | 2939 int pos = peek_position(); |
| 2983 // We start using the binary expression parser for prec >= 4 only! | 2940 // We start using the binary expression parser for prec >= 4 only! |
| 2984 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); | 2941 Expression* expression = ParseBinaryExpression(4, accept_IN, CHECK_OK); |
| 2985 if (peek() != Token::CONDITIONAL) return expression; | 2942 if (peek() != Token::CONDITIONAL) return expression; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3124 return factory()->NewNumberLiteral(-value, pos); | 3081 return factory()->NewNumberLiteral(-value, pos); |
| 3125 case Token::BIT_NOT: | 3082 case Token::BIT_NOT: |
| 3126 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); | 3083 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos); |
| 3127 default: | 3084 default: |
| 3128 break; | 3085 break; |
| 3129 } | 3086 } |
| 3130 } | 3087 } |
| 3131 } | 3088 } |
| 3132 | 3089 |
| 3133 // "delete identifier" is a syntax error in strict mode. | 3090 // "delete identifier" is a syntax error in strict mode. |
| 3134 if (op == Token::DELETE && !scope_->is_classic_mode()) { | 3091 if (op == Token::DELETE && strict_mode() == STRICT) { |
| 3135 VariableProxy* operand = expression->AsVariableProxy(); | 3092 VariableProxy* operand = expression->AsVariableProxy(); |
| 3136 if (operand != NULL && !operand->is_this()) { | 3093 if (operand != NULL && !operand->is_this()) { |
| 3137 ReportMessage("strict_delete", Vector<const char*>::empty()); | 3094 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 3138 *ok = false; | 3095 *ok = false; |
| 3139 return NULL; | 3096 return NULL; |
| 3140 } | 3097 } |
| 3141 } | 3098 } |
| 3142 | 3099 |
| 3143 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback | 3100 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback |
| 3144 // without any special stub and the multiplication is removed later in | 3101 // 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 | 3129 // Signal a reference error if the expression is an invalid |
| 3173 // left-hand side expression. We could report this as a syntax | 3130 // left-hand side expression. We could report this as a syntax |
| 3174 // error here but for compatibility with JSC we choose to report the | 3131 // error here but for compatibility with JSC we choose to report the |
| 3175 // error at runtime. | 3132 // error at runtime. |
| 3176 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3133 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3177 Handle<String> message = | 3134 Handle<String> message = |
| 3178 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3135 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3179 expression = NewThrowReferenceError(message); | 3136 expression = NewThrowReferenceError(message); |
| 3180 } | 3137 } |
| 3181 | 3138 |
| 3182 if (!scope_->is_classic_mode()) { | 3139 if (strict_mode() == STRICT) { |
| 3183 // Prefix expression operand in strict mode may not be eval or arguments. | 3140 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3184 CheckStrictModeLValue(expression, CHECK_OK); | 3141 CheckStrictModeLValue(expression, CHECK_OK); |
| 3185 } | 3142 } |
| 3186 MarkAsLValue(expression); | 3143 MarkExpressionAsLValue(expression); |
| 3187 | 3144 |
| 3188 return factory()->NewCountOperation(op, | 3145 return factory()->NewCountOperation(op, |
| 3189 true /* prefix */, | 3146 true /* prefix */, |
| 3190 expression, | 3147 expression, |
| 3191 position()); | 3148 position()); |
| 3192 | 3149 |
| 3193 } else { | 3150 } else { |
| 3194 return ParsePostfixExpression(ok); | 3151 return ParsePostfixExpression(ok); |
| 3195 } | 3152 } |
| 3196 } | 3153 } |
| 3197 | 3154 |
| 3198 | 3155 |
| 3199 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3156 Expression* Parser::ParsePostfixExpression(bool* ok) { |
| 3200 // PostfixExpression :: | 3157 // PostfixExpression :: |
| 3201 // LeftHandSideExpression ('++' | '--')? | 3158 // LeftHandSideExpression ('++' | '--')? |
| 3202 | 3159 |
| 3203 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 3160 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
| 3204 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3161 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
| 3205 Token::IsCountOp(peek())) { | 3162 Token::IsCountOp(peek())) { |
| 3206 // Signal a reference error if the expression is an invalid | 3163 // Signal a reference error if the expression is an invalid |
| 3207 // left-hand side expression. We could report this as a syntax | 3164 // left-hand side expression. We could report this as a syntax |
| 3208 // error here but for compatibility with JSC we choose to report the | 3165 // error here but for compatibility with JSC we choose to report the |
| 3209 // error at runtime. | 3166 // error at runtime. |
| 3210 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3167 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3211 Handle<String> message = | 3168 Handle<String> message = |
| 3212 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3169 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3213 expression = NewThrowReferenceError(message); | 3170 expression = NewThrowReferenceError(message); |
| 3214 } | 3171 } |
| 3215 | 3172 |
| 3216 if (!scope_->is_classic_mode()) { | 3173 if (strict_mode() == STRICT) { |
| 3217 // Postfix expression operand in strict mode may not be eval or arguments. | 3174 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3218 CheckStrictModeLValue(expression, CHECK_OK); | 3175 CheckStrictModeLValue(expression, CHECK_OK); |
| 3219 } | 3176 } |
| 3220 MarkAsLValue(expression); | 3177 MarkExpressionAsLValue(expression); |
| 3221 | 3178 |
| 3222 Token::Value next = Next(); | 3179 Token::Value next = Next(); |
| 3223 expression = | 3180 expression = |
| 3224 factory()->NewCountOperation(next, | 3181 factory()->NewCountOperation(next, |
| 3225 false /* postfix */, | 3182 false /* postfix */, |
| 3226 expression, | 3183 expression, |
| 3227 position()); | 3184 position()); |
| 3228 } | 3185 } |
| 3229 return expression; | 3186 return expression; |
| 3230 } | 3187 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3353 | 3310 |
| 3354 // Parse the initial primary or function expression. | 3311 // Parse the initial primary or function expression. |
| 3355 Expression* result = NULL; | 3312 Expression* result = NULL; |
| 3356 if (peek() == Token::FUNCTION) { | 3313 if (peek() == Token::FUNCTION) { |
| 3357 Consume(Token::FUNCTION); | 3314 Consume(Token::FUNCTION); |
| 3358 int function_token_position = position(); | 3315 int function_token_position = position(); |
| 3359 bool is_generator = allow_generators() && Check(Token::MUL); | 3316 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3360 Handle<String> name; | 3317 Handle<String> name; |
| 3361 bool is_strict_reserved_name = false; | 3318 bool is_strict_reserved_name = false; |
| 3362 Scanner::Location function_name_location = Scanner::Location::invalid(); | 3319 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3320 FunctionLiteral::FunctionType function_type = |
| 3321 FunctionLiteral::ANONYMOUS_EXPRESSION; |
| 3363 if (peek_any_identifier()) { | 3322 if (peek_any_identifier()) { |
| 3364 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3323 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3365 CHECK_OK); | 3324 CHECK_OK); |
| 3366 function_name_location = scanner()->location(); | 3325 function_name_location = scanner()->location(); |
| 3326 function_type = FunctionLiteral::NAMED_EXPRESSION; |
| 3367 } | 3327 } |
| 3368 FunctionLiteral::FunctionType function_type = name.is_null() | |
| 3369 ? FunctionLiteral::ANONYMOUS_EXPRESSION | |
| 3370 : FunctionLiteral::NAMED_EXPRESSION; | |
| 3371 result = ParseFunctionLiteral(name, | 3328 result = ParseFunctionLiteral(name, |
| 3372 function_name_location, | 3329 function_name_location, |
| 3373 is_strict_reserved_name, | 3330 is_strict_reserved_name, |
| 3374 is_generator, | 3331 is_generator, |
| 3375 function_token_position, | 3332 function_token_position, |
| 3376 function_type, | 3333 function_type, |
| 3377 CHECK_OK); | 3334 CHECK_OK); |
| 3378 } else { | 3335 } else { |
| 3379 result = ParsePrimaryExpression(CHECK_OK); | 3336 result = ParsePrimaryExpression(CHECK_OK); |
| 3380 } | 3337 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3483 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); | 3440 Smi* literal_type = Smi::cast(value->get(kLiteralTypeSlot)); |
| 3484 return static_cast<LiteralType>(literal_type->value()); | 3441 return static_cast<LiteralType>(literal_type->value()); |
| 3485 } | 3442 } |
| 3486 | 3443 |
| 3487 | 3444 |
| 3488 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { | 3445 Handle<FixedArray> CompileTimeValue::GetElements(Handle<FixedArray> value) { |
| 3489 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); | 3446 return Handle<FixedArray>(FixedArray::cast(value->get(kElementsSlot))); |
| 3490 } | 3447 } |
| 3491 | 3448 |
| 3492 | 3449 |
| 3493 Expression* Parser::ParseObjectLiteral(bool* ok) { | |
| 3494 // ObjectLiteral :: | |
| 3495 // '{' ( | |
| 3496 // ((IdentifierName | String | Number) ':' AssignmentExpression) | |
| 3497 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | |
| 3498 // )*[','] '}' | |
| 3499 | |
| 3500 int pos = peek_position(); | |
| 3501 ZoneList<ObjectLiteral::Property*>* properties = | |
| 3502 new(zone()) ZoneList<ObjectLiteral::Property*>(4, zone()); | |
| 3503 int number_of_boilerplate_properties = 0; | |
| 3504 bool has_function = false; | |
| 3505 | |
| 3506 ObjectLiteralChecker checker(this, scope_->language_mode()); | |
| 3507 | |
| 3508 Expect(Token::LBRACE, CHECK_OK); | |
| 3509 | |
| 3510 while (peek() != Token::RBRACE) { | |
| 3511 if (fni_ != NULL) fni_->Enter(); | |
| 3512 | |
| 3513 Literal* key = NULL; | |
| 3514 Token::Value next = peek(); | |
| 3515 int next_pos = peek_position(); | |
| 3516 | |
| 3517 switch (next) { | |
| 3518 case Token::FUTURE_RESERVED_WORD: | |
| 3519 case Token::FUTURE_STRICT_RESERVED_WORD: | |
| 3520 case Token::IDENTIFIER: { | |
| 3521 bool is_getter = false; | |
| 3522 bool is_setter = false; | |
| 3523 Handle<String> id = | |
| 3524 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | |
| 3525 if (fni_ != NULL) fni_->PushLiteralName(id); | |
| 3526 | |
| 3527 if ((is_getter || is_setter) && peek() != Token::COLON) { | |
| 3528 // Special handling of getter and setter syntax: | |
| 3529 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } | |
| 3530 // We have already read the "get" or "set" keyword. | |
| 3531 Token::Value next = Next(); | |
| 3532 bool is_keyword = Token::IsKeyword(next); | |
| 3533 if (next != i::Token::IDENTIFIER && | |
| 3534 next != i::Token::FUTURE_RESERVED_WORD && | |
| 3535 next != i::Token::FUTURE_STRICT_RESERVED_WORD && | |
| 3536 next != i::Token::NUMBER && | |
| 3537 next != i::Token::STRING && | |
| 3538 !is_keyword) { | |
| 3539 // Unexpected token. | |
| 3540 ReportUnexpectedToken(next); | |
| 3541 *ok = false; | |
| 3542 return NULL; | |
| 3543 } | |
| 3544 // Validate the property. | |
| 3545 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | |
| 3546 checker.CheckProperty(next, type, CHECK_OK); | |
| 3547 Handle<String> name = is_keyword | |
| 3548 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) | |
| 3549 : GetSymbol(); | |
| 3550 FunctionLiteral* value = | |
| 3551 ParseFunctionLiteral(name, | |
| 3552 scanner()->location(), | |
| 3553 false, // reserved words are allowed here | |
| 3554 false, // not a generator | |
| 3555 RelocInfo::kNoPosition, | |
| 3556 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
| 3557 CHECK_OK); | |
| 3558 // Allow any number of parameters for compatibilty with JSC. | |
| 3559 // Specification only allows zero parameters for get and one for set. | |
| 3560 ObjectLiteral::Property* property = | |
| 3561 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | |
| 3562 if (ObjectLiteral::IsBoilerplateProperty(property)) { | |
| 3563 number_of_boilerplate_properties++; | |
| 3564 } | |
| 3565 properties->Add(property, zone()); | |
| 3566 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | |
| 3567 | |
| 3568 if (fni_ != NULL) { | |
| 3569 fni_->Infer(); | |
| 3570 fni_->Leave(); | |
| 3571 } | |
| 3572 continue; // restart the while | |
| 3573 } | |
| 3574 // Failed to parse as get/set property, so it's just a property | |
| 3575 // called "get" or "set". | |
| 3576 key = factory()->NewLiteral(id, next_pos); | |
| 3577 break; | |
| 3578 } | |
| 3579 case Token::STRING: { | |
| 3580 Consume(Token::STRING); | |
| 3581 Handle<String> string = GetSymbol(); | |
| 3582 if (fni_ != NULL) fni_->PushLiteralName(string); | |
| 3583 uint32_t index; | |
| 3584 if (!string.is_null() && string->AsArrayIndex(&index)) { | |
| 3585 key = factory()->NewNumberLiteral(index, next_pos); | |
| 3586 break; | |
| 3587 } | |
| 3588 key = factory()->NewLiteral(string, next_pos); | |
| 3589 break; | |
| 3590 } | |
| 3591 case Token::NUMBER: { | |
| 3592 Consume(Token::NUMBER); | |
| 3593 ASSERT(scanner()->is_literal_ascii()); | |
| 3594 double value = StringToDouble(isolate()->unicode_cache(), | |
| 3595 scanner()->literal_ascii_string(), | |
| 3596 ALLOW_HEX | ALLOW_OCTAL | | |
| 3597 ALLOW_IMPLICIT_OCTAL | ALLOW_BINARY); | |
| 3598 key = factory()->NewNumberLiteral(value, next_pos); | |
| 3599 break; | |
| 3600 } | |
| 3601 default: | |
| 3602 if (Token::IsKeyword(next)) { | |
| 3603 Consume(next); | |
| 3604 Handle<String> string = GetSymbol(); | |
| 3605 key = factory()->NewLiteral(string, next_pos); | |
| 3606 } else { | |
| 3607 // Unexpected token. | |
| 3608 Token::Value next = Next(); | |
| 3609 ReportUnexpectedToken(next); | |
| 3610 *ok = false; | |
| 3611 return NULL; | |
| 3612 } | |
| 3613 } | |
| 3614 | |
| 3615 // Validate the property | |
| 3616 checker.CheckProperty(next, kValueProperty, CHECK_OK); | |
| 3617 | |
| 3618 Expect(Token::COLON, CHECK_OK); | |
| 3619 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | |
| 3620 | |
| 3621 ObjectLiteral::Property* property = | |
| 3622 factory()->NewObjectLiteralProperty(key, value); | |
| 3623 | |
| 3624 // Mark top-level object literals that contain function literals and | |
| 3625 // pretenure the literal so it can be added as a constant function | |
| 3626 // property. | |
| 3627 if (scope_->DeclarationScope()->is_global_scope() && | |
| 3628 value->AsFunctionLiteral() != NULL) { | |
| 3629 has_function = true; | |
| 3630 value->AsFunctionLiteral()->set_pretenure(); | |
| 3631 } | |
| 3632 | |
| 3633 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | |
| 3634 if (ObjectLiteral::IsBoilerplateProperty(property)) { | |
| 3635 number_of_boilerplate_properties++; | |
| 3636 } | |
| 3637 properties->Add(property, zone()); | |
| 3638 | |
| 3639 // TODO(1240767): Consider allowing trailing comma. | |
| 3640 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | |
| 3641 | |
| 3642 if (fni_ != NULL) { | |
| 3643 fni_->Infer(); | |
| 3644 fni_->Leave(); | |
| 3645 } | |
| 3646 } | |
| 3647 Expect(Token::RBRACE, CHECK_OK); | |
| 3648 | |
| 3649 // Computation of literal_index must happen before pre parse bailout. | |
| 3650 int literal_index = function_state_->NextMaterializedLiteralIndex(); | |
| 3651 | |
| 3652 return factory()->NewObjectLiteral(properties, | |
| 3653 literal_index, | |
| 3654 number_of_boilerplate_properties, | |
| 3655 has_function, | |
| 3656 pos); | |
| 3657 } | |
| 3658 | |
| 3659 | |
| 3660 ZoneList<Expression*>* Parser::ParseArguments(bool* ok) { | |
| 3661 // Arguments :: | |
| 3662 // '(' (AssignmentExpression)*[','] ')' | |
| 3663 | |
| 3664 ZoneList<Expression*>* result = new(zone()) ZoneList<Expression*>(4, zone()); | |
| 3665 Expect(Token::LPAREN, CHECK_OK); | |
| 3666 bool done = (peek() == Token::RPAREN); | |
| 3667 while (!done) { | |
| 3668 Expression* argument = ParseAssignmentExpression(true, CHECK_OK); | |
| 3669 result->Add(argument, zone()); | |
| 3670 if (result->length() > Code::kMaxArguments) { | |
| 3671 ReportMessageAt(scanner()->location(), "too_many_arguments"); | |
| 3672 *ok = false; | |
| 3673 return NULL; | |
| 3674 } | |
| 3675 done = (peek() == Token::RPAREN); | |
| 3676 if (!done) Expect(Token::COMMA, CHECK_OK); | |
| 3677 } | |
| 3678 Expect(Token::RPAREN, CHECK_OK); | |
| 3679 return result; | |
| 3680 } | |
| 3681 | |
| 3682 | |
| 3683 class SingletonLogger : public ParserRecorder { | |
| 3684 public: | |
| 3685 SingletonLogger() : has_error_(false), start_(-1), end_(-1) { } | |
| 3686 virtual ~SingletonLogger() { } | |
| 3687 | |
| 3688 void Reset() { has_error_ = false; } | |
| 3689 | |
| 3690 virtual void LogFunction(int start, | |
| 3691 int end, | |
| 3692 int literals, | |
| 3693 int properties, | |
| 3694 LanguageMode mode) { | |
| 3695 ASSERT(!has_error_); | |
| 3696 start_ = start; | |
| 3697 end_ = end; | |
| 3698 literals_ = literals; | |
| 3699 properties_ = properties; | |
| 3700 mode_ = mode; | |
| 3701 }; | |
| 3702 | |
| 3703 // Logs a symbol creation of a literal or identifier. | |
| 3704 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } | |
| 3705 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { } | |
| 3706 | |
| 3707 // Logs an error message and marks the log as containing an error. | |
| 3708 // Further logging will be ignored, and ExtractData will return a vector | |
| 3709 // representing the error only. | |
| 3710 virtual void LogMessage(int start, | |
| 3711 int end, | |
| 3712 const char* message, | |
| 3713 const char* argument_opt) { | |
| 3714 if (has_error_) return; | |
| 3715 has_error_ = true; | |
| 3716 start_ = start; | |
| 3717 end_ = end; | |
| 3718 message_ = message; | |
| 3719 argument_opt_ = argument_opt; | |
| 3720 } | |
| 3721 | |
| 3722 virtual int function_position() { return 0; } | |
| 3723 | |
| 3724 virtual int symbol_position() { return 0; } | |
| 3725 | |
| 3726 virtual int symbol_ids() { return -1; } | |
| 3727 | |
| 3728 virtual Vector<unsigned> ExtractData() { | |
| 3729 UNREACHABLE(); | |
| 3730 return Vector<unsigned>(); | |
| 3731 } | |
| 3732 | |
| 3733 virtual void PauseRecording() { } | |
| 3734 | |
| 3735 virtual void ResumeRecording() { } | |
| 3736 | |
| 3737 bool has_error() { return has_error_; } | |
| 3738 | |
| 3739 int start() { return start_; } | |
| 3740 int end() { return end_; } | |
| 3741 int literals() { | |
| 3742 ASSERT(!has_error_); | |
| 3743 return literals_; | |
| 3744 } | |
| 3745 int properties() { | |
| 3746 ASSERT(!has_error_); | |
| 3747 return properties_; | |
| 3748 } | |
| 3749 LanguageMode language_mode() { | |
| 3750 ASSERT(!has_error_); | |
| 3751 return mode_; | |
| 3752 } | |
| 3753 const char* message() { | |
| 3754 ASSERT(has_error_); | |
| 3755 return message_; | |
| 3756 } | |
| 3757 const char* argument_opt() { | |
| 3758 ASSERT(has_error_); | |
| 3759 return argument_opt_; | |
| 3760 } | |
| 3761 | |
| 3762 private: | |
| 3763 bool has_error_; | |
| 3764 int start_; | |
| 3765 int end_; | |
| 3766 // For function entries. | |
| 3767 int literals_; | |
| 3768 int properties_; | |
| 3769 LanguageMode mode_; | |
| 3770 // For error messages. | |
| 3771 const char* message_; | |
| 3772 const char* argument_opt_; | |
| 3773 }; | |
| 3774 | |
| 3775 | |
| 3776 FunctionLiteral* Parser::ParseFunctionLiteral( | 3450 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 3777 Handle<String> function_name, | 3451 Handle<String> function_name, |
| 3778 Scanner::Location function_name_location, | 3452 Scanner::Location function_name_location, |
| 3779 bool name_is_strict_reserved, | 3453 bool name_is_strict_reserved, |
| 3780 bool is_generator, | 3454 bool is_generator, |
| 3781 int function_token_pos, | 3455 int function_token_pos, |
| 3782 FunctionLiteral::FunctionType function_type, | 3456 FunctionLiteral::FunctionType function_type, |
| 3783 bool* ok) { | 3457 bool* ok) { |
| 3784 // Function :: | 3458 // Function :: |
| 3785 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3459 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3821 // under which we compile is _not_ a declaration scope. This holds because | 3495 // under which we compile is _not_ a declaration scope. This holds because |
| 3822 // in all normal cases, function declarations are fully hoisted to a | 3496 // in all normal cases, function declarations are fully hoisted to a |
| 3823 // declaration scope and compiled relative to that. | 3497 // declaration scope and compiled relative to that. |
| 3824 // - (2) is the case iff the current declaration scope is still the original | 3498 // - (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 | 3499 // 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 | 3500 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 3827 // nested function, and hoisting works normally relative to that. | 3501 // nested function, and hoisting works normally relative to that. |
| 3828 Scope* declaration_scope = scope_->DeclarationScope(); | 3502 Scope* declaration_scope = scope_->DeclarationScope(); |
| 3829 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | 3503 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
| 3830 Scope* scope = | 3504 Scope* scope = |
| 3831 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && | 3505 function_type == FunctionLiteral::DECLARATION && |
| 3506 (!FLAG_harmony_scoping || strict_mode() == SLOPPY) && |
| 3832 (original_scope_ == original_declaration_scope || | 3507 (original_scope_ == original_declaration_scope || |
| 3833 declaration_scope != original_declaration_scope) | 3508 declaration_scope != original_declaration_scope) |
| 3834 ? NewScope(declaration_scope, FUNCTION_SCOPE) | 3509 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 3835 : NewScope(scope_, FUNCTION_SCOPE); | 3510 : NewScope(scope_, FUNCTION_SCOPE); |
| 3836 ZoneList<Statement*>* body = NULL; | 3511 ZoneList<Statement*>* body = NULL; |
| 3837 int materialized_literal_count = -1; | 3512 int materialized_literal_count = -1; |
| 3838 int expected_property_count = -1; | 3513 int expected_property_count = -1; |
| 3839 int handler_count = 0; | 3514 int handler_count = 0; |
| 3840 FunctionLiteral::ParameterFlag duplicate_parameters = | 3515 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 3841 FunctionLiteral::kNoDuplicateParameters; | 3516 FunctionLiteral::kNoDuplicateParameters; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3910 | 3585 |
| 3911 Expect(Token::LBRACE, CHECK_OK); | 3586 Expect(Token::LBRACE, CHECK_OK); |
| 3912 | 3587 |
| 3913 // If we have a named function expression, we add a local variable | 3588 // 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 | 3589 // declaration to the body of the function with the name of the |
| 3915 // function and let it refer to the function itself (closure). | 3590 // function and let it refer to the function itself (closure). |
| 3916 // NOTE: We create a proxy and resolve it here so that in the | 3591 // 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 | 3592 // future we can change the AST to only refer to VariableProxies |
| 3918 // instead of Variables and Proxis as is the case now. | 3593 // instead of Variables and Proxis as is the case now. |
| 3919 Variable* fvar = NULL; | 3594 Variable* fvar = NULL; |
| 3920 Token::Value fvar_init_op = Token::INIT_CONST; | 3595 Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| 3921 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { | 3596 if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| 3922 if (is_extended_mode()) fvar_init_op = Token::INIT_CONST_HARMONY; | 3597 if (FLAG_harmony_scoping && strict_mode() == STRICT) { |
| 3923 VariableMode fvar_mode = is_extended_mode() ? CONST_HARMONY : CONST; | 3598 fvar_init_op = Token::INIT_CONST; |
| 3599 } |
| 3600 VariableMode fvar_mode = FLAG_harmony_scoping && strict_mode() == STRICT |
| 3601 ? CONST : CONST_LEGACY; |
| 3924 fvar = new(zone()) Variable(scope_, | 3602 fvar = new(zone()) Variable(scope_, |
| 3925 function_name, fvar_mode, true /* is valid LHS */, | 3603 function_name, fvar_mode, true /* is valid LHS */, |
| 3926 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); | 3604 Variable::NORMAL, kCreatedInitialized, Interface::NewConst()); |
| 3927 VariableProxy* proxy = factory()->NewVariableProxy(fvar); | 3605 VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| 3928 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( | 3606 VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| 3929 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); | 3607 proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| 3930 scope_->DeclareFunctionVar(fvar_declaration); | 3608 scope_->DeclareFunctionVar(fvar_declaration); |
| 3931 } | 3609 } |
| 3932 | 3610 |
| 3933 // Determine if the function can be parsed lazily. Lazy parsing is different | 3611 // Determine if the function can be parsed lazily. Lazy parsing is different |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3983 ReportInvalidPreparseData(function_name, CHECK_OK); | 3661 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 3984 } | 3662 } |
| 3985 scanner()->SeekForward(entry.end_pos() - 1); | 3663 scanner()->SeekForward(entry.end_pos() - 1); |
| 3986 | 3664 |
| 3987 scope->set_end_position(entry.end_pos()); | 3665 scope->set_end_position(entry.end_pos()); |
| 3988 Expect(Token::RBRACE, CHECK_OK); | 3666 Expect(Token::RBRACE, CHECK_OK); |
| 3989 isolate()->counters()->total_preparse_skipped()->Increment( | 3667 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3990 scope->end_position() - function_block_pos); | 3668 scope->end_position() - function_block_pos); |
| 3991 materialized_literal_count = entry.literal_count(); | 3669 materialized_literal_count = entry.literal_count(); |
| 3992 expected_property_count = entry.property_count(); | 3670 expected_property_count = entry.property_count(); |
| 3993 scope_->SetLanguageMode(entry.language_mode()); | 3671 scope_->SetStrictMode(entry.strict_mode()); |
| 3994 } else { | 3672 } else { |
| 3995 // This case happens when we have preparse data but it doesn't contain | 3673 // This case happens when we have preparse data but it doesn't contain |
| 3996 // an entry for the function. As a safety net, fall back to eager | 3674 // an entry for the function. As a safety net, fall back to eager |
| 3997 // parsing. It is unclear whether PreParser's laziness analysis can | 3675 // parsing. It is unclear whether PreParser's laziness analysis can |
| 3998 // produce different results than the Parser's laziness analysis (see | 3676 // produce different results than the Parser's laziness analysis (see |
| 3999 // https://codereview.chromium.org/7565003 ). This safety net is | 3677 // https://codereview.chromium.org/7565003 ). This safety net is |
| 4000 // guarding against the case where Parser thinks a function should be | 3678 // guarding against the case where Parser thinks a function should be |
| 4001 // lazily parsed, but PreParser thinks it should be eagerly parsed -- | 3679 // lazily parsed, but PreParser thinks it should be eagerly parsed -- |
| 4002 // in that case we fall back to eager parsing in Parser, too. Note | 3680 // 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 | 3681 // that the opposite case is worse: if PreParser thinks a function |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4031 args); | 3709 args); |
| 4032 *ok = false; | 3710 *ok = false; |
| 4033 return NULL; | 3711 return NULL; |
| 4034 } | 3712 } |
| 4035 scope->set_end_position(logger.end()); | 3713 scope->set_end_position(logger.end()); |
| 4036 Expect(Token::RBRACE, CHECK_OK); | 3714 Expect(Token::RBRACE, CHECK_OK); |
| 4037 isolate()->counters()->total_preparse_skipped()->Increment( | 3715 isolate()->counters()->total_preparse_skipped()->Increment( |
| 4038 scope->end_position() - function_block_pos); | 3716 scope->end_position() - function_block_pos); |
| 4039 materialized_literal_count = logger.literals(); | 3717 materialized_literal_count = logger.literals(); |
| 4040 expected_property_count = logger.properties(); | 3718 expected_property_count = logger.properties(); |
| 4041 scope_->SetLanguageMode(logger.language_mode()); | 3719 scope_->SetStrictMode(logger.strict_mode()); |
| 4042 } | 3720 } |
| 4043 } | 3721 } |
| 4044 | 3722 |
| 4045 if (!is_lazily_parsed) { | 3723 if (!is_lazily_parsed) { |
| 4046 // Everything inside an eagerly parsed function will be parsed eagerly | 3724 // Everything inside an eagerly parsed function will be parsed eagerly |
| 4047 // (see comment above). | 3725 // (see comment above). |
| 4048 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3726 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 4049 body = new(zone()) ZoneList<Statement*>(8, zone()); | 3727 body = new(zone()) ZoneList<Statement*>(8, zone()); |
| 4050 if (fvar != NULL) { | 3728 if (fvar != NULL) { |
| 4051 VariableProxy* fproxy = scope_->NewUnresolved( | 3729 VariableProxy* fproxy = scope_->NewUnresolved( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4095 materialized_literal_count = function_state.materialized_literal_count(); | 3773 materialized_literal_count = function_state.materialized_literal_count(); |
| 4096 expected_property_count = function_state.expected_property_count(); | 3774 expected_property_count = function_state.expected_property_count(); |
| 4097 handler_count = function_state.handler_count(); | 3775 handler_count = function_state.handler_count(); |
| 4098 | 3776 |
| 4099 Expect(Token::RBRACE, CHECK_OK); | 3777 Expect(Token::RBRACE, CHECK_OK); |
| 4100 scope->set_end_position(scanner()->location().end_pos); | 3778 scope->set_end_position(scanner()->location().end_pos); |
| 4101 } | 3779 } |
| 4102 | 3780 |
| 4103 // Validate strict mode. We can do this only after parsing the function, | 3781 // Validate strict mode. We can do this only after parsing the function, |
| 4104 // since the function can declare itself strict. | 3782 // since the function can declare itself strict. |
| 4105 if (!scope_->is_classic_mode()) { | 3783 if (strict_mode() == STRICT) { |
| 4106 if (IsEvalOrArguments(function_name)) { | 3784 if (IsEvalOrArguments(function_name)) { |
| 4107 ReportMessageAt(function_name_location, "strict_eval_arguments"); | 3785 ReportMessageAt(function_name_location, "strict_eval_arguments"); |
| 4108 *ok = false; | 3786 *ok = false; |
| 4109 return NULL; | 3787 return NULL; |
| 4110 } | 3788 } |
| 4111 if (name_is_strict_reserved) { | 3789 if (name_is_strict_reserved) { |
| 4112 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); | 3790 ReportMessageAt(function_name_location, "unexpected_strict_reserved"); |
| 4113 *ok = false; | 3791 *ok = false; |
| 4114 return NULL; | 3792 return NULL; |
| 4115 } | 3793 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4130 } | 3808 } |
| 4131 CheckOctalLiteral(scope->start_position(), | 3809 CheckOctalLiteral(scope->start_position(), |
| 4132 scope->end_position(), | 3810 scope->end_position(), |
| 4133 CHECK_OK); | 3811 CHECK_OK); |
| 4134 } | 3812 } |
| 4135 ast_properties = *factory()->visitor()->ast_properties(); | 3813 ast_properties = *factory()->visitor()->ast_properties(); |
| 4136 slot_processor = factory()->visitor()->slot_processor(); | 3814 slot_processor = factory()->visitor()->slot_processor(); |
| 4137 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 3815 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| 4138 } | 3816 } |
| 4139 | 3817 |
| 4140 if (is_extended_mode()) { | 3818 if (FLAG_harmony_scoping && strict_mode() == STRICT) { |
| 4141 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3819 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4142 } | 3820 } |
| 4143 | 3821 |
| 4144 FunctionLiteral* function_literal = | 3822 FunctionLiteral* function_literal = |
| 4145 factory()->NewFunctionLiteral(function_name, | 3823 factory()->NewFunctionLiteral(function_name, |
| 4146 scope, | 3824 scope, |
| 4147 body, | 3825 body, |
| 4148 materialized_literal_count, | 3826 materialized_literal_count, |
| 4149 expected_property_count, | 3827 expected_property_count, |
| 4150 handler_count, | 3828 handler_count, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4176 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3854 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 4177 reusable_preparser_->set_allow_modules(allow_modules()); | 3855 reusable_preparser_->set_allow_modules(allow_modules()); |
| 4178 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3856 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 4179 reusable_preparser_->set_allow_lazy(true); | 3857 reusable_preparser_->set_allow_lazy(true); |
| 4180 reusable_preparser_->set_allow_generators(allow_generators()); | 3858 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4181 reusable_preparser_->set_allow_for_of(allow_for_of()); | 3859 reusable_preparser_->set_allow_for_of(allow_for_of()); |
| 4182 reusable_preparser_->set_allow_harmony_numeric_literals( | 3860 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 4183 allow_harmony_numeric_literals()); | 3861 allow_harmony_numeric_literals()); |
| 4184 } | 3862 } |
| 4185 PreParser::PreParseResult result = | 3863 PreParser::PreParseResult result = |
| 4186 reusable_preparser_->PreParseLazyFunction(scope_->language_mode(), | 3864 reusable_preparser_->PreParseLazyFunction(strict_mode(), |
| 4187 is_generator(), | 3865 is_generator(), |
| 4188 logger); | 3866 logger); |
| 4189 return result; | 3867 return result; |
| 4190 } | 3868 } |
| 4191 | 3869 |
| 4192 | 3870 |
| 4193 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3871 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4194 // CallRuntime :: | 3872 // CallRuntime :: |
| 4195 // '%' Identifier Arguments | 3873 // '%' Identifier Arguments |
| 4196 | 3874 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4245 return factory()->NewCallRuntime(name, function, args, pos); | 3923 return factory()->NewCallRuntime(name, function, args, pos); |
| 4246 } | 3924 } |
| 4247 | 3925 |
| 4248 | 3926 |
| 4249 Literal* Parser::GetLiteralUndefined(int position) { | 3927 Literal* Parser::GetLiteralUndefined(int position) { |
| 4250 return factory()->NewLiteral( | 3928 return factory()->NewLiteral( |
| 4251 isolate()->factory()->undefined_value(), position); | 3929 isolate()->factory()->undefined_value(), position); |
| 4252 } | 3930 } |
| 4253 | 3931 |
| 4254 | 3932 |
| 4255 void Parser::MarkAsLValue(Expression* expression) { | |
| 4256 VariableProxy* proxy = expression != NULL | |
| 4257 ? expression->AsVariableProxy() | |
| 4258 : NULL; | |
| 4259 | |
| 4260 if (proxy != NULL) proxy->MarkAsLValue(); | |
| 4261 } | |
| 4262 | |
| 4263 | |
| 4264 // Checks LHS expression for assignment and prefix/postfix increment/decrement | |
| 4265 // in strict mode. | |
| 4266 void Parser::CheckStrictModeLValue(Expression* expression, | |
| 4267 bool* ok) { | |
| 4268 ASSERT(!scope_->is_classic_mode()); | |
| 4269 VariableProxy* lhs = expression != NULL | |
| 4270 ? expression->AsVariableProxy() | |
| 4271 : NULL; | |
| 4272 | |
| 4273 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | |
| 4274 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | |
| 4275 *ok = false; | |
| 4276 } | |
| 4277 } | |
| 4278 | |
| 4279 | |
| 4280 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3933 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4281 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3934 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4282 if (decl != NULL) { | 3935 if (decl != NULL) { |
| 4283 // In harmony mode we treat conflicting variable bindinds as early | 3936 // In harmony mode we treat conflicting variable bindinds as early |
| 4284 // errors. See ES5 16 for a definition of early errors. | 3937 // errors. See ES5 16 for a definition of early errors. |
| 4285 Handle<String> name = decl->proxy()->name(); | 3938 Handle<String> name = decl->proxy()->name(); |
| 4286 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 3939 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4287 const char* elms[2] = { "Variable", c_string.get() }; | 3940 const char* elms[2] = { "Variable", c_string.get() }; |
| 4288 Vector<const char*> args(elms, 2); | 3941 Vector<const char*> args(elms, 2); |
| 4289 int position = decl->proxy()->position(); | 3942 int position = decl->proxy()->position(); |
| (...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4987 Reset(start); | 4640 Reset(start); |
| 4988 return false; | 4641 return false; |
| 4989 } | 4642 } |
| 4990 *min_out = min; | 4643 *min_out = min; |
| 4991 *max_out = max; | 4644 *max_out = max; |
| 4992 return true; | 4645 return true; |
| 4993 } | 4646 } |
| 4994 | 4647 |
| 4995 | 4648 |
| 4996 uc32 RegExpParser::ParseOctalLiteral() { | 4649 uc32 RegExpParser::ParseOctalLiteral() { |
| 4997 ASSERT('0' <= current() && current() <= '7'); | 4650 ASSERT(('0' <= current() && current() <= '7') || current() == kEndMarker); |
| 4998 // For compatibility with some other browsers (not all), we parse | 4651 // For compatibility with some other browsers (not all), we parse |
| 4999 // up to three octal digits with a value below 256. | 4652 // up to three octal digits with a value below 256. |
| 5000 uc32 value = current() - '0'; | 4653 uc32 value = current() - '0'; |
| 5001 Advance(); | 4654 Advance(); |
| 5002 if ('0' <= current() && current() <= '7') { | 4655 if ('0' <= current() && current() <= '7') { |
| 5003 value = value * 8 + current() - '0'; | 4656 value = value * 8 + current() - '0'; |
| 5004 Advance(); | 4657 Advance(); |
| 5005 if (value < 32 && '0' <= current() && current() <= '7') { | 4658 if (value < 32 && '0' <= current() && current() <= '7') { |
| 5006 value = value * 8 + current() - '0'; | 4659 value = value * 8 + current() - '0'; |
| 5007 Advance(); | 4660 Advance(); |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5353 ASSERT(info()->isolate()->has_pending_exception()); | 5006 ASSERT(info()->isolate()->has_pending_exception()); |
| 5354 } else { | 5007 } else { |
| 5355 result = ParseProgram(); | 5008 result = ParseProgram(); |
| 5356 } | 5009 } |
| 5357 } | 5010 } |
| 5358 info()->SetFunction(result); | 5011 info()->SetFunction(result); |
| 5359 return (result != NULL); | 5012 return (result != NULL); |
| 5360 } | 5013 } |
| 5361 | 5014 |
| 5362 } } // namespace v8::internal | 5015 } } // namespace v8::internal |
| OLD | NEW |