OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2653 return result; | 2653 return result; |
2654 } | 2654 } |
2655 | 2655 |
2656 } else { | 2656 } else { |
2657 init = variable_statement; | 2657 init = variable_statement; |
2658 } | 2658 } |
2659 | 2659 |
2660 } else { | 2660 } else { |
2661 Expression* expression = ParseExpression(false, CHECK_OK); | 2661 Expression* expression = ParseExpression(false, CHECK_OK); |
2662 if (peek() == Token::IN) { | 2662 if (peek() == Token::IN) { |
2663 // Report syntax error if the expression is an invalid | 2663 // Signal a reference error if the expression is an invalid |
2664 // left-hand side expression. | 2664 // left-hand side expression. We could report this as a syntax |
| 2665 // error here but for compatibility with JSC we choose to report |
| 2666 // the error at runtime. |
2665 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2667 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2666 if (expression != NULL && expression->AsCall() != NULL) { | 2668 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); |
2667 // According to ECMA-262 host function calls are permitted to | 2669 expression = NewThrowReferenceError(type); |
2668 // return references. This cannot happen in our system so we | |
2669 // will always get an error. We could report this as a syntax | |
2670 // error here but for compatibility with KJS and SpiderMonkey we | |
2671 // choose to report the error at runtime. | |
2672 Handle<String> type = Factory::invalid_lhs_in_for_in_symbol(); | |
2673 expression = NewThrowReferenceError(type); | |
2674 } else { | |
2675 // Invalid left hand side expressions that are not function | |
2676 // calls are reported as syntax errors at compile time. | |
2677 ReportMessage("invalid_lhs_in_for_in", | |
2678 Vector<const char*>::empty()); | |
2679 *ok = false; | |
2680 return NULL; | |
2681 } | |
2682 } | 2670 } |
2683 ForInStatement* loop = NEW(ForInStatement(labels)); | 2671 ForInStatement* loop = NEW(ForInStatement(labels)); |
2684 Target target(this, loop); | 2672 Target target(this, loop); |
2685 | 2673 |
2686 Expect(Token::IN, CHECK_OK); | 2674 Expect(Token::IN, CHECK_OK); |
2687 Expression* enumerable = ParseExpression(true, CHECK_OK); | 2675 Expression* enumerable = ParseExpression(true, CHECK_OK); |
2688 Expect(Token::RPAREN, CHECK_OK); | 2676 Expect(Token::RPAREN, CHECK_OK); |
2689 | 2677 |
2690 Statement* body = ParseStatement(NULL, CHECK_OK); | 2678 Statement* body = ParseStatement(NULL, CHECK_OK); |
2691 if (loop) loop->Initialize(expression, enumerable, body); | 2679 if (loop) loop->Initialize(expression, enumerable, body); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2748 // ConditionalExpression | 2736 // ConditionalExpression |
2749 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 2737 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
2750 | 2738 |
2751 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | 2739 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); |
2752 | 2740 |
2753 if (!Token::IsAssignmentOp(peek())) { | 2741 if (!Token::IsAssignmentOp(peek())) { |
2754 // Parsed conditional expression only (no assignment). | 2742 // Parsed conditional expression only (no assignment). |
2755 return expression; | 2743 return expression; |
2756 } | 2744 } |
2757 | 2745 |
| 2746 // Signal a reference error if the expression is an invalid left-hand |
| 2747 // side expression. We could report this as a syntax error here but |
| 2748 // for compatibility with JSC we choose to report the error at |
| 2749 // runtime. |
2758 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2750 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2759 if (expression != NULL && expression->AsCall() != NULL) { | 2751 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); |
2760 // According to ECMA-262 host function calls are permitted to | 2752 expression = NewThrowReferenceError(type); |
2761 // return references. This cannot happen in our system so we | |
2762 // will always get an error. We could report this as a syntax | |
2763 // error here but for compatibility with KJS and SpiderMonkey we | |
2764 // choose to report the error at runtime. | |
2765 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); | |
2766 expression = NewThrowReferenceError(type); | |
2767 } else { | |
2768 // Invalid left hand side expressions that are not function | |
2769 // calls are reported as syntax errors at compile time. | |
2770 // | |
2771 // NOTE: KJS sometimes delay the error reporting to runtime. If | |
2772 // we want to be completely compatible we should do the same. | |
2773 // For example: "(x++) = 42" gives a reference error at runtime | |
2774 // with KJS whereas we report a syntax error at compile time. | |
2775 ReportMessage("invalid_lhs_in_assignment", Vector<const char*>::empty()); | |
2776 *ok = false; | |
2777 return NULL; | |
2778 } | |
2779 } | 2753 } |
2780 | 2754 |
2781 | |
2782 Token::Value op = Next(); // Get assignment operator. | 2755 Token::Value op = Next(); // Get assignment operator. |
2783 int pos = scanner().location().beg_pos; | 2756 int pos = scanner().location().beg_pos; |
2784 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2757 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
2785 | 2758 |
2786 // TODO(1231235): We try to estimate the set of properties set by | 2759 // TODO(1231235): We try to estimate the set of properties set by |
2787 // constructors. We define a new property whenever there is an | 2760 // constructors. We define a new property whenever there is an |
2788 // assignment to a property of 'this'. We should probably only add | 2761 // assignment to a property of 'this'. We should probably only add |
2789 // properties if we haven't seen them before. Otherwise we'll | 2762 // properties if we haven't seen them before. Otherwise we'll |
2790 // probably overestimate the number of properties. | 2763 // probably overestimate the number of properties. |
2791 Property* property = expression ? expression->AsProperty() : NULL; | 2764 Property* property = expression ? expression->AsProperty() : NULL; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2944 // '++' UnaryExpression | 2917 // '++' UnaryExpression |
2945 // '--' UnaryExpression | 2918 // '--' UnaryExpression |
2946 // '+' UnaryExpression | 2919 // '+' UnaryExpression |
2947 // '-' UnaryExpression | 2920 // '-' UnaryExpression |
2948 // '~' UnaryExpression | 2921 // '~' UnaryExpression |
2949 // '!' UnaryExpression | 2922 // '!' UnaryExpression |
2950 | 2923 |
2951 Token::Value op = peek(); | 2924 Token::Value op = peek(); |
2952 if (Token::IsUnaryOp(op)) { | 2925 if (Token::IsUnaryOp(op)) { |
2953 op = Next(); | 2926 op = Next(); |
2954 Expression* x = ParseUnaryExpression(CHECK_OK); | 2927 Expression* expression = ParseUnaryExpression(CHECK_OK); |
2955 | 2928 |
2956 // Compute some expressions involving only number literals. | 2929 // Compute some expressions involving only number literals. |
2957 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber()) { | 2930 if (expression != NULL && expression->AsLiteral() && |
2958 double x_val = x->AsLiteral()->handle()->Number(); | 2931 expression->AsLiteral()->handle()->IsNumber()) { |
| 2932 double value = expression->AsLiteral()->handle()->Number(); |
2959 switch (op) { | 2933 switch (op) { |
2960 case Token::ADD: | 2934 case Token::ADD: |
2961 return x; | 2935 return expression; |
2962 case Token::SUB: | 2936 case Token::SUB: |
2963 return NewNumberLiteral(-x_val); | 2937 return NewNumberLiteral(-value); |
2964 case Token::BIT_NOT: | 2938 case Token::BIT_NOT: |
2965 return NewNumberLiteral(~DoubleToInt32(x_val)); | 2939 return NewNumberLiteral(~DoubleToInt32(value)); |
2966 default: break; | 2940 default: break; |
2967 } | 2941 } |
2968 } | 2942 } |
2969 | 2943 |
2970 return NEW(UnaryOperation(op, x)); | 2944 return NEW(UnaryOperation(op, expression)); |
2971 | 2945 |
2972 } else if (Token::IsCountOp(op)) { | 2946 } else if (Token::IsCountOp(op)) { |
2973 op = Next(); | 2947 op = Next(); |
2974 Expression* x = ParseUnaryExpression(CHECK_OK); | 2948 Expression* expression = ParseUnaryExpression(CHECK_OK); |
2975 if (x == NULL || !x->IsValidLeftHandSide()) { | 2949 // Signal a reference error if the expression is an invalid |
2976 if (x != NULL && x->AsCall() != NULL) { | 2950 // left-hand side expression. We could report this as a syntax |
2977 // According to ECMA-262 host function calls are permitted to | 2951 // error here but for compatibility with JSC we choose to report the |
2978 // return references. This cannot happen in our system so we | 2952 // error at runtime. |
2979 // will always get an error. We could report this as a syntax | 2953 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
2980 // error here but for compatibility with KJS and SpiderMonkey we | 2954 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); |
2981 // choose to report the error at runtime. | 2955 expression = NewThrowReferenceError(type); |
2982 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); | |
2983 x = NewThrowReferenceError(type); | |
2984 } else { | |
2985 // Invalid left hand side expressions that are not function | |
2986 // calls are reported as syntax errors at compile time. | |
2987 ReportMessage("invalid_lhs_in_prefix_op", Vector<const char*>::empty()); | |
2988 *ok = false; | |
2989 return NULL; | |
2990 } | |
2991 } | 2956 } |
2992 return NEW(CountOperation(true /* prefix */, op, x)); | 2957 return NEW(CountOperation(true /* prefix */, op, expression)); |
2993 | 2958 |
2994 } else { | 2959 } else { |
2995 return ParsePostfixExpression(ok); | 2960 return ParsePostfixExpression(ok); |
2996 } | 2961 } |
2997 } | 2962 } |
2998 | 2963 |
2999 | 2964 |
3000 Expression* Parser::ParsePostfixExpression(bool* ok) { | 2965 Expression* Parser::ParsePostfixExpression(bool* ok) { |
3001 // PostfixExpression :: | 2966 // PostfixExpression :: |
3002 // LeftHandSideExpression ('++' | '--')? | 2967 // LeftHandSideExpression ('++' | '--')? |
3003 | 2968 |
3004 Expression* result = ParseLeftHandSideExpression(CHECK_OK); | 2969 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
3005 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { | 2970 if (!scanner_.has_line_terminator_before_next() && Token::IsCountOp(peek())) { |
3006 if (result == NULL || !result->IsValidLeftHandSide()) { | 2971 // Signal a reference error if the expression is an invalid |
3007 if (result != NULL && result->AsCall() != NULL) { | 2972 // left-hand side expression. We could report this as a syntax |
3008 // According to ECMA-262 host function calls are permitted to | 2973 // error here but for compatibility with JSC we choose to report the |
3009 // return references. This cannot happen in our system so we | 2974 // error at runtime. |
3010 // will always get an error. We could report this as a syntax | 2975 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3011 // error here but for compatibility with KJS and SpiderMonkey we | 2976 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); |
3012 // choose to report the error at runtime. | 2977 expression = NewThrowReferenceError(type); |
3013 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); | |
3014 result = NewThrowReferenceError(type); | |
3015 } else { | |
3016 // Invalid left hand side expressions that are not function | |
3017 // calls are reported as syntax errors at compile time. | |
3018 ReportMessage("invalid_lhs_in_postfix_op", | |
3019 Vector<const char*>::empty()); | |
3020 *ok = false; | |
3021 return NULL; | |
3022 } | |
3023 } | 2978 } |
3024 Token::Value next = Next(); | 2979 Token::Value next = Next(); |
3025 result = NEW(CountOperation(false /* postfix */, next, result)); | 2980 expression = NEW(CountOperation(false /* postfix */, next, expression)); |
3026 } | 2981 } |
3027 return result; | 2982 return expression; |
3028 } | 2983 } |
3029 | 2984 |
3030 | 2985 |
3031 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { | 2986 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { |
3032 // LeftHandSideExpression :: | 2987 // LeftHandSideExpression :: |
3033 // (NewExpression | MemberExpression) ... | 2988 // (NewExpression | MemberExpression) ... |
3034 | 2989 |
3035 Expression* result; | 2990 Expression* result; |
3036 if (peek() == Token::NEW) { | 2991 if (peek() == Token::NEW) { |
3037 result = ParseNewExpression(CHECK_OK); | 2992 result = ParseNewExpression(CHECK_OK); |
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4885 start_position, | 4840 start_position, |
4886 is_expression); | 4841 is_expression); |
4887 return result; | 4842 return result; |
4888 } | 4843 } |
4889 | 4844 |
4890 | 4845 |
4891 #undef NEW | 4846 #undef NEW |
4892 | 4847 |
4893 | 4848 |
4894 } } // namespace v8::internal | 4849 } } // namespace v8::internal |
OLD | NEW |