Bug 828462 - Root Proxy/Wrapper defineProperty. r=terrence
authorTom Schuster <evilpies@gmail.com>
Thu, 21 Mar 2013 23:23:47 +0100
changeset 137070 bf4dc429c4fa355e514fa5a1e656ea23b3a97e64
parent 137069 207ff8c91b7d171fc8f3d45e82a448f6a0578375
child 137071 53a76b390b8c3ac208ed7d11167c1f2ea660f0c7
push id336
push userakeybl@mozilla.com
push dateMon, 17 Jun 2013 22:53:19 +0000
treeherdermozilla-release@574a39cdf657 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs828462
milestone22.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 828462 - Root Proxy/Wrapper defineProperty. r=terrence
dom/base/nsGlobalWindow.cpp
dom/bindings/Codegen.py
dom/bindings/DOMJSProxyHandler.cpp
dom/bindings/DOMJSProxyHandler.h
js/src/jsobj.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/vm/ScopeObject.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -542,18 +542,20 @@ public:
                                      JS::Handle<jsid> id,
                                      JSPropertyDescriptor* desc,
                                      unsigned flags) MOZ_OVERRIDE;
   virtual bool getOwnPropertyDescriptor(JSContext* cx,
                                         JS::Handle<JSObject *> proxy,
                                         JS::Handle<jsid> id,
                                         JSPropertyDescriptor* desc,
                                         unsigned flags) MOZ_OVERRIDE;
-  virtual bool defineProperty(JSContext* cx, JSObject* proxy,
-                              jsid id, JSPropertyDescriptor* desc) MOZ_OVERRIDE;
+  virtual bool defineProperty(JSContext* cx,
+                              JS::Handle<JSObject *> proxy,
+                              JS::Handle<jsid> id,
+                              JSPropertyDescriptor* desc) MOZ_OVERRIDE;
   virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                    JS::AutoIdVector &props) MOZ_OVERRIDE;
   virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id,
                        bool *bp) MOZ_OVERRIDE;
   virtual bool enumerate(JSContext *cx, JSObject *proxy,
                          JS::AutoIdVector &props) MOZ_OVERRIDE;
 
   // Derived traps
@@ -650,18 +652,20 @@ nsOuterWindowProxy::getOwnPropertyDescri
     return true;
   }
   // else fall through to js::Wrapper
 
   return js::Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc, flags);
 }
 
 bool
