Chromium Code Reviews| 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 2780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2791 | 2791 |
| 2792 // Precedence >= 4 | 2792 // Precedence >= 4 |
| 2793 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | 2793 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { |
| 2794 ASSERT(prec >= 4); | 2794 ASSERT(prec >= 4); |
| 2795 Expression* x = ParseUnaryExpression(CHECK_OK); | 2795 Expression* x = ParseUnaryExpression(CHECK_OK); |
| 2796 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | 2796 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { |
| 2797 // prec1 >= 4 | 2797 // prec1 >= 4 |
| 2798 while (Precedence(peek(), accept_IN) == prec1) { | 2798 while (Precedence(peek(), accept_IN) == prec1) { |
| 2799 Token::Value op = Next(); | 2799 Token::Value op = Next(); |
| 2800 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | 2800 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| 2801 | |
| 2802 // Compute some expressions involving only number literals. | 2801 // Compute some expressions involving only number literals. |
| 2803 if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() && | 2802 if (y && y->AsLiteral()) { |
| 2804 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { | 2803 Handle<Object> x_handle; |
| 2805 double x_val = x->AsLiteral()->handle()->Number(); | 2804 Handle<Object> y_handle = y->AsLiteral()->handle(); |
| 2806 double y_val = y->AsLiteral()->handle()->Number(); | 2805 if (x && x->AsLiteral()) { |
| 2807 | 2806 x_handle = x->AsLiteral()->handle(); |
| 2808 switch (op) { | 2807 if (x_handle->IsNumber() && y_handle->IsNumber()) { |
| 2809 case Token::ADD: | 2808 double x_val = x_handle->Number(); |
| 2810 x = NewNumberLiteral(x_val + y_val); | 2809 double y_val = y_handle->Number(); |
| 2811 continue; | 2810 double new_number = NAN; |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
I find this new code less clear than the old becau
| |
| 2812 case Token::SUB: | 2811 |
| 2813 x = NewNumberLiteral(x_val - y_val); | 2812 switch (op) { |
| 2814 continue; | 2813 case Token::ADD: { |
| 2815 case Token::MUL: | 2814 new_number = x_val + y_val; |
| 2816 x = NewNumberLiteral(x_val * y_val); | 2815 break; |
| 2817 continue; | 2816 } |
| 2818 case Token::DIV: | 2817 case Token::SUB: { |
| 2819 x = NewNumberLiteral(x_val / y_val); | 2818 new_number = x_val - y_val; |
| 2820 continue; | 2819 break; |
| 2821 case Token::BIT_OR: | 2820 } |
| 2822 x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val)); | 2821 case Token::MUL: { |
| 2823 continue; | 2822 new_number = x_val * y_val; |
| 2824 case Token::BIT_AND: | 2823 break; |
| 2825 x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val)); | 2824 } |
| 2826 continue; | 2825 case Token::DIV: { |
| 2827 case Token::BIT_XOR: | 2826 new_number = x_val / y_val; |
| 2828 x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val)); | 2827 break; |
| 2829 continue; | 2828 } |
| 2830 case Token::SHL: { | 2829 case Token::BIT_OR: { |
| 2831 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); | 2830 new_number = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
| 2832 x = NewNumberLiteral(value); | 2831 break; |
| 2832 } | |
| 2833 case Token::BIT_AND: { | |
| 2834 new_number = DoubleToInt32(x_val) & DoubleToInt32(y_val); | |
| 2835 break; | |
| 2836 } | |
| 2837 case Token::BIT_XOR: { | |
| 2838 new_number = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); | |
| 2839 break; | |
| 2840 } | |
| 2841 case Token::SHL: { | |
| 2842 new_number = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1 f); | |
| 2843 break; | |
| 2844 } | |
| 2845 case Token::SHR: { | |
| 2846 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | |
| 2847 new_number = DoubleToUint32(x_val) >> shift; | |
| 2848 break; | |
| 2849 } | |
| 2850 case Token::SAR: { | |
| 2851 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | |
| 2852 new_number = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | |
| 2853 break; | |
| 2854 } | |
| 2855 default: | |
| 2856 break; | |
| 2857 } | |
| 2858 | |
| 2859 if (new_number != NAN) { | |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
You have introduced a bug. Because of the way NaN
| |
| 2860 x = NewNumberLiteral(new_number); | |
| 2861 continue; | |
| 2862 } | |
| 2863 } else if (x_handle->IsString() && y_handle->IsString()) { | |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
No, you cannot do this optimization unless op is T
| |
| 2864 Handle<String> str1 = Handle<String>::cast(x_handle); | |
| 2865 Handle<String> str2 = Handle<String>::cast(y_handle); | |
| 2866 Handle<String> str3 = Factory::NewConsString(str1, str2, TENURED); | |
| 2867 x = NEW(Literal(str3)); | |
| 2833 continue; | 2868 continue; |
| 2834 } | 2869 } |
| 2835 case Token::SHR: { | 2870 } else if (x && x->AsBinaryOperation() && y_handle->IsString()) { |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
You cannot do this optimization unless op is Token
| |
| 2836 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | 2871 // is a binary operation |
| 2837 uint32_t value = DoubleToUint32(x_val) >> shift; | 2872 BinaryOperation* bin_op = x->AsBinaryOperation(); |
| 2838 x = NewNumberLiteral(value); | 2873 Expression* right = bin_op->right(); |
| 2839 continue; | 2874 if (bin_op->op() == Token::ADD && right && right->AsLiteral()) { |
| 2875 x_handle = right->AsLiteral()->handle(); | |
| 2876 if (x_handle->IsString()) { | |
| 2877 Handle<String> str1 = Handle<String>::cast(x_handle); | |
| 2878 Handle<String> str2 = Handle<String>::cast(y_handle); | |
| 2879 Handle<String> str3 = Factory::NewConsString(str1, str2, TENURED); | |
| 2880 right = NEW(Literal(str3)); | |
| 2881 x = NEW(BinaryOperation(bin_op->op(), bin_op->left(), right)); | |
| 2882 continue; | |
| 2883 } | |
| 2840 } | 2884 } |
| 2841 case Token::SAR: { | |
| 2842 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | |
| 2843 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | |
| 2844 x = NewNumberLiteral(value); | |
| 2845 continue; | |
| 2846 } | |
| 2847 default: | |
| 2848 break; | |
| 2849 } | 2885 } |
| 2850 } | 2886 } |
| 2851 | 2887 |
| 2852 // Convert constant divisions to multiplications for speed. | 2888 // Convert constant divisions to multiplications for speed. |
| 2853 if (op == Token::DIV && | 2889 if (op == Token::DIV && |
| 2854 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { | 2890 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { |
| 2855 double y_val = y->AsLiteral()->handle()->Number(); | 2891 double y_val = y->AsLiteral()->handle()->Number(); |
| 2856 int64_t y_int = static_cast<int64_t>(y_val); | 2892 int64_t y_int = static_cast<int64_t>(y_val); |
| 2857 // There are rounding issues with this optimization, but they don't | 2893 // There are rounding issues with this optimization, but they don't |
| 2858 // apply if the number to be divided with has a reciprocal that can be | 2894 // apply if the number to be divided with has a reciprocal that can be |
| (...skipping 1967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4826 start_position, | 4862 start_position, |
| 4827 is_expression); | 4863 is_expression); |
| 4828 return result; | 4864 return result; |
| 4829 } | 4865 } |
| 4830 | 4866 |
| 4831 | 4867 |
| 4832 #undef NEW | 4868 #undef NEW |
| 4833 | 4869 |
| 4834 | 4870 |
| 4835 } } // namespace v8::internal | 4871 } } // namespace v8::internal |
| OLD | NEW |