From 53690b68fad9b8a0aeef0ec5d86e65ee10bcbb1e Mon Sep 17 00:00:00 2001 From: "lrn@chromium.org" Date: Mon, 9 Aug 2010 08:54:29 +0000 Subject: [PATCH] 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 --- src/parser.cc | 93 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index bf1a348..e935b7b 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -210,6 +210,7 @@ class Parser { Expression* ParsePrimaryExpression(bool* ok); Expression* ParseArrayLiteral(bool* ok); Expression* ParseObjectLiteral(bool* ok); + ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok); Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); // Populate the constant properties fixed array for a materialized object @@ -3376,11 +3377,7 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) { // default case. default: { - Token::Value tok = peek(); - // 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(); + Token::Value tok = Next(); ReportUnexpectedToken(tok); *ok = false; return NULL; @@ -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 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) { // ObjectLiteral :: // '{' ( @@ -3601,64 +3627,39 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { 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 - // literal. bool is_getter = false; bool is_setter = false; Handle id = ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); - if (is_getter || is_setter) { - // Special handling of getter and setter syntax. - Handle name; - next = peek(); - if (next == Token::IDENTIFIER || - next == Token::STRING || - next == Token::NUMBER || - Token::IsKeyword(next)) { - Consume(next); - Handle name = - factory()->LookupSymbol(scanner_.literal_string(), - scanner_.literal_length()); - FunctionLiteral* value = - ParseFunctionLiteral(name, - RelocInfo::kNoPosition, - DECLARATION, - CHECK_OK); + if ((is_getter || is_setter) && peek() != Token::COLON) { ObjectLiteral::Property* property = - NEW(ObjectLiteral::Property(is_getter, value)); + ParseObjectLiteralGetSet(is_getter, CHECK_OK); if (IsBoilerplateProperty(property)) { number_of_boilerplate_properties++; } properties.Add(property); if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 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)); 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(next); + Consume(Token::STRING); Handle string = factory()->LookupSymbol(scanner_.literal_string(), scanner_.literal_length()); uint32_t index; - if (next == Token::STRING && - !string.is_null() && + if (!string.is_null() && string->AsArrayIndex(&index)) { key = NewNumberLiteral(index); - } else { - key = NEW(Literal(string)); + break; } + key = NEW(Literal(string)); break; } - case Token::NUMBER: { Consume(Token::NUMBER); double value = @@ -3666,10 +3667,20 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { key = NewNumberLiteral(value); break; } - default: - Expect(Token::RBRACE, CHECK_OK); - break; + if (Token::IsKeyword(next)) { + Consume(next); + Handle 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); -- 2.7.4