git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@147 ce2b1a6d-e550...
authorfeng@chromium.org <feng@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 4 Sep 2008 20:49:18 +0000 (20:49 +0000)
committerfeng@chromium.org <feng@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 4 Sep 2008 20:49:18 +0000 (20:49 +0000)
src/parser.cc
test/mjsunit/for-in.js

index d9a65f3..7ddcdf6 100644 (file)
@@ -2652,7 +2652,7 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
 
   ZoneListWrapper<ObjectLiteral::Property> properties =
       factory()->NewList<ObjectLiteral::Property>(4);
-  int number_of_constant_properties = 0;
+  int number_of_boilerplate_properties = 0;
 
   Expect(Token::LBRACE, CHECK_OK);
   while (peek() != Token::RBRACE) {
@@ -2715,9 +2715,12 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
 
     ObjectLiteral::Property* property =
         NEW(ObjectLiteral::Property(key, value));
+    // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
     if ((property != NULL) &&
-        property->kind() == ObjectLiteral::Property::CONSTANT) {
-      number_of_constant_properties++;
+        (property->kind() == ObjectLiteral::Property::CONSTANT ||
+         property->kind() == ObjectLiteral::Property::COMPUTED) ) {
+      number_of_boilerplate_properties++;
     }
     properties.Add(property);
 
@@ -2730,17 +2733,26 @@ Expression* Parser::ParseObjectLiteral(bool* ok) {
   if (is_pre_parsing_) return NULL;
 
   Handle<FixedArray> constant_properties =
-      Factory::NewFixedArray(number_of_constant_properties * 2, TENURED);
+      Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
   int position = 0;
   for (int i = 0; i < properties.length(); i++) {
     ObjectLiteral::Property* property = properties.at(i);
-    if (property->kind() == ObjectLiteral::Property::CONSTANT) {
-      Handle<Object> key = property->key()->handle();
-      Literal* literal = property->value()->AsLiteral();
-      // Add name, value pair to the fixed array.
-      constant_properties->set(position++, *key);
-      constant_properties->set(position++, *literal->handle());
-    }
+    Handle<Object> key = property->key()->handle();
+    Literal* literal = NULL;
+
+    // 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;
+
+    // Add name, value pair to the fixed array.
+    constant_properties->set(position++, *key);
+    constant_properties->set(position++, *literal->handle());
   }
 
   // Construct the expression for calling Runtime::CreateObjectLiteral
index b8faeef..4af570a 100644 (file)
@@ -67,3 +67,11 @@ assertEquals(3, props(a).length);
 
 for (var hest = 'hest' in {}) { }
 assertEquals('hest', hest);
+
+var result = '';
+for (var p in {a : [0], b : 1}) { result += p; }
+assertEquals('ab', result);
+
+var result = '';
+for (var p in {a : {v:1}, b : 1}) { result += p; }
+assertEquals('ab', result);