OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 // parsed into an empty statement. | 1256 // parsed into an empty statement. |
1257 | 1257 |
1258 // Keep the source position of the statement | 1258 // Keep the source position of the statement |
1259 int statement_pos = scanner().peek_location().beg_pos; | 1259 int statement_pos = scanner().peek_location().beg_pos; |
1260 Statement* stmt = NULL; | 1260 Statement* stmt = NULL; |
1261 switch (peek()) { | 1261 switch (peek()) { |
1262 case Token::LBRACE: | 1262 case Token::LBRACE: |
1263 return ParseBlock(labels, ok); | 1263 return ParseBlock(labels, ok); |
1264 | 1264 |
1265 case Token::CONST: // fall through | 1265 case Token::CONST: // fall through |
| 1266 case Token::LET: |
1266 case Token::VAR: | 1267 case Token::VAR: |
1267 stmt = ParseVariableStatement(kStatement, ok); | 1268 stmt = ParseVariableStatement(kStatement, ok); |
1268 break; | 1269 break; |
1269 | 1270 |
1270 case Token::SEMICOLON: | 1271 case Token::SEMICOLON: |
1271 Next(); | 1272 Next(); |
1272 return EmptyStatement(); | 1273 return EmptyStatement(); |
1273 | 1274 |
1274 case Token::IF: | 1275 case Token::IF: |
1275 stmt = ParseIfStatement(labels, ok); | 1276 stmt = ParseIfStatement(labels, ok); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 // True if the binding needs initialization. 'let' and 'const' declared | 1698 // True if the binding needs initialization. 'let' and 'const' declared |
1698 // bindings are created uninitialized by their declaration nodes and | 1699 // bindings are created uninitialized by their declaration nodes and |
1699 // need initialization. 'var' declared bindings are always initialized | 1700 // need initialization. 'var' declared bindings are always initialized |
1700 // immediately by their declaration nodes. | 1701 // immediately by their declaration nodes. |
1701 bool needs_init = false; | 1702 bool needs_init = false; |
1702 bool is_const = false; | 1703 bool is_const = false; |
1703 Token::Value init_op = Token::INIT_VAR; | 1704 Token::Value init_op = Token::INIT_VAR; |
1704 if (peek() == Token::VAR) { | 1705 if (peek() == Token::VAR) { |
1705 Consume(Token::VAR); | 1706 Consume(Token::VAR); |
1706 } else if (peek() == Token::CONST) { | 1707 } else if (peek() == Token::CONST) { |
| 1708 // TODO(ES6): The ES6 Draft Rev4 section 12.2.2 reads: |
| 1709 // |
| 1710 // ConstDeclaration : const ConstBinding (',' ConstBinding)* ';' |
| 1711 // |
| 1712 // * It is a Syntax Error if the code that matches this production is not |
| 1713 // contained in extended code. |
| 1714 // |
| 1715 // However disallowing const in classic mode will break compatibility with |
| 1716 // existing pages. Therefore we keep allowing const with the old |
| 1717 // non-harmony semantics in classic mode. |
1707 Consume(Token::CONST); | 1718 Consume(Token::CONST); |
1708 switch (top_scope_->language_mode()) { | 1719 switch (top_scope_->language_mode()) { |
1709 case CLASSIC_MODE: | 1720 case CLASSIC_MODE: |
1710 mode = CONST; | 1721 mode = CONST; |
1711 init_op = Token::INIT_CONST; | 1722 init_op = Token::INIT_CONST; |
1712 break; | 1723 break; |
1713 case STRICT_MODE: | 1724 case STRICT_MODE: |
1714 ReportMessage("strict_const", Vector<const char*>::empty()); | 1725 ReportMessage("strict_const", Vector<const char*>::empty()); |
1715 *ok = false; | 1726 *ok = false; |
1716 return NULL; | 1727 return NULL; |
1717 case EXTENDED_MODE: | 1728 case EXTENDED_MODE: |
1718 if (var_context != kSourceElement && | 1729 if (var_context != kSourceElement && |
1719 var_context != kForStatement) { | 1730 var_context != kForStatement) { |
1720 // In extended mode 'const' declarations are only allowed in source | 1731 // In extended mode 'const' declarations are only allowed in source |
1721 // element positions. | 1732 // element positions. |
1722 ReportMessage("unprotected_const", Vector<const char*>::empty()); | 1733 ReportMessage("unprotected_const", Vector<const char*>::empty()); |
1723 *ok = false; | 1734 *ok = false; |
1724 return NULL; | 1735 return NULL; |
1725 } | 1736 } |
1726 mode = CONST_HARMONY; | 1737 mode = CONST_HARMONY; |
1727 init_op = Token::INIT_CONST_HARMONY; | 1738 init_op = Token::INIT_CONST_HARMONY; |
1728 } | 1739 } |
1729 is_const = true; | 1740 is_const = true; |
1730 needs_init = true; | 1741 needs_init = true; |
1731 } else if (peek() == Token::LET) { | 1742 } else if (peek() == Token::LET) { |
1732 ASSERT(top_scope_->is_extended_mode()); | 1743 // ES6 Draft Rev4 section 12.2.1: |
| 1744 // |
| 1745 // LetDeclaration : let LetBindingList ; |
| 1746 // |
| 1747 // * It is a Syntax Error if the code that matches this production is not |
| 1748 // contained in extended code. |
| 1749 if (!is_extended_mode()) { |
| 1750 ReportMessage("illegal_let", Vector<const char*>::empty()); |
| 1751 *ok = false; |
| 1752 return NULL; |
| 1753 } |
1733 Consume(Token::LET); | 1754 Consume(Token::LET); |
1734 if (var_context != kSourceElement && | 1755 if (var_context != kSourceElement && |
1735 var_context != kForStatement) { | 1756 var_context != kForStatement) { |
1736 // Let declarations are only allowed in source element positions. | 1757 // Let declarations are only allowed in source element positions. |
1737 ASSERT(var_context == kStatement); | 1758 ASSERT(var_context == kStatement); |
1738 ReportMessage("unprotected_let", Vector<const char*>::empty()); | 1759 ReportMessage("unprotected_let", Vector<const char*>::empty()); |
1739 *ok = false; | 1760 *ok = false; |
1740 return NULL; | 1761 return NULL; |
1741 } | 1762 } |
1742 mode = LET; | 1763 mode = LET; |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2661 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2682 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2662 Handle<String> type = | 2683 Handle<String> type = |
2663 isolate()->factory()->invalid_lhs_in_assignment_symbol(); | 2684 isolate()->factory()->invalid_lhs_in_assignment_symbol(); |
2664 expression = NewThrowReferenceError(type); | 2685 expression = NewThrowReferenceError(type); |
2665 } | 2686 } |
2666 | 2687 |
2667 if (!top_scope_->is_classic_mode()) { | 2688 if (!top_scope_->is_classic_mode()) { |
2668 // Assignment to eval or arguments is disallowed in strict mode. | 2689 // Assignment to eval or arguments is disallowed in strict mode. |
2669 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2690 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
2670 } | 2691 } |
| 2692 MarkAsLValue(expression); |
2671 | 2693 |
2672 Token::Value op = Next(); // Get assignment operator. | 2694 Token::Value op = Next(); // Get assignment operator. |
2673 int pos = scanner().location().beg_pos; | 2695 int pos = scanner().location().beg_pos; |
2674 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2696 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2675 | 2697 |
2676 // TODO(1231235): We try to estimate the set of properties set by | 2698 // TODO(1231235): We try to estimate the set of properties set by |
2677 // constructors. We define a new property whenever there is an | 2699 // constructors. We define a new property whenever there is an |
2678 // assignment to a property of 'this'. We should probably only add | 2700 // assignment to a property of 'this'. We should probably only add |
2679 // properties if we haven't seen them before. Otherwise we'll | 2701 // properties if we haven't seen them before. Otherwise we'll |
2680 // probably overestimate the number of properties. | 2702 // probably overestimate the number of properties. |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2894 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2916 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2895 Handle<String> type = | 2917 Handle<String> type = |
2896 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); | 2918 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); |
2897 expression = NewThrowReferenceError(type); | 2919 expression = NewThrowReferenceError(type); |
2898 } | 2920 } |
2899 | 2921 |
2900 if (!top_scope_->is_classic_mode()) { | 2922 if (!top_scope_->is_classic_mode()) { |
2901 // Prefix expression operand in strict mode may not be eval or arguments. | 2923 // Prefix expression operand in strict mode may not be eval or arguments. |
2902 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2924 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
2903 } | 2925 } |
| 2926 MarkAsLValue(expression); |
2904 | 2927 |
2905 int position = scanner().location().beg_pos; | 2928 int position = scanner().location().beg_pos; |
2906 return new(zone()) CountOperation(isolate(), | 2929 return new(zone()) CountOperation(isolate(), |
2907 op, | 2930 op, |
2908 true /* prefix */, | 2931 true /* prefix */, |
2909 expression, | 2932 expression, |
2910 position); | 2933 position); |
2911 | 2934 |
2912 } else { | 2935 } else { |
2913 return ParsePostfixExpression(ok); | 2936 return ParsePostfixExpression(ok); |
(...skipping 15 matching lines...) Expand all Loading... |
2929 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2952 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2930 Handle<String> type = | 2953 Handle<String> type = |
2931 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); | 2954 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); |
2932 expression = NewThrowReferenceError(type); | 2955 expression = NewThrowReferenceError(type); |
2933 } | 2956 } |
2934 | 2957 |
2935 if (!top_scope_->is_classic_mode()) { | 2958 if (!top_scope_->is_classic_mode()) { |
2936 // Postfix expression operand in strict mode may not be eval or arguments. | 2959 // Postfix expression operand in strict mode may not be eval or arguments. |
2937 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2960 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
2938 } | 2961 } |
| 2962 MarkAsLValue(expression); |
2939 | 2963 |
2940 Token::Value next = Next(); | 2964 Token::Value next = Next(); |
2941 int position = scanner().location().beg_pos; | 2965 int position = scanner().location().beg_pos; |
2942 expression = | 2966 expression = |
2943 new(zone()) CountOperation(isolate(), | 2967 new(zone()) CountOperation(isolate(), |
2944 next, | 2968 next, |
2945 false /* postfix */, | 2969 false /* postfix */, |
2946 expression, | 2970 expression, |
2947 position); | 2971 position); |
2948 } | 2972 } |
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4287 next != Token::FUTURE_STRICT_RESERVED_WORD && | 4311 next != Token::FUTURE_STRICT_RESERVED_WORD && |
4288 !Token::IsKeyword(next)) { | 4312 !Token::IsKeyword(next)) { |
4289 ReportUnexpectedToken(next); | 4313 ReportUnexpectedToken(next); |
4290 *ok = false; | 4314 *ok = false; |
4291 return Handle<String>(); | 4315 return Handle<String>(); |
4292 } | 4316 } |
4293 return GetSymbol(ok); | 4317 return GetSymbol(ok); |
4294 } | 4318 } |
4295 | 4319 |
4296 | 4320 |
| 4321 void Parser::MarkAsLValue(Expression* expression) { |
| 4322 VariableProxy* proxy = expression != NULL |
| 4323 ? expression->AsVariableProxy() |
| 4324 : NULL; |
| 4325 |
| 4326 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4327 } |
| 4328 |
| 4329 |
4297 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4330 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
4298 // in strict mode. | 4331 // in strict mode. |
4299 void Parser::CheckStrictModeLValue(Expression* expression, | 4332 void Parser::CheckStrictModeLValue(Expression* expression, |
4300 const char* error, | 4333 const char* error, |
4301 bool* ok) { | 4334 bool* ok) { |
4302 ASSERT(!top_scope_->is_classic_mode()); | 4335 ASSERT(!top_scope_->is_classic_mode()); |
4303 VariableProxy* lhs = expression != NULL | 4336 VariableProxy* lhs = expression != NULL |
4304 ? expression->AsVariableProxy() | 4337 ? expression->AsVariableProxy() |
4305 : NULL; | 4338 : NULL; |
4306 | 4339 |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5459 ASSERT(info->isolate()->has_pending_exception()); | 5492 ASSERT(info->isolate()->has_pending_exception()); |
5460 } else { | 5493 } else { |
5461 result = parser.ParseProgram(info); | 5494 result = parser.ParseProgram(info); |
5462 } | 5495 } |
5463 } | 5496 } |
5464 info->SetFunction(result); | 5497 info->SetFunction(result); |
5465 return (result != NULL); | 5498 return (result != NULL); |
5466 } | 5499 } |
5467 | 5500 |
5468 } } // namespace v8::internal | 5501 } } // namespace v8::internal |
OLD | NEW |