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

Unified Diff: src/parser.cc

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
===================================================================
--- src/parser.cc (revision 6941)
+++ src/parser.cc (working copy)
@@ -324,22 +324,26 @@
}
-Handle<String> Parser::LookupSymbol(int symbol_id,
- Vector<const char> string) {
+Handle<String> Parser::LookupSymbol(int symbol_id) {
// Length of symbol cache is the number of identified symbols.
// If we are larger than that, or negative, it's not a cached symbol.
// This might also happen if there is no preparser symbol data, even
// if there is some preparser data.
if (static_cast<unsigned>(symbol_id)
>= static_cast<unsigned>(symbol_cache_.length())) {
- return isolate()->factory()->LookupSymbol(string);
+ if (scanner().is_literal_ascii()) {
+ return isolate()->factory()->LookupAsciiSymbol(
+ scanner().literal_ascii_string());
+ } else {
+ return isolate()->factory()->LookupTwoByteSymbol(
+ scanner().literal_uc16_string());
+ }
}
- return LookupCachedSymbol(symbol_id, string);
+ return LookupCachedSymbol(symbol_id);
}
-Handle<String> Parser::LookupCachedSymbol(int symbol_id,
- Vector<const char> string) {
+Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
// Make sure the cache is large enough to hold the symbol identifier.
if (symbol_cache_.length() <= symbol_id) {
// Increase length to index + 1.
@@ -348,7 +352,13 @@
}
Handle<String> result = symbol_cache_.at(symbol_id);
if (result.is_null()) {
- result = isolate()->factory()->LookupSymbol(string);
+ if (scanner().is_literal_ascii()) {
+ result = isolate()->factory()->LookupAsciiSymbol(
+ scanner().literal_ascii_string());
+ } else {
+ result = isolate()->factory()->LookupTwoByteSymbol(
+ scanner().literal_uc16_string());
+ }
symbol_cache_.at(symbol_id) = result;
return result;
}
@@ -617,11 +627,11 @@
// identical calls.
ExternalTwoByteStringUC16CharacterStream stream(
Handle<ExternalTwoByteString>::cast(source), 0, source->length());
- scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals);
+ scanner_.Initialize(&stream);
return DoParseProgram(source, in_global_context, &zone_scope);
} else {
GenericStringUC16CharacterStream stream(source, 0, source->length());
- scanner_.Initialize(&stream, JavaScriptScanner::kAllLiterals);
+ scanner_.Initialize(&stream);
return DoParseProgram(source, in_global_context, &zone_scope);
}
}
@@ -707,7 +717,7 @@
FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info,
UC16CharacterStream* source,
ZoneScope* zone_scope) {
- scanner_.Initialize(source, JavaScriptScanner::kAllLiterals);
+ scanner_.Initialize(source);
ASSERT(target_stack_ == NULL);
Handle<String> name(String::cast(info->name()));
@@ -759,7 +769,7 @@
if (pre_data() != NULL) {
symbol_id = pre_data()->GetSymbolIdentifier();
}
- return LookupSymbol(symbol_id, scanner().literal());
+ return LookupSymbol(symbol_id);
}
@@ -2327,26 +2337,6 @@
}
}
- // 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.)
@@ -2728,8 +2718,9 @@
case Token::NUMBER: {
Consume(Token::NUMBER);
- double value =
- StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS);
+ ASSERT(scanner().is_literal_ascii());
+ double value = StringToDouble(scanner().literal_ascii_string(),
+ ALLOW_HEX | ALLOW_OCTALS);
result = NewNumberLiteral(value);
break;
}
@@ -3001,14 +2992,22 @@
// { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
// We have already read the "get" or "set" keyword.
Token::Value next = Next();
- // TODO(820): Allow NUMBER and STRING as well (and handle array indices).
- if (next == Token::IDENTIFIER || Token::IsKeyword(next)) {
- Handle<String> name = GetSymbol(CHECK_OK);
+ bool is_keyword = Token::IsKeyword(next);
+ if (next == Token::IDENTIFIER || next == Token::NUMBER ||
+ next == Token::STRING || is_keyword) {
+ Handle<String> name;
+ if (is_keyword) {
+ name = isolate_->factory()->LookupAsciiSymbol(Token::String(next));
+ } else {
+ name = GetSymbol(CHECK_OK);
+ }
FunctionLiteral* value =
ParseFunctionLiteral(name,
RelocInfo::kNoPosition,
DECLARATION,
CHECK_OK);
+ // Allow any number of parameters for compatiabilty with JSC.
+ // Specification only allows zero parameters for get and one for set.
ObjectLiteral::Property* property =
new ObjectLiteral::Property(is_getter, value);
return property;
@@ -3079,8 +3078,9 @@
}
case Token::NUMBER: {
Consume(Token::NUMBER);
- double value =
- StringToDouble(scanner().literal(), ALLOW_HEX | ALLOW_OCTALS);
+ ASSERT(scanner().is_literal_ascii());
+ double value = StringToDouble(scanner().literal_ascii_string(),
+ ALLOW_HEX | ALLOW_OCTALS);
key = NewNumberLiteral(value);
break;
}
@@ -3150,11 +3150,9 @@
int literal_index = temp_scope_->NextMaterializedLiteralIndex();
- Handle<String> js_pattern =
- isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED);
+ Handle<String> js_pattern = NextLiteralString(TENURED);
scanner().ScanRegExpFlags();
- Handle<String> js_flags =
- isolate_->factory()->NewStringFromUtf8(scanner().next_literal(), TENURED);
+ Handle<String> js_flags = NextLiteralString(TENURED);
Next();
return new RegExpLiteral(js_pattern, js_flags, literal_index);
@@ -3438,10 +3436,10 @@
bool* ok) {
Expect(Token::IDENTIFIER, ok);
if (!*ok) return Handle<String>();
- if (scanner().literal_length() == 3) {
- const char* token = scanner().literal_string();
- *is_get = strcmp(token, "get") == 0;
- *is_set = !*is_get && strcmp(token, "set") == 0;
+ if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
+ const char* token = scanner().literal_ascii_string().start();
+ *is_get = strncmp(token, "get", 3) == 0;
+ *is_set = !*is_get && strncmp(token, "set", 3) == 0;
}
return GetSymbol(ok);
}
@@ -3623,9 +3621,13 @@
if (literal_length == 0) {
return isolate()->factory()->empty_string();
}
- const char* literal_string = scanner_.literal_string();
- Vector<const char> literal(literal_string, literal_length);
- return isolate()->factory()->NewStringFromUtf8(literal);
+ if (scanner_.is_literal_ascii()) {
+ return isolate()->factory()->NewStringFromAscii(
+ scanner_.literal_ascii_string());
+ } else {
+ return isolate()->factory()->NewStringFromTwoByte(
+ scanner_.literal_uc16_string());
+ }
}
@@ -3637,7 +3639,8 @@
return GetString();
}
case Token::NUMBER: {
- double value = StringToDouble(scanner_.literal(),
+ ASSERT(scanner_.is_literal_ascii());
+ double value = StringToDouble(scanner_.literal_ascii_string(),
NO_FLAGS, // Hex, octal or trailing junk.
OS::nan_value());
return isolate()->factory()->NewNumber(value);
@@ -3683,9 +3686,9 @@
if (value.is_null()) return Handle<Object>::null();
uint32_t index;
if (key->AsArrayIndex(&index)) {
- SetElement(json_object, index, value);
+ SetOwnElement(json_object, index, value);
} else {
- SetProperty(json_object, key, value, NONE);
+ SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
}
} while (scanner_.Next() == Token::COMMA);
if (scanner_.current_token() != Token::RBRACE) {
@@ -4046,9 +4049,21 @@
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': {
@@ -4299,23 +4314,6 @@
}
-// 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
@@ -4381,9 +4379,23 @@
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
@@ -4594,11 +4606,10 @@
// Create a Scanner for the preparser to use as input, and preparse the source.
static ScriptDataImpl* DoPreParse(UC16CharacterStream* source,
bool allow_lazy,
- ParserRecorder* recorder,
- int literal_flags) {
+ ParserRecorder* recorder) {
Isolate* isolate = Isolate::Current();
V8JavaScriptScanner scanner(isolate);
- scanner.Initialize(source, literal_flags);
+ scanner.Initialize(source);
intptr_t stack_limit = isolate->stack_guard()->real_climit();
if (!preparser::PreParser::PreParseProgram(&scanner,
recorder,
@@ -4626,8 +4637,7 @@
return NULL;
}
PartialParserRecorder recorder;
- return DoPreParse(source, allow_lazy, &recorder,
- JavaScriptScanner::kNoLiterals);
+ return DoPreParse(source, allow_lazy, &recorder);
}
@@ -4636,9 +4646,7 @@
Handle<Script> no_script;
bool allow_lazy = FLAG_lazy && (extension == NULL);
CompleteParserRecorder recorder;
- int kPreParseLiteralsFlags =
- JavaScriptScanner::kLiteralString | JavaScriptScanner::kLiteralIdentifier;
- return DoPreParse(source, allow_lazy, &recorder, kPreParseLiteralsFlags);
+ return DoPreParse(source, allow_lazy, &recorder);
}
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698