| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index dd5f9bd0d05080f0ba0f328a80ea0e9611ce1e30..bf1a348211e138273d2fff6ee7463d2880341ad6 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -265,6 +265,7 @@ class Parser {
|
| Literal* GetLiteralNumber(double value);
|
|
|
| Handle<String> ParseIdentifier(bool* ok);
|
| + Handle<String> ParseIdentifierName(bool* ok);
|
| Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
|
| bool* is_set,
|
| bool* ok);
|
| @@ -3121,7 +3122,7 @@ Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
|
| case Token::PERIOD: {
|
| Consume(Token::PERIOD);
|
| int pos = scanner().location().beg_pos;
|
| - Handle<String> name = ParseIdentifier(CHECK_OK);
|
| + Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| result = factory()->NewProperty(result, NEW(Literal(name)), pos);
|
| break;
|
| }
|
| @@ -3207,7 +3208,7 @@ Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
|
| case Token::PERIOD: {
|
| Consume(Token::PERIOD);
|
| int pos = scanner().location().beg_pos;
|
| - Handle<String> name = ParseIdentifier(CHECK_OK);
|
| + Handle<String> name = ParseIdentifierName(CHECK_OK);
|
| result = factory()->NewProperty(result, NEW(Literal(name)), pos);
|
| break;
|
| }
|
| @@ -3586,8 +3587,8 @@ void Parser::BuildObjectLiteralConstantProperties(
|
| Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| // ObjectLiteral ::
|
| // '{' (
|
| - // ((Identifier | String | Number) ':' AssignmentExpression)
|
| - // | (('get' | 'set') FunctionLiteral)
|
| + // ((IdentifierName | String | Number) ':' AssignmentExpression)
|
| + // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
|
| // )*[','] '}'
|
|
|
| ZoneListWrapper<ObjectLiteral::Property> properties =
|
| @@ -3597,7 +3598,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| Expect(Token::LBRACE, CHECK_OK);
|
| while (peek() != Token::RBRACE) {
|
| Literal* key = NULL;
|
| - switch (peek()) {
|
| + Token::Value next = peek();
|
| + switch (next) {
|
| case Token::IDENTIFIER: {
|
| // Store identifier keys as literal symbols to avoid
|
| // resolving them when compiling code for the object
|
| @@ -3608,15 +3610,26 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
|
| if (is_getter || is_setter) {
|
| // Special handling of getter and setter syntax.
|
| - if (peek() == Token::IDENTIFIER) {
|
| - Handle<String> name = ParseIdentifier(CHECK_OK);
|
| + 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);
|
| + ParseFunctionLiteral(name,
|
| + RelocInfo::kNoPosition,
|
| + DECLARATION,
|
| + CHECK_OK);
|
| ObjectLiteral::Property* property =
|
| NEW(ObjectLiteral::Property(is_getter, value));
|
| - if (IsBoilerplateProperty(property))
|
| + if (IsBoilerplateProperty(property)) {
|
| number_of_boilerplate_properties++;
|
| + }
|
| properties.Add(property);
|
| if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
|
| continue; // restart the while
|
| @@ -3625,14 +3638,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
|
| key = NEW(Literal(id));
|
| 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: {
|
| - Consume(Token::STRING);
|
| + Consume(next);
|
| Handle<String> string =
|
| factory()->LookupSymbol(scanner_.literal_string(),
|
| scanner_.literal_length());
|
| uint32_t index;
|
| - if (!string.is_null() && string->AsArrayIndex(&index)) {
|
| + if (next == Token::STRING &&
|
| + !string.is_null() &&
|
| + string->AsArrayIndex(&index)) {
|
| key = NewNumberLiteral(index);
|
| } else {
|
| key = NEW(Literal(string));
|
| @@ -4008,6 +4027,19 @@ Handle<String> Parser::ParseIdentifier(bool* ok) {
|
| scanner_.literal_length());
|
| }
|
|
|
| +
|
| +Handle<String> Parser::ParseIdentifierName(bool* ok) {
|
| + Token::Value next = Next();
|
| + if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
|
| + ReportUnexpectedToken(next);
|
| + *ok = false;
|
| + return Handle<String>();
|
| + }
|
| + return factory()->LookupSymbol(scanner_.literal_string(),
|
| + scanner_.literal_length());
|
| +}
|
| +
|
| +
|
| // This function reads an identifier and determines whether or not it
|
| // is 'get' or 'set'. The reason for not using ParseIdentifier and
|
| // checking on the output is that this involves heap allocation which
|
|
|