Chromium Code Reviews| Index: src/parser.cc |
| =================================================================== |
| --- src/parser.cc (revision 3015) |
| +++ src/parser.cc (working copy) |
| @@ -2798,54 +2798,90 @@ |
| while (Precedence(peek(), accept_IN) == prec1) { |
| Token::Value op = Next(); |
| Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); |
| - |
| // Compute some expressions involving only number literals. |
| - if (x && x->AsLiteral() && x->AsLiteral()->handle()->IsNumber() && |
| - y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) { |
| - double x_val = x->AsLiteral()->handle()->Number(); |
| - double y_val = y->AsLiteral()->handle()->Number(); |
| - |
| - switch (op) { |
| - case Token::ADD: |
| - x = NewNumberLiteral(x_val + y_val); |
| + if (y && y->AsLiteral()) { |
| + Handle<Object> x_handle; |
| + Handle<Object> y_handle = y->AsLiteral()->handle(); |
| + if (x && x->AsLiteral()) { |
| + x_handle = x->AsLiteral()->handle(); |
| + if (x_handle->IsNumber() && y_handle->IsNumber()) { |
| + double x_val = x_handle->Number(); |
| + double y_val = y_handle->Number(); |
| + double new_number = NAN; |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
I find this new code less clear than the old becau
|
| + |
| + switch (op) { |
| + case Token::ADD: { |
| + new_number = x_val + y_val; |
| + break; |
| + } |
| + case Token::SUB: { |
| + new_number = x_val - y_val; |
| + break; |
| + } |
| + case Token::MUL: { |
| + new_number = x_val * y_val; |
| + break; |
| + } |
| + case Token::DIV: { |
| + new_number = x_val / y_val; |
| + break; |
| + } |
| + case Token::BIT_OR: { |
| + new_number = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
| + break; |
| + } |
| + case Token::BIT_AND: { |
| + new_number = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
| + break; |
| + } |
| + case Token::BIT_XOR: { |
| + new_number = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
| + break; |
| + } |
| + case Token::SHL: { |
| + new_number = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
| + break; |
| + } |
| + case Token::SHR: { |
| + uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| + new_number = DoubleToUint32(x_val) >> shift; |
| + break; |
| + } |
| + case Token::SAR: { |
| + uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| + new_number = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
| + break; |
| + } |
| + default: |
| + break; |
| + } |
| + |
| + if (new_number != NAN) { |
|
Kevin Millikin (Chromium)
2009/10/09 04:23:24
You have introduced a bug. Because of the way NaN
|
| + x = NewNumberLiteral(new_number); |
| + continue; |
| + } |
| + } 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
|
| + Handle<String> str1 = Handle<String>::cast(x_handle); |
| + Handle<String> str2 = Handle<String>::cast(y_handle); |
| + Handle<String> str3 = Factory::NewConsString(str1, str2, TENURED); |
| + x = NEW(Literal(str3)); |
| continue; |
| - case Token::SUB: |
| - x = NewNumberLiteral(x_val - y_val); |
| - continue; |
| - case Token::MUL: |
| - x = NewNumberLiteral(x_val * y_val); |
| - continue; |
| - case Token::DIV: |
| - x = NewNumberLiteral(x_val / y_val); |
| - continue; |
| - case Token::BIT_OR: |
| - x = NewNumberLiteral(DoubleToInt32(x_val) | DoubleToInt32(y_val)); |
| - continue; |
| - case Token::BIT_AND: |
| - x = NewNumberLiteral(DoubleToInt32(x_val) & DoubleToInt32(y_val)); |
| - continue; |
| - case Token::BIT_XOR: |
| - x = NewNumberLiteral(DoubleToInt32(x_val) ^ DoubleToInt32(y_val)); |
| - continue; |
| - case Token::SHL: { |
| - int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
| - x = NewNumberLiteral(value); |
| - continue; |
| } |
| - case Token::SHR: { |
| - uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| - uint32_t value = DoubleToUint32(x_val) >> shift; |
| - x = NewNumberLiteral(value); |
| - continue; |
| + } 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
|
| + // is a binary operation |
| + BinaryOperation* bin_op = x->AsBinaryOperation(); |
| + Expression* right = bin_op->right(); |
| + if (bin_op->op() == Token::ADD && right && right->AsLiteral()) { |
| + x_handle = right->AsLiteral()->handle(); |
| + if (x_handle->IsString()) { |
| + Handle<String> str1 = Handle<String>::cast(x_handle); |
| + Handle<String> str2 = Handle<String>::cast(y_handle); |
| + Handle<String> str3 = Factory::NewConsString(str1, str2, TENURED); |
| + right = NEW(Literal(str3)); |
| + x = NEW(BinaryOperation(bin_op->op(), bin_op->left(), right)); |
| + continue; |
| + } |
| } |
| - case Token::SAR: { |
| - uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| - int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
| - x = NewNumberLiteral(value); |
| - continue; |
| - } |
| - default: |
| - break; |
| } |
| } |