Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/parser.cc

Issue 6113004: Version 3.0.7 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 2305 matching lines...) Expand 10 before | Expand all | Expand 10 after
2316 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 2316 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2317 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 2317 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
2318 x = NewNumberLiteral(value); 2318 x = NewNumberLiteral(value);
2319 continue; 2319 continue;
2320 } 2320 }
2321 default: 2321 default:
2322 break; 2322 break;
2323 } 2323 }
2324 } 2324 }
2325 2325
2326 // Convert constant divisions to multiplications for speed.
2327 if (op == Token::DIV &&
2328 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
2329 double y_val = y->AsLiteral()->handle()->Number();
2330 int64_t y_int = static_cast<int64_t>(y_val);
2331 // There are rounding issues with this optimization, but they don't
2332 // apply if the number to be divided with has a reciprocal that can be
2333 // precisely represented as a floating point number. This is the case
2334 // if the number is an integer power of 2. Negative integer powers of
2335 // 2 work too, but for -2, -1, 1 and 2 we don't do the strength
2336 // reduction because the inlined optimistic idiv has a reasonable
2337 // chance of succeeding by producing a Smi answer with no remainder.
2338 if (static_cast<double>(y_int) == y_val &&
2339 (IsPowerOf2(y_int) || IsPowerOf2(-y_int)) &&
2340 (y_int > 2 || y_int < -2)) {
2341 y = NewNumberLiteral(1 / y_val);
2342 op = Token::MUL;
2343 }
2344 }
2345
2346 // For now we distinguish between comparisons and other binary 2326 // For now we distinguish between comparisons and other binary
2347 // operations. (We could combine the two and get rid of this 2327 // operations. (We could combine the two and get rid of this
2348 // code and AST node eventually.) 2328 // code and AST node eventually.)
2349 if (Token::IsCompareOp(op)) { 2329 if (Token::IsCompareOp(op)) {
2350 // We have a comparison. 2330 // We have a comparison.
2351 Token::Value cmp = op; 2331 Token::Value cmp = op;
2352 switch (op) { 2332 switch (op) {
2353 case Token::NE: cmp = Token::EQ; break; 2333 case Token::NE: cmp = Token::EQ; break;
2354 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2334 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2355 default: break; 2335 default: break;
(...skipping 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after
3673 return ReportUnexpectedToken(); 3653 return ReportUnexpectedToken();
3674 } 3654 }
3675 Handle<String> key = GetString(); 3655 Handle<String> key = GetString();
3676 if (scanner_.Next() != Token::COLON) { 3656 if (scanner_.Next() != Token::COLON) {
3677 return ReportUnexpectedToken(); 3657 return ReportUnexpectedToken();
3678 } 3658 }
3679 Handle<Object> value = ParseJsonValue(); 3659 Handle<Object> value = ParseJsonValue();
3680 if (value.is_null()) return Handle<Object>::null(); 3660 if (value.is_null()) return Handle<Object>::null();
3681 uint32_t index; 3661 uint32_t index;
3682 if (key->AsArrayIndex(&index)) { 3662 if (key->AsArrayIndex(&index)) {
3683 CALL_HEAP_FUNCTION_INLINE( 3663 SetOwnElement(json_object, index, value);
3684 (*json_object)->SetElement(index, *value, true));
3685 } else { 3664 } else {
3686 CALL_HEAP_FUNCTION_INLINE( 3665 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
3687 (*json_object)->SetPropertyPostInterceptor(*key, *value, NONE));
3688 } 3666 }
3689 } while (scanner_.Next() == Token::COMMA); 3667 } while (scanner_.Next() == Token::COMMA);
3690 if (scanner_.current_token() != Token::RBRACE) { 3668 if (scanner_.current_token() != Token::RBRACE) {
3691 return ReportUnexpectedToken(); 3669 return ReportUnexpectedToken();
3692 } 3670 }
3693 } 3671 }
3694 return json_object; 3672 return json_object;
3695 } 3673 }
3696 3674
3697 3675
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 break; 4015 break;
4038 case 't': 4016 case 't':
4039 Advance(2); 4017 Advance(2);
4040 builder->AddCharacter('\t'); 4018 builder->AddCharacter('\t');
4041 break; 4019 break;
4042 case 'v': 4020 case 'v':
4043 Advance(2); 4021 Advance(2);
4044 builder->AddCharacter('\v'); 4022 builder->AddCharacter('\v');
4045 break; 4023 break;
4046 case 'c': { 4024 case 'c': {
4047 Advance(2); 4025 Advance();
4048 uc32 control = ParseControlLetterEscape(); 4026 uc32 controlLetter = Next();
4049 builder->AddCharacter(control); 4027 // Special case if it is an ASCII letter.
4028 // Convert lower case letters to uppercase.
4029 uc32 letter = controlLetter & ~('a' ^ 'A');
4030 if (letter < 'A' || 'Z' < letter) {
4031 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4032 // This is outside the specification. We match JSC in
4033 // reading the backslash as a literal character instead
4034 // of as starting an escape.
4035 builder->AddCharacter('\\');
4036 } else {
4037 Advance(2);
4038 builder->AddCharacter(controlLetter & 0x1f);
4039 }
4050 break; 4040 break;
4051 } 4041 }
4052 case 'x': { 4042 case 'x': {
4053 Advance(2); 4043 Advance(2);
4054 uc32 value; 4044 uc32 value;
4055 if (ParseHexEscape(2, &value)) { 4045 if (ParseHexEscape(2, &value)) {
4056 builder->AddCharacter(value); 4046 builder->AddCharacter(value);
4057 } else { 4047 } else {
4058 builder->AddCharacter('x'); 4048 builder->AddCharacter('x');
4059 } 4049 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4314 } else { 4304 } else {
4315 Reset(start); 4305 Reset(start);
4316 return false; 4306 return false;
4317 } 4307 }
4318 *min_out = min; 4308 *min_out = min;
4319 *max_out = max; 4309 *max_out = max;
4320 return true; 4310 return true;
4321 } 4311 }
4322 4312
4323 4313
4324 // Upper and lower case letters differ by one bit.
4325 STATIC_CHECK(('a' ^ 'A') == 0x20);
4326
4327 uc32 RegExpParser::ParseControlLetterEscape() {
4328 if (!has_more())
4329 return 'c';
4330 uc32 letter = current() & ~(0x20); // Collapse upper and lower case letters.
4331 if (letter < 'A' || 'Z' < letter) {
4332 // Non-spec error-correction: "\c" followed by non-control letter is
4333 // interpreted as an IdentityEscape of 'c'.
4334 return 'c';
4335 }
4336 Advance();
4337 return letter & 0x1f; // Remainder modulo 32, per specification.
4338 }
4339
4340
4341 uc32 RegExpParser::ParseOctalLiteral() { 4314 uc32 RegExpParser::ParseOctalLiteral() {
4342 ASSERT('0' <= current() && current() <= '7'); 4315 ASSERT('0' <= current() && current() <= '7');
4343 // For compatibility with some other browsers (not all), we parse 4316 // For compatibility with some other browsers (not all), we parse
4344 // up to three octal digits with a value below 256. 4317 // up to three octal digits with a value below 256.
4345 uc32 value = current() - '0'; 4318 uc32 value = current() - '0';
4346 Advance(); 4319 Advance();
4347 if ('0' <= current() && current() <= '7') { 4320 if ('0' <= current() && current() <= '7') {
4348 value = value * 8 + current() - '0'; 4321 value = value * 8 + current() - '0';
4349 Advance(); 4322 Advance();
4350 if (value < 32 && '0' <= current() && current() <= '7') { 4323 if (value < 32 && '0' <= current() && current() <= '7') {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4396 return '\n'; 4369 return '\n';
4397 case 'r': 4370 case 'r':
4398 Advance(); 4371 Advance();
4399 return '\r'; 4372 return '\r';
4400 case 't': 4373 case 't':
4401 Advance(); 4374 Advance();
4402 return '\t'; 4375 return '\t';
4403 case 'v': 4376 case 'v':
4404 Advance(); 4377 Advance();
4405 return '\v'; 4378 return '\v';
4406 case 'c': 4379 case 'c': {
4407 Advance(); 4380 uc32 controlLetter = Next();
4408 return ParseControlLetterEscape(); 4381 uc32 letter = controlLetter & ~('A' ^ 'a');
4382 // For compatibility with JSC, inside a character class
4383 // we also accept digits and underscore as control characters.
4384 if ((controlLetter >= '0' && controlLetter <= '9') ||
4385 controlLetter == '_' ||
4386 (letter >= 'A' && letter <= 'Z')) {
4387 Advance(2);
4388 // Control letters mapped to ASCII control characters in the range
4389 // 0x00-0x1f.
4390 return controlLetter & 0x1f;
4391 }
4392 // We match JSC in reading the backslash as a literal
4393 // character instead of as starting an escape.
4394 return '\\';
4395 }
4409 case '0': case '1': case '2': case '3': case '4': case '5': 4396 case '0': case '1': case '2': case '3': case '4': case '5':
4410 case '6': case '7': 4397 case '6': case '7':
4411 // For compatibility, we interpret a decimal escape that isn't 4398 // For compatibility, we interpret a decimal escape that isn't
4412 // a back reference (and therefore either \0 or not valid according 4399 // a back reference (and therefore either \0 or not valid according
4413 // to the specification) as a 1..3 digit octal character code. 4400 // to the specification) as a 1..3 digit octal character code.
4414 return ParseOctalLiteral(); 4401 return ParseOctalLiteral();
4415 case 'x': { 4402 case 'x': {
4416 Advance(); 4403 Advance();
4417 uc32 value; 4404 uc32 value;
4418 if (ParseHexEscape(2, &value)) { 4405 if (ParseHexEscape(2, &value)) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
4708 Handle<String> source = Handle<String>(String::cast(script->source())); 4695 Handle<String> source = Handle<String>(String::cast(script->source()));
4709 result = parser.ParseProgram(source, info->is_global()); 4696 result = parser.ParseProgram(source, info->is_global());
4710 } 4697 }
4711 } 4698 }
4712 4699
4713 info->SetFunction(result); 4700 info->SetFunction(result);
4714 return (result != NULL); 4701 return (result != NULL);
4715 } 4702 }
4716 4703
4717 } } // namespace v8::internal 4704 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698