-nsOuterWindowProxy::defineProperty(JSContext* cx, JSObject* proxy,
-                                   jsid id, JSPropertyDescriptor* desc)
+nsOuterWindowProxy::defineProperty(JSContext* cx,
+                                   JS::Handle<JSObject *> proxy,
+                                   JS::Handle<jsid> id,
+                                   JSPropertyDescriptor* desc)
 {
   int32_t index = GetArrayIndexFromId(cx, id);
   if (IsArrayIndex(index)) {
     // Spec says to Reject whether this is a supported index or not,
     // since we have no indexed setter or indexed creator.  That means
     // throwing in strict mode (FIXME: Bug 828137), doing nothing in
     // non-strict mode.
     return true;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6156,18 +6156,18 @@ if (!xpc::WrapperFactory::IsXrayWrapper(
   }
 }
 """ + namedGet + """
 desc->obj = NULL;
 return true;"""
 
 class CGDOMJSProxyHandler_defineProperty(ClassMethod):
     def __init__(self, descriptor):
-        args = [Argument('JSContext*', 'cx'), Argument('JSObject*', 'proxy'),
-                Argument('jsid', 'id'),
+        args = [Argument('JSContext*', 'cx'), Argument('JS::Handle<JSObject *>', 'proxy'),
+                Argument('JS::Handle<jsid>', 'id'),
                 Argument('JSPropertyDescriptor*', 'desc')]
         ClassMethod.__init__(self, "defineProperty", "bool", args)
         self.descriptor = descriptor
     def getBody(self):
         set = ""
 
         indexedSetter = self.descriptor.operations['IndexedSetter']
         if indexedSetter:
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -94,17 +94,17 @@ DOMProxyHandler::getPropertyDescriptor(J
     desc->obj = NULL;
     return true;
   }
 
   return JS_GetPropertyDescriptorById(cx, proto, id, 0, desc);
 }
 
 bool
-DOMProxyHandler::defineProperty(JSContext* cx, JSObject* proxy, jsid id,
+DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject *> proxy, JS::Handle<jsid> id,
                                 JSPropertyDescriptor* desc)
 {
   if ((desc->attrs & JSPROP_GETTER) && desc->setter == JS_StrictPropertyStub) {
     return JS_ReportErrorFlagsAndNumber(cx,
                                         JSREPORT_WARNING | JSREPORT_STRICT |
                                         JSREPORT_STRICT_MODE_ERROR,
                                         js_GetErrorMessage, NULL,
                                         JSMSG_GETTER_ONLY);
--- a/dom/bindings/DOMJSProxyHandler.h
+++ b/dom/bindings/DOMJSProxyHandler.h
@@ -33,17 +33,17 @@ public:
   DOMProxyHandler(const DOMClass& aClass)
     : js::BaseProxyHandler(ProxyFamily()),
       mClass(aClass)
   {
   }
 
   bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject *> proxy, JS::Handle<jsid> id, JSPropertyDescriptor* desc,
                              unsigned flags) MOZ_OVERRIDE;
-  bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
+  bool defineProperty(JSContext* cx, JS::Handle<JSObject *> proxy, JS::Handle<jsid> id,
                       JSPropertyDescriptor* desc) MOZ_OVERRIDE;
   bool delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp) MOZ_OVERRIDE;
   bool enumerate(JSContext* cx, JSObject* proxy, JS::AutoIdVector& props) MOZ_OVERRIDE;
   bool fix(JSContext* cx, JSObject* proxy, JS::Value* vp);
   bool has(JSContext* cx, JSObject* proxy, jsid id, bool* bp) MOZ_OVERRIDE;
   using js::BaseProxyHandler::obj_toString;
 
   static JSObject* GetExpandoObject(JSObject* obj)
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -961,18 +961,20 @@ js::DefineProperty(JSContext *cx, Handle
     if (obj->isArray())
         return DefinePropertyOnArray(cx, obj, id, desc, throwError, rval);
 
     if (obj->getOps()->lookupGeneric) {
         /*
          * FIXME: Once ScriptedIndirectProxies are removed, this code should call
          * TrapDefineOwnProperty directly
          */
-        if (obj->isProxy())
-            return Proxy::defineProperty(cx, obj, id, desc.pd());
+        if (obj->isProxy()) {
+            RootedValue pd(cx, desc.pd());
+            return Proxy::defineProperty(cx, obj, id, pd);
+        }
         return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
     }
 
     return DefinePropertyOnObject(cx, obj, id, desc, throwError, rval);
 }
 
 JSBool
 js_DefineOwnProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &descriptor,
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -475,25 +475,24 @@ DirectProxyHandler::getOwnPropertyDescri
                                              HandleId id, PropertyDescriptor *desc, unsigned flags)
 {
     assertEnteredPolicy(cx, proxy, id);
     RootedObject target(cx, GetProxyTargetObject(proxy));
     return GetOwnPropertyDescriptor(cx, target, id, 0, desc);
 }
 
 bool
-DirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
+DirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                    PropertyDescriptor *desc)
 {
-    assertEnteredPolicy(cx, proxy, id_);
-    RootedObject obj(cx, GetProxyTargetObject(proxy));
-    Rooted<jsid> id(cx, id_);
-    Rooted<Value> v(cx, desc->value);
-    return CheckDefineProperty(cx, obj, id, v, desc->getter, desc->setter, desc->attrs) &&
-           JS_DefinePropertyById(cx, obj, id, v, desc->getter, desc->setter, desc->attrs);
+    assertEnteredPolicy(cx, proxy, id);
+    RootedObject target(cx, GetProxyTargetObject(proxy));
+    RootedValue v(cx, desc->value);
+    return CheckDefineProperty(cx, target, id, v, desc->getter, desc->setter, desc->attrs) &&
+           JS_DefinePropertyById(cx, target, id, v, desc->getter, desc->setter, desc->attrs);
 }
 
 bool
 DirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                         AutoIdVector &props)
 {
     assertEnteredPolicy(cx, proxy, JSID_VOID);
     RootedObject target(cx, GetProxyTargetObject(proxy));
@@ -804,17 +803,17 @@ class ScriptedIndirectProxyHandler : pub
     ScriptedIndirectProxyHandler();
     virtual ~ScriptedIndirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props);
     virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* ES5 Harmony derived proxy traps. */
     virtual bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
@@ -887,22 +886,21 @@ ScriptedIndirectProxyHandler::getOwnProp
     return GetFundamentalTrap(cx, handler, cx->names().getOwnPropertyDescriptor, &fval) &&
            Trap1(cx, handler, fval, id, value.address()) &&
            ((value.get().isUndefined() && IndicatePropertyNotFound(desc)) ||
             (ReturnedValueMustNotBePrimitive(cx, proxy, cx->names().getPropertyDescriptor, value) &&
              ParsePropertyDescriptorObject(cx, proxy, value, desc)));
 }
 
 bool
-ScriptedIndirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id_,
+ScriptedIndirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                              PropertyDescriptor *desc)
 {
     RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
     RootedValue fval(cx), value(cx);
-    RootedId id(cx, id_);
     return GetFundamentalTrap(cx, handler, cx->names().defineProperty, &fval) &&
            NewPropertyDescriptorObject(cx, desc, &value) &&
            Trap2(cx, handler, fval, id, value, value.address());
 }
 
 bool
 ScriptedIndirectProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                                   AutoIdVector &props)
@@ -1066,17 +1064,17 @@ class ScriptedDirectProxyHandler : publi
     ScriptedDirectProxyHandler();
     virtual ~ScriptedDirectProxyHandler();
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props);
     virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* ES5 Harmony derived proxy traps. */
     virtual bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp) MOZ_OVERRIDE;
@@ -1670,22 +1668,19 @@ ScriptedDirectProxyHandler::getOwnProper
         return true;
     }
 
     // steps 3-4
     return ParsePropertyDescriptorObject(cx, proxy, v, desc, true);
 }
 
 bool
-ScriptedDirectProxyHandler::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_,
+ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                            PropertyDescriptor *desc)
 {
-    RootedObject proxy(cx, proxy_);
-    RootedId id(cx, id_);
-
     // step 1
     AutoPropDescArrayRooter descs(cx);
     PropDesc *d = descs.append();
     d->initFromPropertyDescriptor(*desc);
     RootedValue v(cx);
     if (!FromGenericPropertyDescriptor(cx, d, &v))
         return false;
 
@@ -2311,34 +2306,30 @@ Proxy::getOwnPropertyDescriptor(JSContex
 
     AutoPropertyDescriptorRooter desc(cx);
     if (!Proxy::getOwnPropertyDescriptor(cx, proxy, id, &desc, flags))
         return false;
     return NewPropertyDescriptorObject(cx, &desc, vp);
 }
 
 bool
-Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, PropertyDescriptor *desc)
+Proxy::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc)
 {
     JS_CHECK_RECURSION(cx, return false);
-    BaseProxyHandler *handler = GetProxyHandler(proxy_);
-    RootedObject proxy(cx, proxy_);
-    RootedId id(cx, id_);
+    BaseProxyHandler *handler = GetProxyHandler(proxy);
     AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
     if (!policy.allowed())
         return policy.returnValue();
     return GetProxyHandler(proxy)->defineProperty(cx, proxy, id, desc);
 }
 
 bool
-Proxy::defineProperty(JSContext *cx, JSObject *proxy_, jsid id_, const Value &v)
+Proxy::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v)
 {
     JS_CHECK_RECURSION(cx, return false);
-    RootedObject proxy(cx, proxy_);
-    RootedId id(cx, id_);
     AutoPropertyDescriptorRooter desc(cx);
     return ParsePropertyDescriptorObject(cx, proxy, v, &desc) &&
            Proxy::defineProperty(cx, proxy, id, &desc);
 }
 
 bool
 Proxy::getOwnPropertyNames(JSContext *cx, JSObject *proxy_, AutoIdVector &props)
 {
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -104,17 +104,17 @@ class JS_FRIEND_API(BaseProxyHandler) {
                        bool *bp);
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) = 0;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
                                           HandleId id, PropertyDescriptor *desc,
                                           unsigned flags) = 0;
-    virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) = 0;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                      AutoIdVector &props) = 0;
     virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp) = 0;
     virtual bool enumerate(JSContext *cx, JSObject *proxy,
                            AutoIdVector &props) = 0;
 
     /* ES5 Harmony derived proxy traps. */
@@ -158,17 +158,17 @@ public:
     explicit DirectProxyHandler(void *family);
 
     /* ES5 Harmony fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
                                           HandleId id, PropertyDescriptor *desc,
                                           unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *proxy,
                                      AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, JSObject *proxy, jsid id,
                          bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *proxy,
                            AutoIdVector &props) MOZ_OVERRIDE;
 
@@ -210,18 +210,18 @@ class Proxy {
     static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                       PropertyDescriptor *desc, unsigned flags);
     static bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id,
                                       MutableHandleValue vp);
     static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
                                          PropertyDescriptor *desc, unsigned flags);
     static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, unsigned flags, HandleId id,
                                          MutableHandleValue vp);
-    static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc);
-    static bool defineProperty(JSContext *cx, JSObject *proxy, jsid id, const Value &v);
+    static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, PropertyDescriptor *desc);
+    static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v);
     static bool getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoIdVector &props);
     static bool delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     static bool enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props);
 
     /* ES5 Harmony derived proxy traps. */
     static bool has(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     static bool hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
     static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp);
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -249,24 +249,24 @@ CrossCompartmentWrapper::getOwnPropertyD
     RootedId idCopy(cx, id);
     PIERCE(cx, wrapper,
            cx->compartment->wrapId(cx, idCopy.address()),
            Wrapper::getOwnPropertyDescriptor(cx, wrapper, idCopy, desc, flags),
            cx->compartment->wrap(cx, desc));
 }
 
 bool
-CrossCompartmentWrapper::defineProperty(JSContext *cx, JSObject *wrapperArg, jsid id,
+CrossCompartmentWrapper::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                         PropertyDescriptor *desc)
 {
-    RootedObject wrapper(cx, wrapperArg);
+    RootedId idCopy(cx, id);
     AutoPropertyDescriptorRooter desc2(cx, desc);
     PIERCE(cx, wrapper,
-           cx->compartment->wrapId(cx, &id) && cx->compartment->wrap(cx, &desc2),
-           Wrapper::defineProperty(cx, wrapper, id, &desc2),
+           cx->compartment->wrapId(cx, idCopy.address()) && cx->compartment->wrap(cx, &desc2),
+           Wrapper::defineProperty(cx, wrapper, idCopy, &desc2),
            NOTHING);
 }
 
 bool
 CrossCompartmentWrapper::getOwnPropertyNames(JSContext *cx, JSObject *wrapperArg,
                                              AutoIdVector &props)
 {
     RootedObject wrapper(cx, wrapperArg);
@@ -714,17 +714,17 @@ bool
 DeadObjectProxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
-DeadObjectProxy::defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+DeadObjectProxy::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 PropertyDescriptor *desc)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
     return false;
 }
 
 bool
 DeadObjectProxy::getOwnPropertyNames(JSContext *cx, JSObject *wrapper,
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -85,17 +85,17 @@ class JS_FRIEND_API(CrossCompartmentWrap
 
     virtual bool finalizeInBackground(HandleValue priv) MOZ_OVERRIDE;
 
     /* ES5 Harmony fundamental wrapper traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* ES5 Harmony derived wrapper traps. */
     virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
@@ -161,17 +161,17 @@ class JS_FRIEND_API(DeadObjectProxy) : p
 
     explicit DeadObjectProxy();
 
     /* ES5 Harmony fundamental wrapper traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                        PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
                                           PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+    virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                 PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
     virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
     virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
 
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, JSObject *proxy, unsigned argc, Value *vp);
     virtual bool construct(JSContext *cx, JSObject *proxy, unsigned argc, Value *argv, Value *rval);
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -1380,20 +1380,20 @@ class DebugScopeProxy : public BaseProxy
         RootedValue value(cx, *vp);
         if (!JSObject::setGeneric(cx, scope, scope, id, &value, strict))
             return false;
 
         *vp = value;
         return true;
     }
 
-    bool defineProperty(JSContext *cx, JSObject *proxy, jsid idArg, PropertyDescriptor *desc) MOZ_OVERRIDE
+    bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
+                        PropertyDescriptor *desc) MOZ_OVERRIDE
     {
         Rooted<ScopeObject*> scope(cx, &proxy->asDebugScope().scope());
-        RootedId id(cx, idArg);
 
         bool found;
         if (!has(cx, proxy, id, &found))
             return false;
         if (found)
             return Throw(cx, id, JSMSG_CANT_REDEFINE_PROP);
 
         return JS_DefinePropertyById(cx, scope, id, desc->value, desc->getter, desc->setter,
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -177,17 +177,18 @@ class XPCWrappedNativeXrayTraits : publi
 public:
     static const XrayType Type = XrayForWrappedNative;
 
     static bool resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id,
                                       JSPropertyDescriptor *desc, unsigned flags);
     virtual bool resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper, JSObject *wrapper,
                                     JSObject *holder, jsid id, JSPropertyDescriptor *desc,
                                     unsigned flags);
-    static bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+    static bool defineProperty(JSContext *cx, JS::Handle<JSObject *> wrapper,
+                               JS::Handle<jsid>,
                                PropertyDescriptor *desc,
                                PropertyDescriptor &existingDesc,
                                bool *defined);
     static bool enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
                                JS::AutoIdVector &props);
     static bool call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp);
     static bool construct(JSContext *cx, JSObject *wrapper, unsigned argc,
                           Value *argv, Value *rval);
@@ -221,17 +222,17 @@ class DOMXrayTraits : public XrayTraits
 public:
     static const XrayType Type = XrayForDOMObject;
 
     static bool resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject *holder, jsid id,
                                       JSPropertyDescriptor *desc, unsigned flags);
     virtual bool resolveOwnProperty(JSContext *cx, js::Wrapper &jsWrapper, JSObject *wrapper,
                                     JSObject *holder, jsid id, JSPropertyDescriptor *desc,
                                     unsigned flags);
-    static bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+    static bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                PropertyDescriptor *desc,
                                PropertyDescriptor &existingDesc,
                                bool *defined);
     static bool enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
                                JS::AutoIdVector &props);
     static bool call(JSContext *cx, JSObject *wrapper, unsigned argc, Value *vp);
     static bool construct(JSContext *cx, JSObject *wrapper, unsigned argc,
                           Value *argv, Value *rval);
@@ -1033,17 +1034,17 @@ XPCWrappedNativeXrayTraits::resolveOwnPr
                      hasProp), "id got defined somewhere else?");
 #endif
     }
 
     return true;
 }
 
 bool
-XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                            PropertyDescriptor *desc,
                                            PropertyDescriptor &existingDesc,
                                            bool *defined)
 {
     *defined = false;
     JSObject *holder = singleton.ensureHolder(cx, wrapper);
     if (isResolving(cx, holder, id)) {
         if (!(desc->attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
@@ -1187,28 +1188,28 @@ DOMXrayTraits::resolveOwnProperty(JSCont
 
     NS_ASSERTION(!desc->obj || desc->obj == wrapper,
                  "What did we resolve this on?");
 
     return true;
 }
 
 bool
-DOMXrayTraits::defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                               PropertyDescriptor *desc,
                               PropertyDescriptor &existingDesc,
                               bool *defined)
 {
     if (!existingDesc.obj)
         return true;
 
     JSObject *obj= getTargetObject(wrapper);
     if (!js::IsProxy(obj))
         return true;
-    
+
     *defined = true;
     return js::GetProxyHandler(obj)->defineProperty(cx, wrapper, id, desc);
 }
 
 bool
 DOMXrayTraits::enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
                               JS::AutoIdVector &props)
 {
@@ -1600,22 +1601,19 @@ XrayWrapper<Base, Traits>::getOwnPropert
     if (desc->obj)
         desc->obj = wrapper;
 
     return true;
 }
 
 template <typename Base, typename Traits>
 bool
-XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, JSObject *wrapperArg, jsid idArg,
+XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
                                           js::PropertyDescriptor *desc)
 {
-    JS::Rooted<JSObject *> wrapper(cx, wrapperArg);
-    JS::Rooted<jsid> id(cx, idArg);
-
     assertEnteredPolicy(cx, wrapper, id);
     // Redirect access straight to the wrapper if we should be transparent.
     if (XrayUtils::IsTransparent(cx, wrapper, id)) {
         JSObject *obj = Traits::getTargetObject(wrapper);
         JSAutoCompartment ac(cx, obj);
         if (!JS_WrapPropertyDescriptor(cx, desc))
             return false;
 
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -66,17 +66,17 @@ class XrayWrapper : public Base {
     virtual ~XrayWrapper();
 
     /* Fundamental proxy traps. */
     virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject *> wrapper, JS::Handle<jsid> id,
                                        js::PropertyDescriptor *desc, unsigned flags) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject *> wrapper, JS::Handle<jsid> id,
                                           js::PropertyDescriptor *desc,
                                           unsigned flags) MOZ_OVERRIDE;
-    virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
+    virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject *> wrapper, JS::Handle<jsid> id,
                                 js::PropertyDescriptor *desc);
     virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper,
                                      js::AutoIdVector &props);
     virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
     virtual bool enumerate(JSContext *cx, JSObject *wrapper, js::AutoIdVector &props);
 
     /* Derived proxy traps. */
     virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id,