From ecbfddf0521cc37f4fa315483938595a786dd04e Mon Sep 17 00:00:00 2001 From: "feng@chromium.org" Date: Fri, 5 Sep 2008 16:47:42 +0000 Subject: [PATCH] Honor the declaration order of getter/setter in object literals git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@174 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/parser.cc | 38 ++++++++++++++++++++++++++------------ test/mjsunit/for-in.js | 9 +++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/parser.cc b/src/parser.cc index 948d21cad..0b6beffb4 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -151,6 +151,13 @@ class Parser { Expression* ParseObjectLiteral(bool* ok); Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); + // Decide if a property should be the object boilerplate. + bool IsBoilerplateProperty(ObjectLiteral::Property* property); + // If the property is CONSTANT type, it returns the literal value, + // otherwise, it return undefined literal as the placeholder + // in the object literal boilerplate. + Literal* GetBoilerplateValue(ObjectLiteral::Property* property); + enum FunctionLiteralType { EXPRESSION, DECLARATION, @@ -2643,6 +2650,19 @@ Expression* Parser::ParseArrayLiteral(bool* ok) { } +bool Parser::IsBoilerplateProperty(ObjectLiteral::Property* property) { + return property != NULL && + property->kind() != ObjectLiteral::Property::PROTOTYPE; +} + + +Literal* Parser::GetBoilerplateValue(ObjectLiteral::Property* property) { + if (property->kind() == ObjectLiteral::Property::CONSTANT) + return property->value()->AsLiteral(); + return GetLiteralUndefined(); +} + + Expression* Parser::ParseObjectLiteral(bool* ok) { // ObjectLiteral :: // '{' ( @@ -2674,6 +2694,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { ParseFunctionLiteral(name, kNoPosition, DECLARATION, CHECK_OK); ObjectLiteral::Property* property = NEW(ObjectLiteral::Property(is_getter, value)); + if (IsBoilerplateProperty(property)) + number_of_boilerplate_properties++; properties.Add(property); if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); continue; // restart the while @@ -2717,11 +2739,8 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { NEW(ObjectLiteral::Property(key, value)); // Count CONSTANT or COMPUTED properties to maintain the enumeration order. - if ((property != NULL) && - (property->kind() == ObjectLiteral::Property::CONSTANT || - property->kind() == ObjectLiteral::Property::COMPUTED) ) { + if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; - } properties.Add(property); // TODO(1240767): Consider allowing trailing comma. @@ -2737,18 +2756,13 @@ Expression* Parser::ParseObjectLiteral(bool* ok) { int position = 0; for (int i = 0; i < properties.length(); i++) { ObjectLiteral::Property* property = properties.at(i); - Handle key = property->key()->handle(); - Literal* literal = NULL; + if (!IsBoilerplateProperty(property)) continue; // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined // value for COMPUTED properties, the real value is filled in at // runtime. The enumeration order is maintained. - if (property->kind() == ObjectLiteral::Property::CONSTANT) - literal = property->value()->AsLiteral(); - else if (property->kind() == ObjectLiteral::Property::COMPUTED) - literal = GetLiteralUndefined(); - else - continue; + Handle key = property->key()->handle(); + Literal* literal = GetBoilerplateValue(property); // Add name, value pair to the fixed array. constant_properties->set(position++, *key); diff --git a/test/mjsunit/for-in.js b/test/mjsunit/for-in.js index 4af570a77..5d670adc7 100644 --- a/test/mjsunit/for-in.js +++ b/test/mjsunit/for-in.js @@ -75,3 +75,12 @@ assertEquals('ab', result); var result = ''; for (var p in {a : {v:1}, b : 1}) { result += p; } assertEquals('ab', result); + +var result = ''; +for (var p in { get a() {}, b : 1}) { result += p; } +assertEquals('ab', result); + +var result = ''; +for (var p in { get a() {}, set a(x) {}, b : 1}) { result += p; } +assertEquals('ab', result); + -- 2.34.1