Backed out changeset ff97ac763705 (bug 1097694)
authorWes Kocher <wkocher@mozilla.com>
Mon, 24 Nov 2014 17:04:50 -0800
changeset 217304 2ca8635fe240b9f62672153a9d030432473e4955
parent 217303 3670435aed44ffc5ec5c9004e000e5d5c36bc1bb
child 217305 852b845d1056f17991a6c417d6e674c8d8b8078c
push idunknown
push userunknown
push dateunknown
bugs1097694
milestone36.0a1
backs outff97ac763705dd01700fc605500047a1bd374297
Backed out changeset ff97ac763705 (bug 1097694)
js/src/builtin/Object.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/proxy/DirectProxyHandler.cpp
js/src/proxy/ScriptedDirectProxyHandler.cpp
js/src/vm/Debugger.cpp
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -59,18 +59,17 @@ obj_propertyIsEnumerable(JSContext *cx, 
     /* Steps 1-2. */
     jsid id;
     if (args.thisv().isObject() && ValueToId<NoGC>(cx, idValue, &id)) {
         JSObject *obj = &args.thisv().toObject(), *pobj;
 
         /* Step 3. */
         Shape *shape;
         if (!obj->is<ProxyObject>() &&
-            NonProxyLookupOwnProperty<NoGC>(cx, obj->getOps()->lookupGeneric, obj, id,
-                                            &pobj, &shape))
+            HasOwnProperty<NoGC>(cx, obj->getOps()->lookupGeneric, obj, id, &pobj, &shape))
         {
             /* Step 4. */
             if (!shape) {
                 args.rval().setBoolean(false);
                 return true;
             }
 
             /* Step 5. */
@@ -719,34 +718,42 @@ js::obj_hasOwnProperty(JSContext *cx, un
     HandleValue idValue = args.get(0);
 
     /* Step 1, 2. */
     jsid id;
     if (args.thisv().isObject() && ValueToId<NoGC>(cx, idValue, &id)) {
         JSObject *obj = &args.thisv().toObject(), *obj2;
         Shape *prop;
         if (!obj->is<ProxyObject>() &&
-            NonProxyLookupOwnProperty<NoGC>(cx, obj->getOps()->lookupGeneric, obj, id,
-                                            &obj2, &prop))
+            HasOwnProperty<NoGC>(cx, obj->getOps()->lookupGeneric, obj, id, &obj2, &prop))
         {
             args.rval().setBoolean(!!prop);
             return true;
         }
     }
 
     /* Step 1. */
     RootedId idRoot(cx);
     if (!ValueToId<CanGC>(cx, idValue, &idRoot))
         return false;
 
     /* Step 2. */
     RootedObject obj(cx, ToObject(cx, args.thisv()));
     if (!obj)
         return false;
 
+    /* Non-standard code for proxies. */
+    if (obj->is<ProxyObject>()) {
+        bool has;
+        if (!Proxy::hasOwn(cx, obj, idRoot, &has))
+            return false;
+        args.rval().setBoolean(has);
+        return true;
+    }
+
     /* Step 3. */
     bool found;
     if (!HasOwnProperty(cx, obj, idRoot, &found))
         return false;
 
     /* Step 4,5. */
     args.rval().setBoolean(found);
     return true;
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -366,18 +366,17 @@ bool
 js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
                              MutableHandle<PropertyDescriptor> desc)
 {
     if (obj->is<ProxyObject>())
         return Proxy::getOwnPropertyDescriptor(cx, obj, id, desc);
 
     RootedObject pobj(cx);
     RootedShape shape(cx);
-    LookupGenericOp lookupOp = obj->getOps()->lookupGeneric;
-    if (!NonProxyLookupOwnProperty<CanGC>(cx, lookupOp, obj, id, &pobj, &shape))
+    if (!HasOwnProperty<CanGC>(cx, obj->getOps()->lookupGeneric, obj, id, &pobj, &shape))
         return false;
     if (!shape) {
         desc.object().set(nullptr);
         return true;
     }
 
     bool doGet = true;
     if (pobj->isNative()) {
@@ -719,17 +718,17 @@ js::CheckDefineProperty(JSContext *cx, H
 static bool
 DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const PropDesc &desc,
                        bool throwError, bool *rval)
 {
     /* 8.12.9 step 1. */
     RootedShape shape(cx);
     RootedObject obj2(cx);
     MOZ_ASSERT(!obj->getOps()->lookupGeneric);
-    if (!NonProxyLookupOwnProperty<CanGC>(cx, nullptr, obj, id, &obj2, &shape))
+    if (!HasOwnProperty<CanGC>(cx, nullptr, obj, id, &obj2, &shape))
         return false;
 
     MOZ_ASSERT(!obj->getOps()->defineProperty);
 
     /* 8.12.9 steps 2-4. */
     if (!shape) {
         bool extensible;
         if (!JSObject::isExtensible(cx, obj, &extensible))
@@ -3161,24 +3160,22 @@ js::LookupNameUnqualified(JSContext *cx,
     }
 
     objp.set(scope);
     return true;
 }
 
 template <AllowGC allowGC>
 bool
-js::NonProxyLookupOwnProperty(JSContext *cx, LookupGenericOp lookup,
-                              typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
-                              typename MaybeRooted<jsid, allowGC>::HandleType id,
-                              typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
-                              typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
+js::HasOwnProperty(JSContext *cx, LookupGenericOp lookup,
+                   typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
+                   typename MaybeRooted<jsid, allowGC>::HandleType id,
+                   typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
+                   typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
 {
-    MOZ_ASSERT(!obj->template is<ProxyObject>());
-
     if (lookup) {
         if (!allowGC)
             return false;
         if (!lookup(cx,
                     MaybeRooted<JSObject*, allowGC>::toHandle(obj),
                     MaybeRooted<jsid, allowGC>::toHandle(id),
                     MaybeRooted<JSObject*, allowGC>::toMutableHandle(objp),
                     MaybeRooted<Shape*, allowGC>::toMutableHandle(propp)))
@@ -3216,36 +3213,31 @@ js::NonProxyLookupOwnProperty(JSContext 
     }
 
     if (outer != objp)
         propp.set(nullptr);
     return true;
 }
 
 template bool
-js::NonProxyLookupOwnProperty<CanGC>(JSContext *cx, LookupGenericOp lookup,
-                                     HandleObject obj, HandleId id,
-                                     MutableHandleObject objp, MutableHandleShape propp);
+js::HasOwnProperty<CanGC>(JSContext *cx, LookupGenericOp lookup,
+                          HandleObject obj, HandleId id,
+                          MutableHandleObject objp, MutableHandleShape propp);
 
 template bool
-js::NonProxyLookupOwnProperty<NoGC>(JSContext *cx, LookupGenericOp lookup,
-                                    JSObject *obj, jsid id,
-                                    FakeMutableHandle<JSObject*> objp,
-                                    FakeMutableHandle<Shape*> propp);
+js::HasOwnProperty<NoGC>(JSContext *cx, LookupGenericOp lookup,
+                         JSObject *obj, jsid id,
+                         FakeMutableHandle<JSObject*> objp, FakeMutableHandle<Shape*> propp);
 
 bool
 js::HasOwnProperty(JSContext *cx, HandleObject obj, HandleId id, bool *resultp)
 {
-    if (obj->is<ProxyObject>())
-        return Proxy::hasOwn(cx, obj, id, resultp);
-
     RootedObject pobj(cx);
     RootedShape shape(cx);
-    LookupGenericOp lookupOp = obj->getOps()->lookupGeneric;
-    if (!NonProxyLookupOwnProperty<CanGC>(cx, lookupOp, obj, id, &pobj, &shape))
+    if (!HasOwnProperty<CanGC>(cx, obj->getOps()->lookupGeneric, obj, id, &pobj, &shape))
         return false;
     *resultp = (shape != nullptr);
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
 LookupPropertyPureInline(ThreadSafeContext *cx, JSObject *obj, jsid id, NativeObject **objp,
                          Shape **propp)
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -919,21 +919,21 @@ class ValueArray {
 namespace js {
 
 /* Set *resultp to tell whether obj has an own property with the given id. */
 bool
 HasOwnProperty(JSContext *cx, HandleObject obj, HandleId id, bool *resultp);
 
 template <AllowGC allowGC>
 extern bool
-NonProxyLookupOwnProperty(JSContext *cx, LookupGenericOp lookup,
-                          typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
-                          typename MaybeRooted<jsid, allowGC>::HandleType id,
-                          typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
-                          typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp);
+HasOwnProperty(JSContext *cx, LookupGenericOp lookup,
+               typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
+               typename MaybeRooted<jsid, allowGC>::HandleType id,
+               typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
+               typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp);
 
 typedef JSObject *(*ClassInitializerOp)(JSContext *cx, JS::HandleObject obj);
 
 /* Fast access to builtin constructors and prototypes. */
 bool
 GetBuiltinConstructor(ExclusiveContext *cx, JSProtoKey key, MutableHandleObject objp);
 
 bool
--- a/js/src/proxy/DirectProxyHandler.cpp
+++ b/js/src/proxy/DirectProxyHandler.cpp
@@ -203,17 +203,21 @@ DirectProxyHandler::has(JSContext *cx, H
     return true;
 }
 
 bool
 DirectProxyHandler::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const
 {
     assertEnteredPolicy(cx, proxy, id, GET);
     RootedObject target(cx, proxy->as<ProxyObject>().target());
-    return js::HasOwnProperty(cx, target, id, bp);
+    Rooted<PropertyDescriptor> desc(cx);
+    if (!JS_GetPropertyDescriptorById(cx, target, id, &desc))
+        return false;
+    *bp = (desc.object() == target);
+    return true;
 }
 
 bool
 DirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
                         HandleId id, MutableHandleValue vp) const
 {
     assertEnteredPolicy(cx, proxy, id, GET);
     RootedObject target(cx, proxy->as<ProxyObject>().target());
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp
+++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp
@@ -138,16 +138,26 @@ IsSealed(JSContext* cx, HandleObject obj
     if (!GetOwnPropertyDescriptor(cx, obj, id, &desc))
         return false;
 
     // steps 2-3
     *bp = desc.object() && desc.isPermanent();
     return true;
 }
 
+static bool
+HasOwn(JSContext *cx, HandleObject obj, HandleId id, bool *bp)
+{
+    Rooted<PropertyDescriptor> desc(cx);
+    if (!JS_GetPropertyDescriptorById(cx, obj, id, &desc))
+        return false;
+    *bp = (desc.object() == obj);
+    return true;
+}
+
 // Get the [[ProxyHandler]] of a scripted direct proxy.
 static JSObject *
 GetDirectProxyHandlerObject(JSObject *proxy)
 {
     MOZ_ASSERT(proxy->as<ProxyObject>().handler() == &ScriptedDirectProxyHandler::singleton);
     return proxy->as<ProxyObject>().extra(ScriptedDirectProxyHandler::HANDLER_EXTRA).toObjectOrNull();
 }
 
@@ -194,17 +204,17 @@ ArrayToIdVector(JSContext *cx, HandleObj
             if (props[j].get() == id) {
                 ReportInvalidTrapResult(cx, proxy, trapName);
                 return false;
             }
         }
 
         // step iv
         bool isFixed;
-        if (!HasOwnProperty(cx, target, id, &isFixed))
+        if (!HasOwn(cx, target, id, &isFixed))
             return false;
 
         // step v
         bool extensible;
         if (!JSObject::isExtensible(cx, target, &extensible))
             return false;
         if (!extensible && !isFixed) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_NEW);
@@ -241,17 +251,17 @@ ArrayToIdVector(JSContext *cx, HandleObj
             return false;
         if (sealed) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_SKIP_NC);
             return false;
         }
 
         // step ii
         bool isFixed;
-        if (!HasOwnProperty(cx, target, id, &isFixed))
+        if (!HasOwn(cx, target, id, &isFixed))
             return false;
 
         // step iii
         bool extensible;
         if (!JSObject::isExtensible(cx, target, &extensible))
             return false;
         if (!extensible && isFixed) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_REPORT_E_AS_NE);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4339,17 +4339,17 @@ DebuggerScript_getAllOffsets(JSContext *
         if (!flowData[offset].hasNoEdges() && flowData[offset].lineno() != lineno) {
             /* Get the offsets array for this line. */
             RootedObject offsets(cx);
             RootedValue offsetsv(cx);
 
             RootedId id(cx, INT_TO_JSID(lineno));
 
             bool found;
-            if (!HasOwnProperty(cx, result, id, &found))
+            if (!js::HasOwnProperty(cx, result, id, &found))
                 return false;
             if (found && !JSObject::getGeneric(cx, result, result, id, &offsetsv))
                 return false;
 
             if (offsetsv.isObject()) {
                 offsets = &offsetsv.toObject();
             } else {
                 MOZ_ASSERT(offsetsv.isUndefined());