Backed out changeset c69e27e86565 (bug 1083211)
authorWes Kocher <wkocher@mozilla.com>
Mon, 24 Nov 2014 17:04:42 -0800
changeset 217303 3670435aed44ffc5ec5c9004e000e5d5c36bc1bb
parent 217302 63f71ff39bbc6f87008f7222db71d21d5d9d6d95
child 217304 2ca8635fe240b9f62672153a9d030432473e4955
push idunknown
push userunknown
push dateunknown
bugs1083211
milestone36.0a1
backs outc69e27e865656ccd9180a82e5ca761e32140860c
Backed out changeset c69e27e86565 (bug 1083211)
js/src/jsapi.h
js/src/proxy/BaseProxyHandler.cpp
js/src/proxy/ScriptedIndirectProxyHandler.cpp
js/src/proxy/ScriptedIndirectProxyHandler.h
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3026,23 +3026,16 @@ class PropertyDescriptorOperations
     bool hasGetterObject() const { return desc()->attrs & JSPROP_GETTER; }
     bool hasSetterObject() const { return desc()->attrs & JSPROP_SETTER; }
     bool hasGetterOrSetterObject() const { return desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER); }
     bool hasGetterOrSetter() const { return desc()->getter || desc()->setter; }
     bool isShared() const { return desc()->attrs & JSPROP_SHARED; }
     bool isIndex() const { return desc()->attrs & JSPROP_INDEX; }
     bool hasAttributes(unsigned attrs) const { return desc()->attrs & attrs; }
 
