Bug 489623 - JSOP_SETPROP does not run resolve hook when adding properties
authorKannan Vijayan <kvijayan@mozilla.com>
Fri, 27 Apr 2012 14:51:48 -0400
changeset 93102 fcbb7e877c1221d80fb8e106329d263b1b496112
parent 93101 c45668383f517ec4df164b2d3883cf7d026d8ddc
child 93103 5a6e9f648a26a1c66453d45471a2e559a75599f8
push id837
push userkvijayan@mozilla.com
push dateFri, 27 Apr 2012 18:52:04 +0000
bugs489623
milestone14.0a1
Bug 489623 - JSOP_SETPROP does not run resolve hook when adding properties
js/src/ion/IonCaches.cpp
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -451,27 +451,41 @@ IonCacheSetProperty::attachNativeAdding(
 static bool
 IsEligibleForInlinePropertyAdd(JSContext *cx, JSObject *obj, jsid propId, uint32_t oldSlots,
                                const Shape **propShapeOut)
 {
     const Shape *propShape = obj->nativeLookup(cx, propId);
     if (!propShape || propShape->inDictionary() || !propShape->hasSlot() || !propShape->hasDefaultSetter())
         return false;
 
+    // If object has a non-default resolve hook, don't inline
+    if (obj->getClass()->resolve != JS_ResolveStub)
+        return false;
+
     // walk up the object prototype chain and ensure that all prototypes
     // are native, and that all prototypes have no getter or setter
     // defined on the property
     for (JSObject *proto = obj->getProto(); proto; proto = proto->getProto()) {
         // if prototype is non-native, don't optimize
         if (!proto->isNative()) 
             return false;
 
         // if prototype defines this property in a non-plain way, don't optimize
         const Shape *protoShape = proto->nativeLookup(cx, propId);
-        if (protoShape && !protoShape->hasDefaultSetter())
+        if (protoShape) {
+            // If the prototype has a property with this name, we may be able to
+            // inline-add if the property has a default setter.  If there's no
+            // default setter, then setting would potentially cause special
+            // behaviour, so we choose not to optimize.
+            return protoShape->hasDefaultSetter();
+        }
+
+        // Otherise, if there's no such property, watch out for a resolve hook that would need
+        // to be invoked and thus prevent inlining of property addition.
+        if (proto->getClass()->resolve != JS_ResolveStub)
             return false;
     }
 
     // Only add a IC entry if the dynamic slots didn't change when the shapes
     // changed.  Need to ensure that a shape change for a subsequent object
     // won't involve reallocating the slot array.
     if (obj->numDynamicSlots() != oldSlots)
         return false;