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

Side by Side Diff: src/parser.cc

Issue 16739008: For-of statements do not permit initializers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 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
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2606 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 Expect(Token::LPAREN, CHECK_OK); 2617 Expect(Token::LPAREN, CHECK_OK);
2618 Expression* cond = ParseExpression(true, CHECK_OK); 2618 Expression* cond = ParseExpression(true, CHECK_OK);
2619 Expect(Token::RPAREN, CHECK_OK); 2619 Expect(Token::RPAREN, CHECK_OK);
2620 Statement* body = ParseStatement(NULL, CHECK_OK); 2620 Statement* body = ParseStatement(NULL, CHECK_OK);
2621 2621
2622 if (loop != NULL) loop->Initialize(cond, body); 2622 if (loop != NULL) loop->Initialize(cond, body);
2623 return loop; 2623 return loop;
2624 } 2624 }
2625 2625
2626 2626
2627 bool Parser::CheckInOrOf(ForEachStatement::VisitMode* visit_mode) { 2627 bool Parser::CheckInOrOf(bool accept_OF,
2628 ForEachStatement::VisitMode* visit_mode) {
2628 if (Check(Token::IN)) { 2629 if (Check(Token::IN)) {
2629 *visit_mode = ForEachStatement::ENUMERATE; 2630 *visit_mode = ForEachStatement::ENUMERATE;
2630 return true; 2631 return true;
2631 } else if (allow_for_of() && CheckContextualKeyword(CStrVector("of"))) { 2632 } else if (allow_for_of() && accept_OF &&
2633 CheckContextualKeyword(CStrVector("of"))) {
2632 *visit_mode = ForEachStatement::ITERATE; 2634 *visit_mode = ForEachStatement::ITERATE;
2633 return true; 2635 return true;
2634 } 2636 }
2635 return false; 2637 return false;
2636 } 2638 }
2637 2639
2638 2640
2639 void Parser::InitializeForEachStatement(ForEachStatement* stmt, 2641 void Parser::InitializeForEachStatement(ForEachStatement* stmt,
2640 Expression* each, 2642 Expression* each,
2641 Expression* subject, 2643 Expression* subject,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2719 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE); 2721 Scope* for_scope = NewScope(top_scope_, BLOCK_SCOPE);
2720 top_scope_ = for_scope; 2722 top_scope_ = for_scope;
2721 2723
2722 Expect(Token::FOR, CHECK_OK); 2724 Expect(Token::FOR, CHECK_OK);
2723 Expect(Token::LPAREN, CHECK_OK); 2725 Expect(Token::LPAREN, CHECK_OK);
2724 for_scope->set_start_position(scanner().location().beg_pos); 2726 for_scope->set_start_position(scanner().location().beg_pos);
2725 if (peek() != Token::SEMICOLON) { 2727 if (peek() != Token::SEMICOLON) {
2726 if (peek() == Token::VAR || peek() == Token::CONST) { 2728 if (peek() == Token::VAR || peek() == Token::CONST) {
2727 bool is_const = peek() == Token::CONST; 2729 bool is_const = peek() == Token::CONST;
2728 Handle<String> name; 2730 Handle<String> name;
2731 VariableDeclarationProperties decl_props = kHasNoInitializers;
2729 Block* variable_statement = 2732 Block* variable_statement =
2730 ParseVariableDeclarations(kForStatement, NULL, NULL, &name, CHECK_OK); 2733 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2734 CHECK_OK);
2735 bool accept_OF = decl_props == kHasNoInitializers;
2731 ForEachStatement::VisitMode mode; 2736 ForEachStatement::VisitMode mode;
2732 2737
2733 if (!name.is_null() && CheckInOrOf(&mode)) { 2738 if (!name.is_null() && CheckInOrOf(accept_OF, &mode)) {
2734 Interface* interface = 2739 Interface* interface =
2735 is_const ? Interface::NewConst() : Interface::NewValue(); 2740 is_const ? Interface::NewConst() : Interface::NewValue();
2736 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); 2741 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels);
2737 Target target(&this->target_stack_, loop); 2742 Target target(&this->target_stack_, loop);
2738 2743
2739 Expression* enumerable = ParseExpression(true, CHECK_OK); 2744 Expression* enumerable = ParseExpression(true, CHECK_OK);
2740 Expect(Token::RPAREN, CHECK_OK); 2745 Expect(Token::RPAREN, CHECK_OK);
2741 2746
2742 VariableProxy* each = 2747 VariableProxy* each =
2743 top_scope_->NewUnresolved(factory(), name, interface); 2748 top_scope_->NewUnresolved(factory(), name, interface);
(...skipping 11 matching lines...) Expand all
2755 } else { 2760 } else {
2756 init = variable_statement; 2761 init = variable_statement;
2757 } 2762 }
2758 } else if (peek() == Token::LET) { 2763 } else if (peek() == Token::LET) {
2759 Handle<String> name; 2764 Handle<String> name;
2760 VariableDeclarationProperties decl_props = kHasNoInitializers; 2765 VariableDeclarationProperties decl_props = kHasNoInitializers;
2761 Block* variable_statement = 2766 Block* variable_statement =
2762 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name, 2767 ParseVariableDeclarations(kForStatement, &decl_props, NULL, &name,
2763 CHECK_OK); 2768 CHECK_OK);
2764 bool accept_IN = !name.is_null() && decl_props != kHasInitializers; 2769 bool accept_IN = !name.is_null() && decl_props != kHasInitializers;
2770 bool accept_OF = decl_props == kHasNoInitializers;
2765 ForEachStatement::VisitMode mode; 2771 ForEachStatement::VisitMode mode;
2766 2772
2767 if (accept_IN && CheckInOrOf(&mode)) { 2773 if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
2768 // Rewrite a for-in statement of the form 2774 // Rewrite a for-in statement of the form
2769 // 2775 //
2770 // for (let x in e) b 2776 // for (let x in e) b
2771 // 2777 //
2772 // into 2778 // into
2773 // 2779 //
2774 // <let x' be a temporary variable> 2780 // <let x' be a temporary variable>
2775 // for (x' in e) { 2781 // for (x' in e) {
2776 // let x; 2782 // let x;
2777 // x = x'; 2783 // x = x';
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2813 body_block->set_scope(for_scope); 2819 body_block->set_scope(for_scope);
2814 // Parsed for-in loop w/ let declaration. 2820 // Parsed for-in loop w/ let declaration.
2815 return loop; 2821 return loop;
2816 2822
2817 } else { 2823 } else {
2818 init = variable_statement; 2824 init = variable_statement;
2819 } 2825 }
2820 } else { 2826 } else {
2821 Expression* expression = ParseExpression(false, CHECK_OK); 2827 Expression* expression = ParseExpression(false, CHECK_OK);
2822 ForEachStatement::VisitMode mode; 2828 ForEachStatement::VisitMode mode;
2829 bool accept_OF = expression->AsVariableProxy();
2823 2830
2824 if (CheckInOrOf(&mode)) { 2831 if (CheckInOrOf(accept_OF, &mode)) {
2825 // Signal a reference error if the expression is an invalid 2832 // Signal a reference error if the expression is an invalid
2826 // left-hand side expression. We could report this as a syntax 2833 // left-hand side expression. We could report this as a syntax
2827 // error here but for compatibility with JSC we choose to report 2834 // error here but for compatibility with JSC we choose to report
2828 // the error at runtime. 2835 // the error at runtime.
2829 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2836 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2830 Handle<String> message = 2837 Handle<String> message =
2831 isolate()->factory()->invalid_lhs_in_for_in_string(); 2838 isolate()->factory()->invalid_lhs_in_for_in_string();
2832 expression = NewThrowReferenceError(message); 2839 expression = NewThrowReferenceError(message);
2833 } 2840 }
2834 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels); 2841 ForEachStatement* loop = factory()->NewForEachStatement(mode, labels);
(...skipping 3095 matching lines...) Expand 10 before | Expand all | Expand 10 after
5930 ASSERT(info()->isolate()->has_pending_exception()); 5937 ASSERT(info()->isolate()->has_pending_exception());
5931 } else { 5938 } else {
5932 result = ParseProgram(); 5939 result = ParseProgram();
5933 } 5940 }
5934 } 5941 }
5935 info()->SetFunction(result); 5942 info()->SetFunction(result);
5936 return (result != NULL); 5943 return (result != NULL);
5937 } 5944 }
5938 5945
5939 } } // namespace v8::internal 5946 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698