| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index 55269339ab556ebb4c04bfbc4dedca5842ce35aa..5ea1c5e083ac44a15ea4ac100f1f6848d9d4fffd 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -2323,26 +2323,6 @@ Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
|
| }
|
| }
|
|
|
| - // Convert constant divisions to multiplications for speed.
|
| - if (op == Token::DIV &&
|
| - y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
|
| - double y_val = y->AsLiteral()->handle()->Number();
|
| - int64_t y_int = static_cast<int64_t>(y_val);
|
| - // There are rounding issues with this optimization, but they don't
|
| - // apply if the number to be divided with has a reciprocal that can be
|
| - // precisely represented as a floating point number. This is the case
|
| - // if the number is an integer power of 2. Negative integer powers of
|
| - // 2 work too, but for -2, -1, 1 and 2 we don't do the strength
|
| - // reduction because the inlined optimistic idiv has a reasonable
|
| - // chance of succeeding by producing a Smi answer with no remainder.
|
| - if (static_cast<double>(y_int) == y_val &&
|
| - (IsPowerOf2(y_int) || IsPowerOf2(-y_int)) &&
|
| - (y_int > 2 || y_int < -2)) {
|
| - y = NewNumberLiteral(1 / y_val);
|
| - op = Token::MUL;
|
| - }
|
| - }
|
| -
|
| // For now we distinguish between comparisons and other binary
|
| // operations. (We could combine the two and get rid of this
|
| // code and AST node eventually.)
|
| @@ -3680,11 +3660,9 @@ Handle<Object> JsonParser::ParseJsonObject() {
|
| if (value.is_null()) return Handle<Object>::null();
|
| uint32_t index;
|
| if (key->AsArrayIndex(&index)) {
|
| - CALL_HEAP_FUNCTION_INLINE(
|
| - (*json_object)->SetElement(index, *value, true));
|
| + SetOwnElement(json_object, index, value);
|
| } else {
|
| - CALL_HEAP_FUNCTION_INLINE(
|
| - (*json_object)->SetPropertyPostInterceptor(*key, *value, NONE));
|
| + SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
|
| }
|
| } while (scanner_.Next() == Token::COMMA);
|
| if (scanner_.current_token() != Token::RBRACE) {
|
| @@ -4044,9 +4022,21 @@ RegExpTree* RegExpParser::ParseDisjunction() {
|
| builder->AddCharacter('\v');
|
| break;
|
| case 'c': {
|
| - Advance(2);
|
| - uc32 control = ParseControlLetterEscape();
|
| - builder->AddCharacter(control);
|
| + Advance();
|
| + uc32 controlLetter = Next();
|
| + // Special case if it is an ASCII letter.
|
| + // Convert lower case letters to uppercase.
|
| + uc32 letter = controlLetter & ~('a' ^ 'A');
|
| + if (letter < 'A' || 'Z' < letter) {
|
| + // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
|
| + // This is outside the specification. We match JSC in
|
| + // reading the backslash as a literal character instead
|
| + // of as starting an escape.
|
| + builder->AddCharacter('\\');
|
| + } else {
|
| + Advance(2);
|
| + builder->AddCharacter(controlLetter & 0x1f);
|
| + }
|
| break;
|
| }
|
| case 'x': {
|
| @@ -4321,23 +4311,6 @@ bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
|
| }
|
|
|
|
|
| -// Upper and lower case letters differ by one bit.
|
| -STATIC_CHECK(('a' ^ 'A') == 0x20);
|
| -
|
| -uc32 RegExpParser::ParseControlLetterEscape() {
|
| - if (!has_more())
|
| - return 'c';
|
| - uc32 letter = current() & ~(0x20); // Collapse upper and lower case letters.
|
| - if (letter < 'A' || 'Z' < letter) {
|
| - // Non-spec error-correction: "\c" followed by non-control letter is
|
| - // interpreted as an IdentityEscape of 'c'.
|
| - return 'c';
|
| - }
|
| - Advance();
|
| - return letter & 0x1f; // Remainder modulo 32, per specification.
|
| -}
|
| -
|
| -
|
| uc32 RegExpParser::ParseOctalLiteral() {
|
| ASSERT('0' <= current() && current() <= '7');
|
| // For compatibility with some other browsers (not all), we parse
|
| @@ -4403,9 +4376,23 @@ uc32 RegExpParser::ParseClassCharacterEscape() {
|
| case 'v':
|
| Advance();
|
| return '\v';
|
| - case 'c':
|
| - Advance();
|
| - return ParseControlLetterEscape();
|
| + case 'c': {
|
| + uc32 controlLetter = Next();
|
| + uc32 letter = controlLetter & ~('A' ^ 'a');
|
| + // For compatibility with JSC, inside a character class
|
| + // we also accept digits and underscore as control characters.
|
| + if ((controlLetter >= '0' && controlLetter <= '9') ||
|
| + controlLetter == '_' ||
|
| + (letter >= 'A' && letter <= 'Z')) {
|
| + Advance(2);
|
| + // Control letters mapped to ASCII control characters in the range
|
| + // 0x00-0x1f.
|
| + return controlLetter & 0x1f;
|
| + }
|
| + // We match JSC in reading the backslash as a literal
|
| + // character instead of as starting an escape.
|
| + return '\\';
|
| + }
|
| case '0': case '1': case '2': case '3': case '4': case '5':
|
| case '6': case '7':
|
| // For compatibility, we interpret a decimal escape that isn't
|
|
|