Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: src/parser.cc

Issue 15300018: Add initial parser support for harmony iteration (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use subtyping instead of enumerated value Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698