Bug 1146979. When cloning objects in self-hosting preserve the property attributes of the properties (or at least the readonly/configurable attributes). r=till
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 24 Mar 2015 18:32:48 -0400
changeset 265768 6796d08c38c18d8afb4c7d2868233276998825c2
parent 265767 5c96d3fc176b42ceb96d651980fa586e55f8a7c9
child 265769 f0b9e9a81916ac1704f80168bc0c3d37e6364aa9
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstill
bugs1146979
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1146979. When cloning objects in self-hosting preserve the property attributes of the properties (or at least the readonly/configurable attributes). r=till
js/src/vm/SelfHosting.cpp
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1266,39 +1266,56 @@ GetUnclonedValue(JSContext *cx, HandleNa
     vp.set(selfHostedObject->getSlot(shape->slot()));
     return true;
 }
 
 static bool
 CloneProperties(JSContext *cx, HandleNativeObject selfHostedObject, HandleObject clone)
 {
     AutoIdVector ids(cx);
+    Vector<uint8_t, 16> attrs(cx);
 
     for (size_t i = 0; i < selfHostedObject->getDenseInitializedLength(); i++) {
         if (!selfHostedObject->getDenseElement(i).isMagic(JS_ELEMENTS_HOLE)) {
             if (!ids.append(INT_TO_JSID(i)))
                 return false;
+            if (!attrs.append(JSPROP_ENUMERATE))
+                return false;
         }
     }
 
+    AutoShapeVector shapes(cx);
     for (Shape::Range<NoGC> range(selfHostedObject->lastProperty()); !range.empty(); range.popFront()) {
         Shape &shape = range.front();
-        if (shape.enumerable() && !ids.append(shape.propid()))
+        if (shape.enumerable() && !shapes.append(&shape))
+            return false;
+    }
+
+    // Now our shapes are in last-to-first order, so....
+    Reverse(shapes.begin(), shapes.end());
+    for (size_t i = 0; i < shapes.length(); ++i) {
+        MOZ_ASSERT(!shapes[i]->isAccessorShape(),
+                   "Can't handle cloning accessors here yet.");
+        if (!ids.append(shapes[i]->propid()))
+            return false;
+        uint8_t shapeAttrs =
+            shapes[i]->attributes() & (JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY);
+        if (!attrs.append(shapeAttrs))
             return false;
     }
 
     RootedId id(cx);
     RootedValue val(cx);
     RootedValue selfHostedValue(cx);
     for (uint32_t i = 0; i < ids.length(); i++) {
         id = ids[i];
         if (!GetUnclonedValue(cx, selfHostedObject, id, &selfHostedValue))
             return false;
         if (!CloneValue(cx, selfHostedValue, &val) ||
-            !JS_DefinePropertyById(cx, clone, id, val, 0))
+            !JS_DefinePropertyById(cx, clone, id, val, attrs[i]))
         {
             return false;
         }
     }
 
     return true;
 }