Commit 53690b68 authored by lrn@chromium.org's avatar lrn@chromium.org

Changed layout of object literal parser.

Review URL: http://codereview.chromium.org/3032064

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5206 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 53e22e38
...@@ -210,6 +210,7 @@ class Parser { ...@@ -210,6 +210,7 @@ class Parser {
Expression* ParsePrimaryExpression(bool* ok); Expression* ParsePrimaryExpression(bool* ok);
Expression* ParseArrayLiteral(bool* ok); Expression* ParseArrayLiteral(bool* ok);
Expression* ParseObjectLiteral(bool* ok); Expression* ParseObjectLiteral(bool* ok);
ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
// Populate the constant properties fixed array for a materialized object // Populate the constant properties fixed array for a materialized object
...@@ -3376,11 +3377,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { ...@@ -3376,11 +3377,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
// default case. // default case.
default: { default: {
Token::Value tok = peek(); Token::Value tok = Next();
// Token::Peek returns the value of the next token but
// location() gives info about the current token.
// Therefore, we need to read ahead to the next token
Next();
ReportUnexpectedToken(tok); ReportUnexpectedToken(tok);
*ok = false; *ok = false;
return NULL; return NULL;
...@@ -3584,6 +3581,35 @@ void Parser::BuildObjectLiteralConstantProperties( ...@@ -3584,6 +3581,35 @@ void Parser::BuildObjectLiteralConstantProperties(
} }
ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
bool* ok) {
// Special handling of getter and setter syntax:
// { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
// We have already read the "get" or "set" keyword.
Token::Value next = Next();
if (next == Token::IDENTIFIER ||
next == Token::STRING ||
next == Token::NUMBER ||
Token::IsKeyword(next)) {
Handle<String> name =
factory()->LookupSymbol(scanner_.literal_string(),
scanner_.literal_length());
FunctionLiteral* value =
ParseFunctionLiteral(name,
RelocInfo::kNoPosition,
DECLARATION,
CHECK_OK);
ObjectLiteral::Property* property =
NEW(ObjectLiteral::Property(is_getter, value));
return property;
} else {
ReportUnexpectedToken(next);
*ok = false;
return NULL;
}
}
Expression* Parser::ParseObjectLiteral(bool* ok) { Expression* Parser::ParseObjectLiteral(bool* ok) {
// ObjectLiteral :: // ObjectLiteral ::
// '{' ( // '{' (
...@@ -3601,32 +3627,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3601,32 +3627,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
Token::Value next = peek(); Token::Value next = peek();
switch (next) { switch (next) {
case Token::IDENTIFIER: { case Token::IDENTIFIER: {
// Store identifier keys as literal symbols to avoid
// resolving them when compiling code for the object
// literal.
bool is_getter = false; bool is_getter = false;
bool is_setter = false; bool is_setter = false;
Handle<String> id = Handle<String> id =
ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
if (is_getter || is_setter) { if ((is_getter || is_setter) && peek() != Token::COLON) {
// Special handling of getter and setter syntax.
Handle<String> name;
next = peek();
if (next == Token::IDENTIFIER ||
next == Token::STRING ||
next == Token::NUMBER ||
Token::IsKeyword(next)) {
Consume(next);
Handle<String> name =
factory()->LookupSymbol(scanner_.literal_string(),
scanner_.literal_length());
FunctionLiteral* value =
ParseFunctionLiteral(name,
RelocInfo::kNoPosition,
DECLARATION,
CHECK_OK);
ObjectLiteral::Property* property = ObjectLiteral::Property* property =
NEW(ObjectLiteral::Property(is_getter, value)); ParseObjectLiteralGetSet(is_getter, CHECK_OK);
if (IsBoilerplateProperty(property)) { if (IsBoilerplateProperty(property)) {
number_of_boilerplate_properties++; number_of_boilerplate_properties++;
} }
...@@ -3634,31 +3641,25 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3634,31 +3641,25 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
continue; // restart the while continue; // restart the while
} }
} // Failed to parse as get/set property, so it's just a property
// called "get" or "set".
key = NEW(Literal(id)); key = NEW(Literal(id));
break; break;
} }
#define CASE_KEYWORD(name, ignore1, ignore2) \
case Token::name:
TOKEN_LIST(IGNORE_TOKEN, CASE_KEYWORD, IGNORE_TOKEN)
#undef CASE_KEYWORD
// FALLTHROUGH - keyword tokens fall through to the same code as strings.
case Token::STRING: { case Token::STRING: {
Consume(next); Consume(Token::STRING);
Handle<String> string = Handle<String> string =
factory()->LookupSymbol(scanner_.literal_string(), factory()->LookupSymbol(scanner_.literal_string(),
scanner_.literal_length()); scanner_.literal_length());
uint32_t index; uint32_t index;
if (next == Token::STRING && if (!string.is_null() &&
!string.is_null() &&
string->AsArrayIndex(&index)) { string->AsArrayIndex(&index)) {
key = NewNumberLiteral(index); key = NewNumberLiteral(index);
} else { break;
key = NEW(Literal(string));
} }
key = NEW(Literal(string));
break; break;
} }
case Token::NUMBER: { case Token::NUMBER: {
Consume(Token::NUMBER); Consume(Token::NUMBER);
double value = double value =
...@@ -3666,10 +3667,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ...@@ -3666,10 +3667,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
key = NewNumberLiteral(value); key = NewNumberLiteral(value);
break; break;
} }
default: default:
Expect(Token::RBRACE, CHECK_OK); if (Token::IsKeyword(next)) {
break; Consume(next);
Handle<String> string =
factory()->LookupSymbol(scanner_.literal_string(),
scanner_.literal_length());
key = NEW(Literal(string));
} else {
// Unexpected token.
Token::Value next = Next();
ReportUnexpectedToken(next);
*ok = false;
return NULL;
}
} }
Expect(Token::COLON, CHECK_OK); Expect(Token::COLON, CHECK_OK);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment