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 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 reusable_preparser_(NULL), | 544 reusable_preparser_(NULL), |
545 top_scope_(NULL), | 545 top_scope_(NULL), |
546 current_function_state_(NULL), | 546 current_function_state_(NULL), |
547 target_stack_(NULL), | 547 target_stack_(NULL), |
548 extension_(info->extension()), | 548 extension_(info->extension()), |
549 pre_parse_data_(NULL), | 549 pre_parse_data_(NULL), |
550 fni_(NULL), | 550 fni_(NULL), |
551 allow_natives_syntax_(false), | 551 allow_natives_syntax_(false), |
552 allow_lazy_(false), | 552 allow_lazy_(false), |
553 allow_generators_(false), | 553 allow_generators_(false), |
554 allow_for_of_(false), | |
554 stack_overflow_(false), | 555 stack_overflow_(false), |
555 parenthesized_function_(false), | 556 parenthesized_function_(false), |
556 zone_(info->zone()), | 557 zone_(info->zone()), |
557 info_(info) { | 558 info_(info) { |
558 ASSERT(!script_.is_null()); | 559 ASSERT(!script_.is_null()); |
559 isolate_->set_ast_node_id(0); | 560 isolate_->set_ast_node_id(0); |
560 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 561 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
561 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 562 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
562 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 563 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
563 set_allow_lazy(false); // Must be explicitly enabled. | 564 set_allow_lazy(false); // Must be explicitly enabled. |
564 set_allow_generators(FLAG_harmony_generators); | 565 set_allow_generators(FLAG_harmony_generators); |
566 set_allow_for_of(FLAG_harmony_iteration); | |
565 } | 567 } |
566 | 568 |
567 | 569 |
568 FunctionLiteral* Parser::ParseProgram() { | 570 FunctionLiteral* Parser::ParseProgram() { |
569 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); | 571 ZoneScope zone_scope(zone(), DONT_DELETE_ON_EXIT); |
570 HistogramTimerScope timer(isolate()->counters()->parse()); | 572 HistogramTimerScope timer(isolate()->counters()->parse()); |
571 Handle<String> source(String::cast(script_->source())); | 573 Handle<String> source(String::cast(script_->source())); |
572 isolate()->counters()->total_parse_size()->Increment(source->length()); | 574 isolate()->counters()->total_parse_size()->Increment(source->length()); |
573 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; | 575 int64_t start = FLAG_trace_parse ? OS::Ticks() : 0; |
574 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 576 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1215 return ParseModuleLiteral(ok); | 1217 return ParseModuleLiteral(ok); |
1216 | 1218 |
1217 case Token::ASSIGN: { | 1219 case Token::ASSIGN: { |
1218 Expect(Token::ASSIGN, CHECK_OK); | 1220 Expect(Token::ASSIGN, CHECK_OK); |
1219 Module* result = ParseModulePath(CHECK_OK); | 1221 Module* result = ParseModulePath(CHECK_OK); |
1220 ExpectSemicolon(CHECK_OK); | 1222 ExpectSemicolon(CHECK_OK); |
1221 return result; | 1223 return result; |
1222 } | 1224 } |
1223 | 1225 |
1224 default: { | 1226 default: { |
1225 ExpectContextualKeyword("at", CHECK_OK); | 1227 ExpectContextualKeyword(CStrVector("at"), CHECK_OK); |
1226 Module* result = ParseModuleUrl(CHECK_OK); | 1228 Module* result = ParseModuleUrl(CHECK_OK); |
1227 ExpectSemicolon(CHECK_OK); | 1229 ExpectSemicolon(CHECK_OK); |
1228 return result; | 1230 return result; |
1229 } | 1231 } |
1230 } | 1232 } |
1231 } | 1233 } |
1232 | 1234 |
1233 | 1235 |
1234 Module* Parser::ParseModuleLiteral(bool* ok) { | 1236 Module* Parser::ParseModuleLiteral(bool* ok) { |
1235 // Module: | 1237 // Module: |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1387 ZoneStringList names(1, zone()); | 1389 ZoneStringList names(1, zone()); |
1388 | 1390 |
1389 Handle<String> name = ParseIdentifierName(CHECK_OK); | 1391 Handle<String> name = ParseIdentifierName(CHECK_OK); |
1390 names.Add(name, zone()); | 1392 names.Add(name, zone()); |
1391 while (peek() == Token::COMMA) { | 1393 while (peek() == Token::COMMA) { |
1392 Consume(Token::COMMA); | 1394 Consume(Token::COMMA); |
1393 name = ParseIdentifierName(CHECK_OK); | 1395 name = ParseIdentifierName(CHECK_OK); |
1394 names.Add(name, zone()); | 1396 names.Add(name, zone()); |
1395 } | 1397 } |
1396 | 1398 |
1397 ExpectContextualKeyword("from", CHECK_OK); | 1399 ExpectContextualKeyword(CStrVector("from"), CHECK_OK); |
1398 Module* module = ParseModuleSpecifier(CHECK_OK); | 1400 Module* module = ParseModuleSpecifier(CHECK_OK); |
1399 ExpectSemicolon(CHECK_OK); | 1401 ExpectSemicolon(CHECK_OK); |
1400 | 1402 |
1401 // Generate a separate declaration for each identifier. | 1403 // Generate a separate declaration for each identifier. |
1402 // TODO(ES6): once we implement destructuring, make that one declaration. | 1404 // TODO(ES6): once we implement destructuring, make that one declaration. |
1403 Block* block = factory()->NewBlock(NULL, 1, true); | 1405 Block* block = factory()->NewBlock(NULL, 1, true); |
1404 for (int i = 0; i < names.length(); ++i) { | 1406 for (int i = 0; i < names.length(); ++i) { |
1405 #ifdef DEBUG | 1407 #ifdef DEBUG |
1406 if (FLAG_print_interface_details) | 1408 if (FLAG_print_interface_details) |
1407 PrintF("# Import %s ", names[i]->ToAsciiArray()); | 1409 PrintF("# Import %s ", names[i]->ToAsciiArray()); |
(...skipping 1400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2808 Expect(Token::LPAREN, CHECK_OK); | 2810 Expect(Token::LPAREN, CHECK_OK); |
2809 Expression* cond = ParseExpression(true, CHECK_OK); | 2811 Expression* cond = ParseExpression(true, CHECK_OK); |
2810 Expect(Token::RPAREN, CHECK_OK); | 2812 Expect(Token::RPAREN, CHECK_OK); |
2811 Statement* body = ParseStatement(NULL, CHECK_OK); | 2813 Statement* body = ParseStatement(NULL, CHECK_OK); |
2812 | 2814 |
2813 if (loop != NULL) loop->Initialize(cond, body); | 2815 if (loop != NULL) loop->Initialize(cond, body); |
2814 return loop; | 2816 return loop; |
2815 } | 2817 } |
2816 | 2818 |
2817 | 2819 |
2820 bool Parser::CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { | |
2821 if (Check(Token::IN)) { | |
2822 *visit_mode = ForEachStatement::ENUMERATE; | |
2823 return true; | |
2824 } else if (FLAG_harmony_iteration && | |
2825 CheckContextualKeyword(CStrVector("of"))) { | |
2826 *visit_mode = ForEachStatement::ITERATE; | |
2827 return true; | |
2828 } | |
2829 return false; | |
2830 } | |
2831 | |
2832 | |
2818 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2833 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
2819 // ForStatement :: | 2834 // ForStatement :: |
2820 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2835 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
2821 | 2836 |
2822 Statement* init = NULL; | 2837 Statement* init = NULL; |
2823 | 2838 |
2824 // Create an in-between scope for let-bound iteration variables. | 2839 // Create an in-between scope for let-bound iteration variables. |
2825 Scope* saved_scope = top_scope_; | 2840 Scope* saved_scope = top_scope_; |
2826 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); | 2841 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); |
2827 top_scope_ = for_scope; | 2842 top_scope_ = for_scope; |
2828 | 2843 |
2829 Expect(Token::FOR, CHECK_OK); | 2844 Expect(Token::FOR, CHECK_OK); |
2830 Expect(Token::LPAREN, CHECK_OK); | 2845 Expect(Token::LPAREN, CHECK_OK); |
2831 for_scope->set_start_position(scanner().location().beg_pos); | 2846 for_scope->set_start_position(scanner().location().beg_pos); |
2832 if (peek() != Token::SEMICOLON) { | 2847 if (peek() != Token::SEMICOLON) { |
2833 if (peek() == Token::VAR || peek() == Token::CONST) { | 2848 if (peek() == Token::VAR || peek() == Token::CONST) { |
2834 bool is_const = peek() == Token::CONST; | 2849 bool is_const = peek() == Token::CONST; |
2835 Handle<String> name; | 2850 Handle<String> name; |
2836 Block* variable_statement = | 2851 Block* variable_statement = |
2837 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); | 2852 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); |
2853 ForEachStatement::VisitMode mode; | |
2838 | 2854 |
2839 if (peek() == Token::IN && !name.is_null()) { | 2855 if (!name.is_null() && CheckInOrOf(&mode)) { |
2840 Interface* interface = | 2856 Interface* interface = |
2841 is_const ? Interface::NewConst() : Interface::NewValue(); | 2857 is_const ? Interface::NewConst() : Interface::NewValue(); |
2842 ForInStatement* loop = factory()->NewForInStatement(labels); | 2858 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2843 Target target(&this->target_stack_, loop); | 2859 Target target(&this->target_stack_, loop); |
2844 | 2860 |
2845 Expect(Token::IN, CHECK_OK); | |
2846 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2861 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2847 Expect(Token::RPAREN, CHECK_OK); | 2862 Expect(Token::RPAREN, CHECK_OK); |
2848 | 2863 |
2849 VariableProxy* each = | 2864 VariableProxy* each = |
2850 top_scope_->NewUnresolved(factory(), name, interface); | 2865 top_scope_->NewUnresolved(factory(), name, interface); |
2851 Statement* body = ParseStatement(NULL, CHECK_OK); | 2866 Statement* body = ParseStatement(NULL, CHECK_OK); |
2852 loop->Initialize(each, enumerable, body); | 2867 loop->Initialize(each, enumerable, body); |
2853 Block* result = factory()->NewBlock(NULL, 2, false); | 2868 Block* result = factory()->NewBlock(NULL, 2, false); |
2854 result->AddStatement(variable_statement, zone()); | 2869 result->AddStatement(variable_statement, zone()); |
2855 result->AddStatement(loop, zone()); | 2870 result->AddStatement(loop, zone()); |
2856 top_scope_ = saved_scope; | 2871 top_scope_ = saved_scope; |
2857 for_scope->set_end_position(scanner().location().end_pos); | 2872 for_scope->set_end_position(scanner().location().end_pos); |
2858 for_scope = for_scope->FinalizeBlockScope(); | 2873 for_scope = for_scope->FinalizeBlockScope(); |
2859 ASSERT(for_scope == NULL); | 2874 ASSERT(for_scope == NULL); |
2860 // Parsed for-in loop w/ variable/const declaration. | 2875 // Parsed for-in loop w/ variable/const declaration. |
2861 return result; | 2876 return result; |
2862 } else { | 2877 } else { |
2863 init = variable_statement; | 2878 init = variable_statement; |
2864 } | 2879 } |
2865 } else if (peek() == Token::LET) { | 2880 } else if (peek() == Token::LET) { |
2866 Handle<String> name; | 2881 Handle<String> name; |
2867 VariableDeclarationProperties decl_props = kHasNoInitializers; | 2882 VariableDeclarationProperties decl_props = kHasNoInitializers; |
2868 Block* variable_statement = | 2883 Block* variable_statement = |
2869 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, | 2884 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, |
2870 CHECK_OK); | 2885 CHECK_OK); |
2871 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; | 2886 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; |
2872 if (peek() == Token::IN && accept_IN) { | 2887 ForEachStatement::VisitMode mode; |
2888 | |
2889 if (accept_IN && CheckInOrOf(&mode)) { | |
2873 // Rewrite a for-in statement of the form | 2890 // Rewrite a for-in statement of the form |
2874 // | 2891 // |
2875 // for (let x in e) b | 2892 // for (let x in e) b |
2876 // | 2893 // |
2877 // into | 2894 // into |
2878 // | 2895 // |
2879 // <let x' be a temporary variable> | 2896 // <let x' be a temporary variable> |
2880 // for (x' in e) { | 2897 // for (x' in e) { |
2881 // let x; | 2898 // let x; |
2882 // x = x'; | 2899 // x = x'; |
2883 // b; | 2900 // b; |
2884 // } | 2901 // } |
2885 | 2902 |
2886 // TODO(keuchel): Move the temporary variable to the block scope, after | 2903 // TODO(keuchel): Move the temporary variable to the block scope, after |
2887 // implementing stack allocated block scoped variables. | 2904 // implementing stack allocated block scoped variables. |
2888 Factory* heap_factory = isolate()->factory(); | 2905 Factory* heap_factory = isolate()->factory(); |
2889 Handle<String> tempstr = | 2906 Handle<String> tempstr = |
2890 heap_factory->NewConsString(heap_factory->dot_for_string(), name); | 2907 heap_factory->NewConsString(heap_factory->dot_for_string(), name); |
2891 Handle<String> tempname = heap_factory->InternalizeString(tempstr); | 2908 Handle<String> tempname = heap_factory->InternalizeString(tempstr); |
2892 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); | 2909 Variable* temp = top_scope_->DeclarationScope()->NewTemporary(tempname); |
2893 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); | 2910 VariableProxy* temp_proxy = factory()->NewVariableProxy(temp); |
2894 ForInStatement* loop = factory()->NewForInStatement(labels); | 2911 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2895 Target target(&this->target_stack_, loop); | 2912 Target target(&this->target_stack_, loop); |
2896 | 2913 |
2897 // The expression does not see the loop variable. | 2914 // The expression does not see the loop variable. |
2898 Expect(Token::IN, CHECK_OK); | |
2899 top_scope_ = saved_scope; | 2915 top_scope_ = saved_scope; |
2900 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2916 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2901 top_scope_ = for_scope; | 2917 top_scope_ = for_scope; |
2902 Expect(Token::RPAREN, CHECK_OK); | 2918 Expect(Token::RPAREN, CHECK_OK); |
2903 | 2919 |
2904 VariableProxy* each = | 2920 VariableProxy* each = |
2905 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); | 2921 top_scope_->NewUnresolved(factory(), name, Interface::NewValue()); |
2906 Statement* body = ParseStatement(NULL, CHECK_OK); | 2922 Statement* body = ParseStatement(NULL, CHECK_OK); |
2907 Block* body_block = factory()->NewBlock(NULL, 3, false); | 2923 Block* body_block = factory()->NewBlock(NULL, 3, false); |
2908 Assignment* assignment = factory()->NewAssignment( | 2924 Assignment* assignment = factory()->NewAssignment( |
2909 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); | 2925 Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition); |
2910 Statement* assignment_statement = | 2926 Statement* assignment_statement = |
2911 factory()->NewExpressionStatement(assignment); | 2927 factory()->NewExpressionStatement(assignment); |
2912 body_block->AddStatement(variable_statement, zone()); | 2928 body_block->AddStatement(variable_statement, zone()); |
2913 body_block->AddStatement(assignment_statement, zone()); | 2929 body_block->AddStatement(assignment_statement, zone()); |
2914 body_block->AddStatement(body, zone()); | 2930 body_block->AddStatement(body, zone()); |
2915 loop->Initialize(temp_proxy, enumerable, body_block); | 2931 loop->Initialize(temp_proxy, enumerable, body_block); |
2916 top_scope_ = saved_scope; | 2932 top_scope_ = saved_scope; |
2917 for_scope->set_end_position(scanner().location().end_pos); | 2933 for_scope->set_end_position(scanner().location().end_pos); |
2918 for_scope = for_scope->FinalizeBlockScope(); | 2934 for_scope = for_scope->FinalizeBlockScope(); |
2919 body_block->set_scope(for_scope); | 2935 body_block->set_scope(for_scope); |
2920 // Parsed for-in loop w/ let declaration. | 2936 // Parsed for-in loop w/ let declaration. |
2921 return loop; | 2937 return loop; |
2922 | 2938 |
2923 } else { | 2939 } else { |
2924 init = variable_statement; | 2940 init = variable_statement; |
2925 } | 2941 } |
2926 } else { | 2942 } else { |
2927 Expression* expression = ParseExpression(false, CHECK_OK); | 2943 Expression* expression = ParseExpression(false, CHECK_OK); |
2928 if (peek() == Token::IN) { | 2944 ForEachStatement::VisitMode mode; |
2945 | |
2946 if (CheckInOrOf(&mode)) { | |
2929 // Signal a reference error if the expression is an invalid | 2947 // Signal a reference error if the expression is an invalid |
2930 // left-hand side expression. We could report this as a syntax | 2948 // left-hand side expression. We could report this as a syntax |
2931 // error here but for compatibility with JSC we choose to report | 2949 // error here but for compatibility with JSC we choose to report |
2932 // the error at runtime. | 2950 // the error at runtime. |
2933 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2951 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2934 Handle<String> type = | 2952 Handle<String> type = |
2935 isolate()->factory()->invalid_lhs_in_for_in_string(); | 2953 isolate()->factory()->invalid_lhs_in_for_in_string(); |
2936 expression = NewThrowReferenceError(type); | 2954 expression = NewThrowReferenceError(type); |
2937 } | 2955 } |
2938 ForInStatement* loop = factory()->NewForInStatement(labels); | 2956 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); |
2939 Target target(&this->target_stack_, loop); | 2957 Target target(&this->target_stack_, loop); |
2940 | 2958 |
2941 Expect(Token::IN, CHECK_OK); | |
2942 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2959 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2943 Expect(Token::RPAREN, CHECK_OK); | 2960 Expect(Token::RPAREN, CHECK_OK); |
2944 | 2961 |
2945 Statement* body = ParseStatement(NULL, CHECK_OK); | 2962 Statement* body = ParseStatement(NULL, CHECK_OK); |
2946 if (loop) loop->Initialize(expression, enumerable, body); | 2963 loop->Initialize(expression, enumerable, body); |
rossberg
2013/06/06 10:32:33
Weird, what was the purpose of this condition?
wingo
2013/06/06 14:09:51
I... I don't know! I think this is another vestig
| |
2947 top_scope_ = saved_scope; | 2964 top_scope_ = saved_scope; |
2948 for_scope->set_end_position(scanner().location().end_pos); | 2965 for_scope->set_end_position(scanner().location().end_pos); |
2949 for_scope = for_scope->FinalizeBlockScope(); | 2966 for_scope = for_scope->FinalizeBlockScope(); |
2950 ASSERT(for_scope == NULL); | 2967 ASSERT(for_scope == NULL); |
2951 // Parsed for-in loop. | 2968 // Parsed for-in loop. |
2952 return loop; | 2969 return loop; |
2953 | 2970 |
2954 } else { | 2971 } else { |
2955 init = factory()->NewExpressionStatement(expression); | 2972 init = factory()->NewExpressionStatement(expression); |
2956 } | 2973 } |
(...skipping 1742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4699 if (reusable_preparser_ == NULL) { | 4716 if (reusable_preparser_ == NULL) { |
4700 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 4717 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
4701 reusable_preparser_ = new preparser::PreParser(&scanner_, | 4718 reusable_preparser_ = new preparser::PreParser(&scanner_, |
4702 NULL, | 4719 NULL, |
4703 stack_limit); | 4720 stack_limit); |
4704 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4721 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4705 reusable_preparser_->set_allow_modules(allow_modules()); | 4722 reusable_preparser_->set_allow_modules(allow_modules()); |
4706 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 4723 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
4707 reusable_preparser_->set_allow_lazy(true); | 4724 reusable_preparser_->set_allow_lazy(true); |
4708 reusable_preparser_->set_allow_generators(allow_generators()); | 4725 reusable_preparser_->set_allow_generators(allow_generators()); |
4726 reusable_preparser_->set_allow_for_of(allow_for_of()); | |
4709 } | 4727 } |
4710 preparser::PreParser::PreParseResult result = | 4728 preparser::PreParser::PreParseResult result = |
4711 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), | 4729 reusable_preparser_->PreParseLazyFunction(top_scope_->language_mode(), |
4712 is_generator(), | 4730 is_generator(), |
4713 logger); | 4731 logger); |
4714 return result; | 4732 return result; |
4715 } | 4733 } |
4716 | 4734 |
4717 | 4735 |
4718 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4736 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4796 bool Parser::Check(Token::Value token) { | 4814 bool Parser::Check(Token::Value token) { |
4797 Token::Value next = peek(); | 4815 Token::Value next = peek(); |
4798 if (next == token) { | 4816 if (next == token) { |
4799 Consume(next); | 4817 Consume(next); |
4800 return true; | 4818 return true; |
4801 } | 4819 } |
4802 return false; | 4820 return false; |
4803 } | 4821 } |
4804 | 4822 |
4805 | 4823 |
4824 bool Parser::CheckContextualKeyword(Vector<const char> keyword) { | |
4825 if (peek() == Token::IDENTIFIER && | |
4826 scanner().is_next_contextual_keyword(keyword)) { | |
4827 Consume(Token::IDENTIFIER); | |
4828 return true; | |
4829 } | |
4830 return false; | |
4831 } | |
4832 | |
4833 | |
4806 void Parser::ExpectSemicolon(bool* ok) { | 4834 void Parser::ExpectSemicolon(bool* ok) { |
4807 // Check for automatic semicolon insertion according to | 4835 // Check for automatic semicolon insertion according to |
4808 // the rules given in ECMA-262, section 7.9, page 21. | 4836 // the rules given in ECMA-262, section 7.9, page 21. |
4809 Token::Value tok = peek(); | 4837 Token::Value tok = peek(); |
4810 if (tok == Token::SEMICOLON) { | 4838 if (tok == Token::SEMICOLON) { |
4811 Next(); | 4839 Next(); |
4812 return; | 4840 return; |
4813 } | 4841 } |
4814 if (scanner().HasAnyLineTerminatorBeforeNext() || | 4842 if (scanner().HasAnyLineTerminatorBeforeNext() || |
4815 tok == Token::RBRACE || | 4843 tok == Token::RBRACE || |
4816 tok == Token::EOS) { | 4844 tok == Token::EOS) { |
4817 return; | 4845 return; |
4818 } | 4846 } |
4819 Expect(Token::SEMICOLON, ok); | 4847 Expect(Token::SEMICOLON, ok); |
4820 } | 4848 } |
4821 | 4849 |
4822 | 4850 |
4823 void Parser::ExpectContextualKeyword(const char* keyword, bool* ok) { | 4851 void Parser::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
4824 Expect(Token::IDENTIFIER, ok); | 4852 Expect(Token::IDENTIFIER, ok); |
4825 if (!*ok) return; | 4853 if (!*ok) return; |
4826 Handle<String> symbol = GetSymbol(ok); | 4854 if (!scanner().is_literal_contextual_keyword(keyword)) { |
4827 if (!*ok) return; | |
4828 if (!symbol->IsUtf8EqualTo(CStrVector(keyword))) { | |
4829 *ok = false; | 4855 *ok = false; |
4830 ReportUnexpectedToken(scanner().current_token()); | 4856 ReportUnexpectedToken(scanner().current_token()); |
4831 } | 4857 } |
4832 } | 4858 } |
4833 | 4859 |
4834 | 4860 |
4835 Literal* Parser::GetLiteralUndefined() { | 4861 Literal* Parser::GetLiteralUndefined() { |
4836 return factory()->NewLiteral(isolate()->factory()->undefined_value()); | 4862 return factory()->NewLiteral(isolate()->factory()->undefined_value()); |
4837 } | 4863 } |
4838 | 4864 |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5954 // Create a Scanner for the preparser to use as input, and preparse the source. | 5980 // Create a Scanner for the preparser to use as input, and preparse the source. |
5955 ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { | 5981 ScriptDataImpl* PreParserApi::PreParse(Utf16CharacterStream* source) { |
5956 CompleteParserRecorder recorder; | 5982 CompleteParserRecorder recorder; |
5957 Isolate* isolate = Isolate::Current(); | 5983 Isolate* isolate = Isolate::Current(); |
5958 HistogramTimerScope timer(isolate->counters()->pre_parse()); | 5984 HistogramTimerScope timer(isolate->counters()->pre_parse()); |
5959 Scanner scanner(isolate->unicode_cache()); | 5985 Scanner scanner(isolate->unicode_cache()); |
5960 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5986 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
5961 preparser::PreParser preparser(&scanner, &recorder, stack_limit); | 5987 preparser::PreParser preparser(&scanner, &recorder, stack_limit); |
5962 preparser.set_allow_lazy(true); | 5988 preparser.set_allow_lazy(true); |
5963 preparser.set_allow_generators(FLAG_harmony_generators); | 5989 preparser.set_allow_generators(FLAG_harmony_generators); |
5990 preparser.set_allow_for_of(FLAG_harmony_iteration); | |
5964 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); | 5991 preparser.set_allow_harmony_scoping(FLAG_harmony_scoping); |
5965 scanner.Initialize(source); | 5992 scanner.Initialize(source); |
5966 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); | 5993 preparser::PreParser::PreParseResult result = preparser.PreParseProgram(); |
5967 if (result == preparser::PreParser::kPreParseStackOverflow) { | 5994 if (result == preparser::PreParser::kPreParseStackOverflow) { |
5968 isolate->StackOverflow(); | 5995 isolate->StackOverflow(); |
5969 return NULL; | 5996 return NULL; |
5970 } | 5997 } |
5971 | 5998 |
5972 // Extract the accumulated data from the recorder as a single | 5999 // Extract the accumulated data from the recorder as a single |
5973 // contiguous vector that we are responsible for disposing. | 6000 // contiguous vector that we are responsible for disposing. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6025 ASSERT(info()->isolate()->has_pending_exception()); | 6052 ASSERT(info()->isolate()->has_pending_exception()); |
6026 } else { | 6053 } else { |
6027 result = ParseProgram(); | 6054 result = ParseProgram(); |
6028 } | 6055 } |
6029 } | 6056 } |
6030 info()->SetFunction(result); | 6057 info()->SetFunction(result); |
6031 return (result != NULL); | 6058 return (result != NULL); |
6032 } | 6059 } |
6033 | 6060 |
6034 } } // namespace v8::internal | 6061 } } // namespace v8::internal |
OLD | NEW |