| 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 |