-    // Descriptors with JSPropertyOps are considered data descriptors. It's
-    // complicated.
-    bool isAccessorDescriptor() const { return hasGetterOrSetterObject(); }
-    bool isDataDescriptor() const { return !isAccessorDescriptor(); }
-
-    bool isWritable() const { MOZ_ASSERT(isDataDescriptor()); return !isReadonly(); }
-
     JS::HandleObject object() const {
         return JS::HandleObject::fromMarkedLocation(&desc()->obj);
     }
     unsigned attributes() const { return desc()->attrs; }
     JSPropertyOp getter() const { return desc()->getter; }
     JSStrictPropertyOp setter() const { return desc()->setter; }
     JS::HandleObject getterObject() const {
         MOZ_ASSERT(hasGetterObject());
--- a/js/src/proxy/BaseProxyHandler.cpp
+++ b/js/src/proxy/BaseProxyHandler.cpp
@@ -73,81 +73,30 @@ BaseProxyHandler::get(JSContext *cx, Han
 }
 
 bool
 BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
                       HandleId id, bool strict, MutableHandleValue vp) const
 {
     assertEnteredPolicy(cx, proxy, id, SET);
 
-    // This method is not covered by any spec, but we follow ES6 draft rev 28
-    // (2014 Oct 14) 9.1.9 fairly closely, adapting it slightly for
-    // SpiderMonkey's particular foibles.
-
-    // Steps 2-3.  (Step 1 is a superfluous assertion.)
-    Rooted<PropertyDescriptor> ownDesc(cx);
-    if (!getOwnPropertyDescriptor(cx, proxy, id, &ownDesc))
+    // Find an own or inherited property. The code here is strange for maximum
+    // backward compatibility with earlier code written before ES6 and before
+    // SetPropertyIgnoringNamedGetter.
+    Rooted<PropertyDescriptor> desc(cx);
+    if (!getOwnPropertyDescriptor(cx, proxy, id, &desc))
         return false;
-
-    // Step 4.
-    if (!ownDesc.object()) {
-        // The spec calls this variable "parent", but that word has weird
-        // connotations in SpiderMonkey, so let's go with "proto".
-        RootedObject proto(cx);
-        if (!JSObject::getProto(cx, proxy, &proto))
+    bool descIsOwn = desc.object() != nullptr;
+    if (!descIsOwn) {
+        if (!getPropertyDescriptor(cx, proxy, id, &desc))
             return false;
-        if (proto)
-            return JSObject::setGeneric(cx, proto, receiver, id, vp, strict);
-
-        // Change ownDesc to be a complete descriptor for a configurable,
-        // writable, enumerable data property. Then fall through to step 5.
-        ownDesc.clear();
-        ownDesc.setAttributes(JSPROP_ENUMERATE);
     }
 
-    // Step 5.
-    if (ownDesc.isDataDescriptor()) {
-        // Steps 5.a-b, adapted to our nonstandard implementation of ES6
-        // [[Set]] return values.
-        if (!ownDesc.isWritable()) {
-            if (strict)
-                return JSObject::reportReadOnly(cx, id, JSREPORT_ERROR);
-            if (cx->compartment()->options().extraWarnings(cx))
-                return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
-            return true;
-        }
-
-        // Nonstandard SpiderMonkey special case: setter ops.
-        StrictPropertyOp setter = ownDesc.setter();
-        if (setter && setter != JS_StrictPropertyStub)
-            return CallSetter(cx, receiver, id, setter, ownDesc.attributes(), strict, vp);
-
-        // Steps 5.c-d. Adapt for SpiderMonkey by using HasOwnProperty instead
-        // of the standard [[GetOwnProperty]].
-        bool existingDescriptor;
-        if (!HasOwnProperty(cx, receiver, id, &existingDescriptor))
-            return false;
-
-        // Steps 5.e-f.
-        unsigned attrs =
-            existingDescriptor
-            ? JSPROP_IGNORE_ENUMERATE | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_PERMANENT
-            : JSPROP_ENUMERATE;
-        return JSObject::defineGeneric(cx, receiver, id, vp, nullptr, nullptr, attrs);
-    }
-
-    // Step 6.
-    MOZ_ASSERT(ownDesc.isAccessorDescriptor());
-    RootedObject setter(cx);
-    if (ownDesc.hasSetterObject())
-        setter = ownDesc.setterObject();
-    if (!setter)
-        return js_ReportGetterOnlyAssignment(cx, strict);
-    RootedValue setterValue(cx, ObjectValue(*setter));
-    return InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp);
+    return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, strict,
+                                          vp);
 }
 
 bool
 js::SetPropertyIgnoringNamedGetter(JSContext *cx, const BaseProxyHandler *handler,
                                    HandleObject proxy, HandleObject receiver,
                                    HandleId id, MutableHandle<PropertyDescriptor> desc,
                                    bool descIsOwn, bool strict, MutableHandleValue vp)
 {
--- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp
@@ -282,41 +282,21 @@ ScriptedIndirectProxyHandler::set(JSCont
     JS::AutoValueArray<3> argv(cx);
     argv[0].setObjectOrNull(receiver);
     argv[1].set(idv);
     argv[2].set(vp);
     RootedValue fval(cx);
     if (!GetDerivedTrap(cx, handler, cx->names().set, &fval))
         return false;
     if (!IsCallable(fval))
-        return derivedSet(cx, proxy, receiver, id, strict, vp);
+        return BaseProxyHandler::set(cx, proxy, receiver, id, strict, vp);
     return Trap(cx, handler, fval, 3, argv.begin(), &idv);
 }
 
 bool
-ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver,
-                                         HandleId id, bool strict, MutableHandleValue vp) const
-{
-    // Find an own or inherited property. The code here is strange for maximum
-    // backward compatibility with earlier code written before ES6 and before
-    // SetPropertyIgnoringNamedGetter.
-    Rooted<PropertyDescriptor> desc(cx);
-    if (!getOwnPropertyDescriptor(cx, proxy, id, &desc))
-        return false;
-    bool descIsOwn = desc.object() != nullptr;
-    if (!descIsOwn) {
-        if (!getPropertyDescriptor(cx, proxy, id, &desc))
-            return false;
-    }
-
-    return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, strict,
-                                          vp);
-}
-
-bool
 ScriptedIndirectProxyHandler::getOwnEnumerablePropertyKeys(JSContext *cx, HandleObject proxy,
                                                            AutoIdVector &props) const
 {
     RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
     RootedValue value(cx);
     if (!GetDerivedTrap(cx, handler, cx->names().keys, &value))
         return false;
     if (!IsCallable(value))
--- a/js/src/proxy/ScriptedIndirectProxyHandler.h
+++ b/js/src/proxy/ScriptedIndirectProxyHandler.h
@@ -47,20 +47,16 @@ class ScriptedIndirectProxyHandler : pub
                          MutableHandleObject objp) const MOZ_OVERRIDE;
     virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
                             CallArgs args) const MOZ_OVERRIDE;
     virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) const MOZ_OVERRIDE;
     virtual bool isScripted() const MOZ_OVERRIDE { return true; }
 
     static const char family;
     static const ScriptedIndirectProxyHandler singleton;
-
-private:
-    bool derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
-                    bool strict, MutableHandleValue vp) const;
 };
 
 /* Derived class to handle Proxy.createFunction() */
 class CallableScriptedIndirectProxyHandler : public ScriptedIndirectProxyHandler
 {
   public:
     CallableScriptedIndirectProxyHandler() : ScriptedIndirectProxyHandler() { }
     virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const MOZ_OVERRIDE;