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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 reusable_preparser_(NULL), | 542 reusable_preparser_(NULL), |
543 top_scope_(NULL), | 543 top_scope_(NULL), |
544 current_function_state_(NULL), | 544 current_function_state_(NULL), |
545 target_stack_(NULL), | 545 target_stack_(NULL), |
546 extension_(info->extension()), | 546 extension_(info->extension()), |
547 pre_parse_data_(NULL), | 547 pre_parse_data_(NULL), |
548 fni_(NULL), | 548 fni_(NULL), |
549 allow_natives_syntax_(false), | 549 allow_natives_syntax_(false), |
550 allow_lazy_(false), | 550 allow_lazy_(false), |
551 allow_generators_(false), | 551 allow_generators_(false), |
| 552 allow_for_of_(false), |
552 stack_overflow_(false), | 553 stack_overflow_(false), |
553 parenthesized_function_(false), | 554 parenthesized_function_(false), |
554 zone_(info->zone()), | 555 zone_(info->zone()), |
555 info_(info) { | 556 info_(info) { |
556 ASSERT(!script_.is_null()); | 557 ASSERT(!script_.is_null()); |
557 isolate_->set_ast_node_id(0); | 558 isolate_->set_ast_node_id(0); |
558 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 559 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
559 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 560 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
560 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 561 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
561 set_allow_lazy(false); // Must be explicitly enabled. | 562 set_allow_lazy(false); // Must be explicitly enabled. |
562 set_allow_generators(FLAG_harmony_generators); | 563 set_allow_generators(FLAG_harmony_generators); |
| 564 set_allow_for_of(FLAG_harmony_iteration); |
563 } | 565 } |
564 | 566 |
565 | 567 |
566 FunctionLiteral* Parser::ParseProgram() { | 568 FunctionLiteral* Parser::ParseProgram() { |
567 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); | 569 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); |
568 HistogramTimerScope timer(isolate()->counters()->parse()); | 570 HistogramTimerScope timer(isolate()->counters()->parse()); |
569 Handle<String> source(String::cast(script_->source())); | 571 Handle<String> source(String::cast(script_->source())); |
570 isolate()->counters()->total_parse_size()->Increment(source->length()); | 572 isolate()->counters()->total_parse_size()->Increment(source->length()); |
571 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; | 573 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; |
572 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 574 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 return ParseModuleLiteral(ok); | 1023 return ParseModuleLiteral(ok); |
1022 | 1024 |
1023 case Token::ASSIGN: { | 1025 case Token::ASSIGN: { |
1024 Expect(Token::ASSIGN, CHECK_OK); | 1026 Expect(Token::ASSIGN, CHECK_OK); |
1025 Module* result = ParseModulePath(CHECK_OK); | 1027 Module* result = ParseModulePath(CHECK_OK); |
1026 ExpectSemicolon(CHECK_OK); | 1028 ExpectSemicolon(CHECK_OK); |
1027 return result; | 1029 return result; |
1028 } | 1030 } |
1029 | 1031 |
1030 default: { | 1032 default: { |
1031 ExpectContextualKeyword("at", CHECK_OK); | 1033 ExpectContextualKeyword(CStrVector("at"), CHECK_OK); |
1032 Module* result = ParseModuleUrl(CHECK_OK); | 1034 Module* result = ParseModuleUrl(CHECK_OK); |
1033 ExpectSemicolon(CHECK_OK); | 1035 ExpectSemicolon(CHECK_OK); |
1034 return result; | 1036 return result; |
1035 } | 1037 } |
1036 } | 1038 } |
1037 } | 1039 } |
1038 | 1040 |
1039 | 1041 |
1040 Module* Parser::ParseModuleLiteral(bool* ok) { | 1042 Module* Parser::ParseModuleLiteral(bool* ok) { |
1041 // Module: | 1043 // Module: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 ZoneStringList names(1, zone()); | 1195 ZoneStringList names(1, zone()); |
1194 | 1196 |
1195 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1197 Handle<String> name = ParseIdentifierName(CHECK_OK); |
1196 names.Add(name, zone()); | 1198 names.Add(name, zone()); |
1197 while (peek() == Token::COMMA) { | 1199 while (peek() == Token::COMMA) { |
1198 Consume(Token::COMMA); | 1200 Consume(Token::COMMA); |
1199 name = ParseIdentifierName(CHECK_OK); | 1201 name = ParseIdentifierName(CHECK_OK); |
1200 names.Add(name, zone()); | 1202 names.Add(name, zone()); |
1201 } | 1203 } |
1202 | 1204 |
1203 ExpectContextualKeyword("from", CHECK_OK); | 1205 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1204 Module* module = ParseModuleSpecifier(CHECK_OK); | 1206 Module* module = ParseModuleSpecifier(CHECK_OK); |
1205 ExpectSemicolon(CHECK_OK); | 1207 ExpectSemicolon(CHECK_OK); |
1206 | 1208 |
1207 // Generate a separate declaration for each identifier. | 1209 // Generate a separate declaration for each identifier. |
1208 // TODO(ES6): once we implement destructuring, make that one declaration. | 1210 // TODO(ES6): once we implement destructuring, make that one declaration. |
1209 Block* block = factory()->NewBlock(NULL, 1, true); | 1211 Block* block = factory()->NewBlock(NULL, 1, true); |
1210 for (int i = 0; i < names.length(); ++i) { | 1212 for (int i = 0; i < names.length(); ++i) { |
1211 #ifdef DEBUG | 1213 #ifdef DEBUG |
1212 if (FLAG_print_interface_details) | 1214 if (FLAG_print_interface_details) |
1213 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1215 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 Expect(Token::LPAREN, CHECK_OK); | 2617 Expect(Token::LPAREN, CHECK_OK); |
2616 Expression* cond = ParseExpression(true, CHECK_OK); | 2618 Expression* cond = ParseExpression(true, CHECK_OK); |
2617 Expect(Token::RPAREN, CHECK_OK); | 2619 Expect(Token::RPAREN, CHECK_OK); |
2618 Statement* body = ParseStatement(NULL, CHECK_OK); | 2620 Statement* body = ParseStatement(NULL, CHECK_OK); |
2619 | 2621 |
2620 if (loop != NULL) loop->Initialize(cond, body); | 2622 if (loop != NULL) loop->Initialize(cond, body); |
2621 return loop; | 2623 return loop; |
2622 } | 2624 } |
2623 | 2625 |
2624 | 2626 |
| 2627 bool Parser::CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { |
| 2628 if (Check(Token::IN)) { |
| 2629 *visit_mode = ForEachStatement::ENUMERATE; |
| 2630 return true; |
| 2631 } else if (allow_for_of() && CheckContextualKeyword(CStrVector("of"))) { |
| 2632 *visit_mode = ForEachStatement::ITERATE; |
| 2633 return true; |
| 2634 } |
| 2635 return false; |
| 2636 } |
| 2637 |
| 2638 |
2625 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2639 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2626 // ForStatement :: | 2640 // ForStatement :: |
2627 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2641 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2628 | 2642 |
2629 Statement* init = NULL; | 2643 Statement* init = NULL; |
2630 | 2644 |
2631 // Create an in-between scope for let-bound iteration variables. | 2645 // Create an in-between scope for let-bound iteration variables. |
2632 Scope* saved_scope = top_scope_; | 2646 Scope* saved_scope = top_scope_; |
2633 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2647 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2634 top_scope_ = for_scope; | 2648 top_scope_ = for_scope; |
2635 | 2649 |
2636 Expect(Token::FOR, CHECK_OK); | 2650 Expect(Token::FOR, CHECK_OK); |
2637 Expect(Token::LPAREN, CHECK_OK); | 2651 Expect(Token::LPAREN, CHECK_OK); |
2638 for_scope->set_start_position(scanner().location().beg_pos); | 2652 for_scope->set_start_position(scanner().location().beg_pos); |
2639 if (peek() != Token::SEMICOLON) { | 2653 if (peek() != Token::SEMICOLON) { |
2640 if (peek() == Token::VAR || peek() == Token::CONST) { | 2654 if (peek() == Token::VAR || peek() == Token::CONST) { |
2641 bool is_const = peek() == Token::CONST; | 2655 bool is_const = peek() == Token::CONST; |
2642 Handle<String> name; | 2656 Handle<String> name; |
2643 Block* variable_statement = | 2657 Block* variable_statement = |
2644 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); | 2658 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); |
| 2659 ForEachStatement::VisitMode mode; |
2645 | 2660 |
2646 if (peek() == Token::IN && !name.is_null()) { | 2661 if (!name.is_null() && CheckInOrOf(&mode)) { |
2647 Interface* interface = | 2662 Interface* interface = |
2648 is_const ? Interface::NewConst() : Interface::NewValue(); | 2663 is_const ? Interface::NewConst() : Interface::NewValue(); |
2649 ForInStatement* loop = factory()->NewForInStatement(labels); | 2664 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2650 Target target(&this->target_stack_, loop); | 2665 Target target(&this->target_stack_, loop); |
2651 | 2666 |
2652 Expect(Token::IN, CHECK_OK); | |
2653 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2667 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2654 Expect(Token::RPAREN, CHECK_OK); | 2668 Expect(Token::RPAREN, CHECK_OK); |
2655 | 2669 |
2656 VariableProxy* each = | 2670 VariableProxy* each = |
2657 top_scope_->NewUnresolved(factory(), name, interface); | 2671 top_scope_->NewUnresolved(factory(), name, interface); |
2658 Statement* body = ParseStatement(NULL, CHECK_OK); | 2672 Statement* body = ParseStatement(NULL, CHECK_OK); |
2659 loop->Initialize(each, enumerable, body); | 2673 loop->Initialize(each, enumerable, body); |
2660 Block* result = factory()->NewBlock(NULL, 2, false); | 2674 Block* result = factory()->NewBlock(NULL, 2, false); |
2661 result->AddStatement(variable_statement, zone()); | 2675 result->AddStatement(variable_statement, zone()); |
2662 result->AddStatement(loop, zone()); | 2676 result->AddStatement(loop, zone()); |
2663 top_scope_ = saved_scope; | 2677 top_scope_ = saved_scope; |
2664 for_scope->set_end_position(scanner().location().end_pos); | 2678 for_scope->set_end_position(scanner().location().end_pos); |
2665 for_scope = for_scope->FinalizeBlockScope(); | 2679 for_scope = for_scope->FinalizeBlockScope(); |
2666 ASSERT(for_scope == NULL); | 2680 ASSERT(for_scope == NULL); |
2667 // Parsed for-in loop w/ variable/const declaration. | 2681 // Parsed for-in loop w/ variable/const declaration. |
2668 return result; | 2682 return result; |
2669 } else { | 2683 } else { |
2670 init = variable_statement; | 2684 init = variable_statement; |
2671 } | 2685 } |
2672 } else if (peek() == Token::LET) { | 2686 } else if (peek() == Token::LET) { |
2673 Handle<String> name; | 2687 Handle<String> name; |
2674 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2688 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2675 Block* variable_statement = | 2689 Block* variable_statement = |
2676 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2690 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
2677 CHECK_OK); | 2691 CHECK_OK); |
2678 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2692 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
2679 if (peek() == Token::IN && accept_IN) { | 2693 ForEachStatement::VisitMode mode; |
| 2694 |
| 2695 if (accept_IN && CheckInOrOf(&mode)) { |
2680 // Rewrite a for-in statement of the form | 2696 // Rewrite a for-in statement of the form |
2681 // | 2697 // |
2682 // for (let x in e) b | 2698 // for (let x in e) b |
2683 // | 2699 // |
2684 // into | 2700 // into |
2685 // | 2701 // |
2686 // <let x' be a temporary variable> | 2702 // <let x' be a temporary variable> |
2687 // for (x' in e) { | 2703 // for (x' in e) { |
2688 // let x; | 2704 // let x; |
2689 // x = x'; | 2705 // x = x'; |
2690 // b; | 2706 // b; |
2691 // } | 2707 // } |
2692 | 2708 |
2693 // TODO(keuchel): Move the temporary variable to the block scope, after | 2709 // TODO(keuchel): Move the temporary variable to the block scope, after |
2694 // implementing stack allocated block scoped variables. | 2710 // implementing stack allocated block scoped variables. |
2695 Factory* heap_factory = isolate()->factory(); | 2711 Factory* heap_factory = isolate()->factory(); |
2696 Handle<String> tempstr = | 2712 Handle<String> tempstr = |
2697 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2713 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
2698 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2714 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
2699 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2715 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
2700 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2716 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2701 ForInStatement* loop = factory()->NewForInStatement(labels); | 2717 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2702 Target target(&this->target_stack_, loop); | 2718 Target target(&this->target_stack_, loop); |
2703 | 2719 |
2704 // The expression does not see the loop variable. | 2720 // The expression does not see the loop variable. |
2705 Expect(Token::IN, CHECK_OK); | |
2706 top_scope_ = saved_scope; | 2721 top_scope_ = saved_scope; |
2707 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2722 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2708 top_scope_ = for_scope; | 2723 top_scope_ = for_scope; |
2709 Expect(Token::RPAREN, CHECK_OK); | 2724 Expect(Token::RPAREN, CHECK_OK); |
2710 | 2725 |
2711 VariableProxy* each = | 2726 VariableProxy* each = |
2712 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2727 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2713 Statement* body = ParseStatement(NULL, CHECK_OK); | 2728 Statement* body = ParseStatement(NULL, CHECK_OK); |
2714 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2729 Block* body_block = factory()->NewBlock(NULL, 3, false); |
2715 Assignment* assignment = factory()->NewAssignment( | 2730 Assignment* assignment = factory()->NewAssignment( |
2716 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2731 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2717 Statement* assignment_statement = | 2732 Statement* assignment_statement = |
2718 factory()->NewExpressionStatement(assignment); | 2733 factory()->NewExpressionStatement(assignment); |
2719 body_block->AddStatement(variable_statement, zone()); | 2734 body_block->AddStatement(variable_statement, zone()); |
2720 body_block->AddStatement(assignment_statement, zone()); | 2735 body_block->AddStatement(assignment_statement, zone()); |
2721 body_block->AddStatement(body, zone()); | 2736 body_block->AddStatement(body, zone()); |
2722 loop->Initialize(temp_proxy, enumerable, body_block); | 2737 loop->Initialize(temp_proxy, enumerable, body_block); |
2723 top_scope_ = saved_scope; | 2738 top_scope_ = saved_scope; |
2724 for_scope->set_end_position(scanner().location().end_pos); | 2739 for_scope->set_end_position(scanner().location().end_pos); |
2725 for_scope = for_scope->FinalizeBlockScope(); | 2740 for_scope = for_scope->FinalizeBlockScope(); |
2726 body_block->set_scope(for_scope); | 2741 body_block->set_scope(for_scope); |
2727 // Parsed for-in loop w/ let declaration. | 2742 // Parsed for-in loop w/ let declaration. |
2728 return loop; | 2743 return loop; |
2729 | 2744 |
2730 } else { | 2745 } else { |
2731 init = variable_statement; | 2746 init = variable_statement; |
2732 } | 2747 } |
2733 } else { | 2748 } else { |
2734 Expression* expression = ParseExpression(false, CHECK_OK); | 2749 Expression* expression = ParseExpression(false, CHECK_OK); |
2735 if (peek() == Token::IN) { | 2750 ForEachStatement::VisitMode mode; |
| 2751 |
| 2752 if (CheckInOrOf(&mode)) { |
2736 // Signal a reference error if the expression is an invalid | 2753 // Signal a reference error if the expression is an invalid |
2737 // left-hand side expression. We could report this as a syntax | 2754 // left-hand side expression. We could report this as a syntax |
2738 // error here but for compatibility with JSC we choose to report | 2755 // error here but for compatibility with JSC we choose to report |
2739 // the error at runtime. | 2756 // the error at runtime. |
2740 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2757 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2741 Handle<String> message = | 2758 Handle<String> message = |
2742 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2759 isolate()->factory()->invalid_lhs_in_for_in_string(); |
2743 expression = NewThrowReferenceError(message); | 2760 expression = NewThrowReferenceError(message); |
2744 } | 2761 } |
2745 ForInStatement* loop = factory()->NewForInStatement(labels); | 2762 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2746 Target target(&this->target_stack_, loop); | 2763 Target target(&this->target_stack_, loop); |
2747 | 2764 |
2748 Expect(Token::IN, CHECK_OK); | |
2749 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2765 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2750 Expect(Token::RPAREN, CHECK_OK); | 2766 Expect(Token::RPAREN, CHECK_OK); |
2751 | 2767 |
2752 Statement* body = ParseStatement(NULL, CHECK_OK); | 2768 Statement* body = ParseStatement(NULL, CHECK_OK); |
2753 if (loop) loop->Initialize(expression, enumerable, body); | 2769 loop->Initialize(expression, enumerable, body); |
2754 top_scope_ = saved_scope; | 2770 top_scope_ = saved_scope; |
2755 for_scope->set_end_position(scanner().location().end_pos); | 2771 for_scope->set_end_position(scanner().location().end_pos); |
2756 for_scope = for_scope->FinalizeBlockScope(); | 2772 for_scope = for_scope->FinalizeBlockScope(); |
2757 ASSERT(for_scope == NULL); | 2773 ASSERT(for_scope == NULL); |
2758 // Parsed for-in loop. | 2774 // Parsed for-in loop. |
2759 return loop; | 2775 return loop; |
2760 | 2776 |
2761 } else { | 2777 } else { |
2762 init = factory()->NewExpressionStatement(expression); | 2778 init = factory()->NewExpressionStatement(expression); |
2763 } | 2779 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2797 // | 2813 // |
2798 // { | 2814 // { |
2799 // let x = i; | 2815 // let x = i; |
2800 // for (; c; n) b | 2816 // for (; c; n) b |
2801 // } | 2817 // } |
2802 ASSERT(init != NULL); | 2818 ASSERT(init != NULL); |
2803 Block* result = factory()->NewBlock(NULL, 2, false); | 2819 Block* result = factory()->NewBlock(NULL, 2, false); |
2804 result->AddStatement(init, zone()); | 2820 result->AddStatement(init, zone()); |
2805 result->AddStatement(loop, zone()); | 2821 result->AddStatement(loop, zone()); |
2806 result->set_scope(for_scope); | 2822 result->set_scope(for_scope); |
2807 if (loop) loop->Initialize(NULL, cond, next, body); | 2823 loop->Initialize(NULL, cond, next, body); |
2808 return result; | 2824 return result; |
2809 } else { | 2825 } else { |
2810 if (loop) loop->Initialize(init, cond, next, body); | 2826 loop->Initialize(init, cond, next, body); |
2811 return loop; | 2827 return loop; |
2812 } | 2828 } |
2813 } | 2829 } |
2814 | 2830 |
2815 | 2831 |
2816 // Precedence = 1 | 2832 // Precedence = 1 |
2817 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { | 2833 Expression* Parser::ParseExpression(bool accept_IN, bool* ok) { |
2818 // Expression :: | 2834 // Expression :: |
2819 // AssignmentExpression | 2835 // AssignmentExpression |
2820 // Expression ',' AssignmentExpression | 2836 // Expression ',' AssignmentExpression |
(...skipping 1679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4500 if (reusable_preparser_ == NULL) { | 4516 if (reusable_preparser_ == NULL) { |
4501 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4517 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
4502 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4518 reusable_preparser_ = new preparser::PreParser(&scanner_, |
4503 NULL, | 4519 NULL, |
4504 stack_limit); | 4520 stack_limit); |
4505 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4521 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4506 reusable_preparser_->set_allow_modules(allow_modules()); | 4522 reusable_preparser_->set_allow_modules(allow_modules()); |
4507 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4523 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
4508 reusable_preparser_->set_allow_lazy(true); | 4524 reusable_preparser_->set_allow_lazy(true); |
4509 reusable_preparser_->set_allow_generators(allow_generators()); | 4525 reusable_preparser_->set_allow_generators(allow_generators()); |
| 4526 reusable_preparser_->set_allow_for_of(allow_for_of()); |
4510 } | 4527 } |
4511 preparser::PreParser::PreParseResult result = | 4528 preparser::PreParser::PreParseResult result = |
4512 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4529 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
4513 is_generator(), | 4530 is_generator(), |
4514 logger); | 4531 logger); |
4515 return result; | 4532 return result; |
4516 } | 4533 } |
4517 | 4534 |
4518 | 4535 |
4519 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4536 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4597 bool Parser::Check(Token::Value token) { | 4614 bool Parser::Check(Token::Value token) { |
4598 Token::Value next = peek(); | 4615 Token::Value next = peek(); |
4599 if (next == token) { | 4616 if (next == token) { |
4600 Consume(next); | 4617 Consume(next); |
4601 return true; | 4618 return true; |
4602 } | 4619 } |
4603 return false; | 4620 return false; |
4604 } | 4621 } |
4605 | 4622 |
4606 | 4623 |
| 4624 bool Parser::CheckContextualKeyword(Vector<const char> keyword) { |
| 4625 if (peek() == Token::IDENTIFIER && |
| 4626 scanner().is_next_contextual_keyword(keyword)) { |
| 4627 Consume(Token::IDENTIFIER); |
| 4628 return true; |
| 4629 } |
| 4630 return false; |
| 4631 } |
| 4632 |
| 4633 |
4607 void Parser::ExpectSemicolon(bool* ok) { | 4634 void Parser::ExpectSemicolon(bool* ok) { |
4608 // Check for automatic semicolon insertion according to | 4635 // Check for automatic semicolon insertion according to |
4609 // the rules given in ECMA-262, section 7.9, page 21. | 4636 // the rules given in ECMA-262, section 7.9, page 21. |
4610 Token::Value tok = peek(); | 4637 Token::Value tok = peek(); |
4611 if (tok == Token::SEMICOLON) { | 4638 if (tok == Token::SEMICOLON) { |
4612 Next(); | 4639 Next(); |
4613 return; | 4640 return; |
4614 } | 4641 } |
4615 if (scanner().HasAnyLineTerminatorBeforeNext() || | 4642 if (scanner().HasAnyLineTerminatorBeforeNext() || |
4616 tok == Token::RBRACE || | 4643 tok == Token::RBRACE || |
4617 tok == Token::EOS) { | 4644 tok == Token::EOS) { |
4618 return; | 4645 return; |
4619 } | 4646 } |
4620 Expect(Token::SEMICOLON, ok); | 4647 Expect(Token::SEMICOLON, ok); |
4621 } | 4648 } |
4622 | 4649 |
4623 | 4650 |
4624 void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) { | 4651 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
4625 Expect(Token::IDENTIFIER, ok); | 4652 Expect(Token::IDENTIFIER, ok); |
4626 if (!*ok) return; | 4653 if (!*ok) return; |
4627 Handle<String> symbol = GetSymbol(); | 4654 if (!scanner().is_literal_contextual_keyword(keyword)) { |
4628 if (!*ok) return; | |
4629 if (!symbol->IsUtf8EqualTo(CStrVector(keyword))) { | |
4630 *ok = false; | 4655 *ok = false; |
4631 ReportUnexpectedToken(scanner().current_token()); | 4656 ReportUnexpectedToken(scanner().current_token()); |
4632 } | 4657 } |
4633 } | 4658 } |
4634 | 4659 |
4635 | 4660 |
4636 Literal* Parser::GetLiteralUndefined() { | 4661 Literal* Parser::GetLiteralUndefined() { |
4637 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4662 return factory()->NewLiteral(isolate()->factory()->undefined_value()); |
4638 } | 4663 } |
4639 | 4664 |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5757 // Create a Scanner for the preparser to use as input, and preparse the source. | 5782 // Create a Scanner for the preparser to use as input, and preparse the source. |
5758 ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { | 5783 ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { |
5759 CompleteParserRecorder recorder; | 5784 CompleteParserRecorder recorder; |
5760 Isolate* isolate = Isolate::Current(); | 5785 Isolate* isolate = Isolate::Current(); |
5761 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5786 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
5762 Scanner scanner(isolate->unicode_cache()); | 5787 Scanner scanner(isolate->unicode_cache()); |
5763 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5788 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
5764 preparser::PreParser preparser(&scanner, &recorder, stack_limit); | 5789 preparser::PreParser preparser(&scanner, &recorder, stack_limit); |
5765 preparser.set_allow_lazy(true); | 5790 preparser.set_allow_lazy(true); |
5766 preparser.set_allow_generators(FLAG_harmony_generators); | 5791 preparser.set_allow_generators(FLAG_harmony_generators); |
| 5792 preparser.set_allow_for_of(FLAG_harmony_iteration); |
5767 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | 5793 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
5768 scanner.Initialize(source); | 5794 scanner.Initialize(source); |
5769 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); | 5795 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); |
5770 if (result == preparser::PreParser::kPreParseStackOverflow) { | 5796 if (result == preparser::PreParser::kPreParseStackOverflow) { |
5771 isolate->StackOverflow(); | 5797 isolate->StackOverflow(); |
5772 return NULL; | 5798 return NULL; |
5773 } | 5799 } |
5774 | 5800 |
5775 // Extract the accumulated data from the recorder as a single | 5801 // Extract the accumulated data from the recorder as a single |
5776 // contiguous vector that we are responsible for disposing. | 5802 // contiguous vector that we are responsible for disposing. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5828 ASSERT(info()->isolate()->has_pending_exception()); | 5854 ASSERT(info()->isolate()->has_pending_exception()); |
5829 } else { | 5855 } else { |
5830 result = ParseProgram(); | 5856 result = ParseProgram(); |
5831 } | 5857 } |
5832 } | 5858 } |
5833 info()->SetFunction(result); | 5859 info()->SetFunction(result); |
5834 return (result != NULL); | 5860 return (result != NULL); |
5835 } | 5861 } |
5836 | 5862 |
5837 } } // namespace v8::internal | 5863 } } // namespace v8::internal |
OLD | NEW |