Bug 603201 - Change GetProperty receiver argument to Value in the browser. r=smaug
authorTom Schuster <evilpies@gmail.com>
Fri, 18 Sep 2015 00:14:41 +0200
changeset 297473 81385142227216ba4f0a73a11dd1a0ef8df63c4e
parent 297472 0dd901033bab9d3b1b9e2c8bbc914b42496afb06
child 297474 6126225bbb9311e8279825af2457790d9f4d8e66
push id962
push userjlund@mozilla.com
push dateFri, 04 Dec 2015 23:28:54 +0000
treeherdermozilla-release@23a2d286e80f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs603201
milestone43.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 603201 - Change GetProperty receiver argument to Value in the browser. r=smaug
dom/base/nsGlobalWindow.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
js/ipc/JavaScriptBase.h
js/ipc/PJavaScript.ipdl
js/ipc/WrapperAnswer.cpp
js/ipc/WrapperAnswer.h
js/ipc/WrapperOwner.cpp
js/ipc/WrapperOwner.h
js/src/jsapi.cpp
js/src/jsapi.h
js/xpconnect/src/Sandbox.cpp
js/xpconnect/wrappers/AddonWrapper.cpp
js/xpconnect/wrappers/AddonWrapper.h
js/xpconnect/wrappers/WaiveXrayWrapper.cpp
js/xpconnect/wrappers/WaiveXrayWrapper.h
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -630,17 +630,17 @@ public:
   virtual bool preventExtensions(JSContext* cx,
                                  JS::Handle<JSObject*> proxy,
                                  JS::ObjectOpResult& result) const override;
   virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
                             const override;
   virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy,
                    JS::Handle<jsid> id, bool *bp) const override;
   virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy,
-                   JS::Handle<JSObject*> receiver,
+                   JS::Handle<JS::Value> receiver,
                    JS::Handle<jsid> id,
                    JS::MutableHandle<JS::Value> vp) const override;
   virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy,
                    JS::Handle<jsid> id, JS::Handle<JS::Value> v,
                    JS::Handle<JS::Value> receiver,
                    JS::ObjectOpResult &result) const override;
 
   // SpiderMonkey extensions
@@ -895,17 +895,17 @@ nsOuterWindowProxy::hasOwn(JSContext *cx
     return true;
   }
 
   return js::Wrapper::hasOwn(cx, proxy, id, bp);
 }
 
 bool
 nsOuterWindowProxy::get(JSContext *cx, JS::Handle<JSObject*> proxy,
-                        JS::Handle<JSObject*> receiver,
+                        JS::Handle<JS::Value> receiver,
                         JS::Handle<jsid> id,
                         JS::MutableHandle<JS::Value> vp) const
 {
   if (id == nsDOMClassInfo::sWrappedJSObject_id &&
       xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) {
     vp.set(JS::ObjectValue(*proxy));
     return true;
   }
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1694,18 +1694,18 @@ NativePropertyHooks sEmptyNativeProperty
   },
   prototypes::id::_ID_Count,
   constructors::id::_ID_Count,
   nullptr
 };
 
 bool
 GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id, bool* found,
-                       JS::MutableHandle<JS::Value> vp)
+                       JS::Handle<JS::Value> receiver, JS::Handle<jsid> id,
+                       bool* found, JS::MutableHandle<JS::Value> vp)
 {
   JS::Rooted<JSObject*> proto(cx);
   if (!js::GetObjectProto(cx, proxy, &proto)) {
     return false;
   }
   if (!proto) {
     *found = false;
     return true;
@@ -1714,17 +1714,17 @@ GetPropertyOnPrototype(JSContext* cx, JS
   if (!JS_HasPropertyById(cx, proto, id, found)) {
     return false;
   }
 
   if (!*found) {
     return true;
   }
 
-  return JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp);
+  return JS_ForwardGetPropertyTo(cx, proto, id, receiver, vp);
 }
 
 bool
 HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
                        JS::Handle<jsid> id, bool* has)
 {
   JS::Rooted<JSObject*> proto(cx);
   if (!js::GetObjectProto(cx, proxy, &proto)) {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1842,18 +1842,18 @@ UnforgeableValueOf(JSContext* cx, unsign
 bool
 ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
 
 bool
 ThrowConstructorWithoutNew(JSContext* cx, const char* name);
 
 bool
 GetPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
-                       JS::Handle<jsid> id, bool* found,
-                       JS::MutableHandle<JS::Value> vp);
+                       JS::Handle<JS::Value> receiver, JS::Handle<jsid> id,
+                       bool* found, JS::MutableHandle<JS::Value> vp);
 
 //
 bool
 HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
                        JS::Handle<jsid> id, bool* has);
 
 
 // Append the property names in "names" to "props". If
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -11034,17 +11034,17 @@ class CGDOMJSProxyHandler_hasOwn(ClassMe
             indexed=indexed,
             named=named)
 
 
 class CGDOMJSProxyHandler_get(ClassMethod):
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'),
                 Argument('JS::Handle<JSObject*>', 'proxy'),
-                Argument('JS::Handle<JSObject*>', 'receiver'),
+                Argument('JS::Handle<JS::Value>', 'receiver'),
                 Argument('JS::Handle<jsid>', 'id'),
                 Argument('JS::MutableHandle<JS::Value>', 'vp')]
         ClassMethod.__init__(self, "get", "bool", args,
                              virtual=True, override=True, const=True)
         self.descriptor = descriptor
 
     def getBody(self):
         getUnforgeableOrExpando = dedent("""
@@ -11089,17 +11089,17 @@ class CGDOMJSProxyHandler_get(ClassMetho
             if self.descriptor.supportsIndexedProperties():
                 getNamed = CGIfWrapper(getNamed, "!IsArrayIndex(index)")
             getNamed = getNamed.define() + "\n"
         else:
             getNamed = ""
 
         getOnPrototype = dedent("""
             bool foundOnPrototype;
-            if (!GetPropertyOnPrototype(cx, proxy, id, &foundOnPrototype, vp)) {
+            if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) {
               return false;
             }
 
             if (foundOnPrototype) {
               return true;
             }
 
             """)
--- a/js/ipc/JavaScriptBase.h
+++ b/js/ipc/JavaScriptBase.h
@@ -61,19 +61,18 @@ class JavaScriptBase : public WrapperOwn
     bool RecvHas(const uint64_t& objId, const JSIDVariant& id,
                    ReturnStatus* rs, bool* bp) {
         return Answer::RecvHas(ObjectId::deserialize(objId), id, rs, bp);
     }
     bool RecvHasOwn(const uint64_t& objId, const JSIDVariant& id,
                       ReturnStatus* rs, bool* bp) {
         return Answer::RecvHasOwn(ObjectId::deserialize(objId), id, rs, bp);
     }
-    bool RecvGet(const uint64_t& objId, const ObjectVariant& receiverVar,
-                   const JSIDVariant& id,
-                   ReturnStatus* rs, JSVariant* result) {
+    bool RecvGet(const uint64_t& objId, const JSVariant& receiverVar, const JSIDVariant& id,
+                 ReturnStatus* rs, JSVariant* result) {
         return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
     }
     bool RecvSet(const uint64_t& objId, const JSIDVariant& id, const JSVariant& value,
                  const JSVariant& receiverVar, ReturnStatus* rs) {
         return Answer::RecvSet(ObjectId::deserialize(objId), id, value, receiverVar, rs);
     }
 
     bool RecvIsExtensible(const uint64_t& objId, ReturnStatus* rs,
@@ -150,18 +149,17 @@ class JavaScriptBase : public WrapperOwn
     bool SendHas(const ObjectId& objId, const JSIDVariant& id,
                    ReturnStatus* rs, bool* bp) {
         return Base::SendHas(objId.serialize(), id, rs, bp);
     }
     bool SendHasOwn(const ObjectId& objId, const JSIDVariant& id,
                     ReturnStatus* rs, bool* bp) {
         return Base::SendHasOwn(objId.serialize(), id, rs, bp);
     }
-    bool SendGet(const ObjectId& objId, const ObjectVariant& receiverVar,
-                 const JSIDVariant& id,
+    bool SendGet(const ObjectId& objId, const JSVariant& receiverVar, const JSIDVariant& id,
                  ReturnStatus* rs, JSVariant* result) {
         return Base::SendGet(objId.serialize(), receiverVar, id, rs, result);
     }
     bool SendSet(const ObjectId& objId, const JSIDVariant& id, const JSVariant& value,
                  const JSVariant& receiverVar, ReturnStatus* rs) {
         return Base::SendSet(objId.serialize(), id, value, receiverVar, rs);
     }
 
--- a/js/ipc/PJavaScript.ipdl
+++ b/js/ipc/PJavaScript.ipdl
@@ -27,17 +27,17 @@ both:
     prio(high) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
     prio(high) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
     prio(high) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
     prio(high) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
     prio(high) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs);
 
     prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
     prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
-    prio(high) sync Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
+    prio(high) sync Get(uint64_t objId, JSVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
     prio(high) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs);
 
     prio(high) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
     prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
     prio(high) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
     prio(high) sync ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
     prio(high) sync ClassName(uint64_t objId) returns (nsCString name);
     prio(high) sync GetPrototype(uint64_t objId) returns (ReturnStatus rs, ObjectOrNullVariant result);
--- a/js/ipc/WrapperAnswer.cpp
+++ b/js/ipc/WrapperAnswer.cpp
@@ -267,35 +267,35 @@ WrapperAnswer::RecvHasOwn(const ObjectId
         return fail(jsapi, rs);
 
     if (!JS_HasOwnPropertyById(cx, obj, id, foundp))
         return fail(jsapi, rs);
     return ok(rs);
 }
 
 bool
-WrapperAnswer::RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
+WrapperAnswer::RecvGet(const ObjectId& objId, const JSVariant& receiverVar,
                        const JSIDVariant& idVar, ReturnStatus* rs, JSVariant* result)
 {
     // We may run scripted getters.
     AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()),
                         "Cross-Process Object Wrapper 'get'");
     aes.TakeOwnershipOfErrorReporting();
     JSContext* cx = aes.cx();
 
     // The outparam will be written to the buffer, so it must be set even if
     // the parent won't read it.
     *result = UndefinedVariant();
 
     RootedObject obj(cx, findObjectById(cx, objId));
     if (!obj)
         return fail(aes, rs);
 
-    RootedObject receiver(cx, fromObjectVariant(cx, receiverVar));
-    if (!receiver)
+    RootedValue receiver(cx);
+    if (!fromVariant(cx, receiverVar, &receiver))
         return fail(aes, rs);
 
     RootedId id(cx);
     if (!fromJSIDVariant(cx, idVar, &id))
         return fail(aes, rs);
 
     JS::RootedValue val(cx);
     if (!JS_ForwardGetPropertyTo(cx, obj, id, receiver, &val))
--- a/js/ipc/WrapperAnswer.h
+++ b/js/ipc/WrapperAnswer.h
@@ -34,17 +34,17 @@ class WrapperAnswer : public virtual Jav
     bool RecvDefineProperty(const ObjectId& objId, const JSIDVariant& id,
                             const PPropertyDescriptor& flags, ReturnStatus* rs);
     bool RecvDelete(const ObjectId& objId, const JSIDVariant& id, ReturnStatus* rs);
 
     bool RecvHas(const ObjectId& objId, const JSIDVariant& id,
                  ReturnStatus* rs, bool* foundp);
     bool RecvHasOwn(const ObjectId& objId, const JSIDVariant& id,
                     ReturnStatus* rs, bool* foundp);
-    bool RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
+    bool RecvGet(const ObjectId& objId, const JSVariant& receiverVar,
                  const JSIDVariant& id,
                  ReturnStatus* rs, JSVariant* result);
     bool RecvSet(const ObjectId& objId, const JSIDVariant& id, const JSVariant& value,
                  const JSVariant& receiverVar, ReturnStatus* rs);
 
     bool RecvIsExtensible(const ObjectId& objId, ReturnStatus* rs,
                           bool* result);
     bool RecvCallOrConstruct(const ObjectId& objId, InfallibleTArray<JSParam>&& argv,
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -106,17 +106,17 @@ class CPOWProxyHandler : public BaseProx
                                  AutoIdVector& props) const override;
     virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
                          ObjectOpResult& result) const override;
     virtual bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp) const override;
     virtual bool preventExtensions(JSContext* cx, HandleObject proxy,
                                    ObjectOpResult& result) const override;
     virtual bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override;
     virtual bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
-    virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver,
+    virtual bool get(JSContext* cx, HandleObject proxy, HandleValue receiver,
                      HandleId id, MutableHandleValue vp) const override;
     virtual bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
                      JS::HandleValue receiver, JS::ObjectOpResult& result) const override;
     virtual bool call(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
     virtual bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args) const override;
 
     virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
                                        MutableHandle<JSPropertyDescriptor> desc) const override;
@@ -336,17 +336,17 @@ WrapperOwner::hasOwn(JSContext* cx, Hand
         return ipcfail(cx);
 
     LOG_STACK();
 
     return !!ok(cx, status);
 }
 
 bool
-CPOWProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
+CPOWProxyHandler::get(JSContext* cx, HandleObject proxy, HandleValue receiver,
                       HandleId id, MutableHandleValue vp) const
 {
     FORWARD(get, (cx, proxy, receiver, id, vp));
 }
 
 static bool
 CPOWDOMQI(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -453,23 +453,23 @@ WrapperOwner::DOMQI(JSContext* cx, JS::H
     if (!propDesc.value().isObject()) {
         MOZ_ASSERT_UNREACHABLE("We didn't get QueryInterface off a node");
         return Throw(cx, NS_ERROR_UNEXPECTED);
     }
     return JS_CallFunctionValue(cx, proxy, propDesc.value(), args, args.rval());
 }
 
 bool
-WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
+WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleValue receiver,
                   HandleId id, MutableHandleValue vp)
 {
     ObjectId objId = idOf(proxy);
 
-    ObjectVariant receiverVar;
-    if (!toObjectVariant(cx, receiver, &receiverVar))
+    JSVariant receiverVar;
+    if (!toVariant(cx, receiver, &receiverVar))
         return false;
 
     JSIDVariant idVar;
     if (!toJSIDVariant(cx, id, &idVar))
         return false;
 
     AuxCPOWData* data = AuxCPOWDataOf(proxy);
     if (data->isDOMObject &&
--- a/js/ipc/WrapperOwner.h
+++ b/js/ipc/WrapperOwner.h
@@ -35,17 +35,17 @@ class WrapperOwner : public virtual Java
                         JS::Handle<JSPropertyDescriptor> desc,
                         JS::ObjectOpResult& result);
     bool ownPropertyKeys(JSContext* cx, JS::HandleObject proxy, JS::AutoIdVector& props);
     bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
                  JS::ObjectOpResult& result);
     bool preventExtensions(JSContext* cx, JS::HandleObject proxy, JS::ObjectOpResult& result);
     bool isExtensible(JSContext* cx, JS::HandleObject proxy, bool* extensible);
     bool has(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, bool* bp);
-    bool get(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
+    bool get(JSContext* cx, JS::HandleObject proxy, JS::HandleValue receiver,
              JS::HandleId id, JS::MutableHandleValue vp);
     bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
              JS::HandleValue receiver, JS::ObjectOpResult& result);
     bool callOrConstruct(JSContext* cx, JS::HandleObject proxy, const JS::CallArgs& args,
                          bool construct);
 
     // SpiderMonkey extensions.
     bool getPropertyDescriptor(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
@@ -120,17 +120,17 @@ class WrapperOwner : public virtual Java
                                     ReturnStatus* rs) = 0;
     virtual bool SendDelete(const ObjectId& objId, const JSIDVariant& id,
                             ReturnStatus* rs) = 0;
 
     virtual bool SendHas(const ObjectId& objId, const JSIDVariant& id,
                          ReturnStatus* rs, bool* bp) = 0;
     virtual bool SendHasOwn(const ObjectId& objId, const JSIDVariant& id,
                             ReturnStatus* rs, bool* bp) = 0;
-    virtual bool SendGet(const ObjectId& objId, const ObjectVariant& receiverVar,
+    virtual bool SendGet(const ObjectId& objId, const JSVariant& receiverVar,
                          const JSIDVariant& id,
                          ReturnStatus* rs, JSVariant* result) = 0;
     virtual bool SendSet(const ObjectId& objId, const JSIDVariant& id, const JSVariant& value,
                          const JSVariant& receiverVar, ReturnStatus* rs) = 0;
 
     virtual bool SendIsExtensible(const ObjectId& objId, ReturnStatus* rs,
                                   bool* result) = 0;
     virtual bool SendCallOrConstruct(const ObjectId& objId, const nsTArray<JSParam>& argv,
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -2915,34 +2915,42 @@ JS_GetPropertyDescriptor(JSContext* cx, 
         return false;
     RootedId id(cx, AtomToId(atom));
     return atom && JS_GetPropertyDescriptorById(cx, obj, id, desc);
 }
 
 JS_PUBLIC_API(bool)
 JS_GetPropertyById(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
 {
-    return JS_ForwardGetPropertyTo(cx, obj, id, obj, vp);
-}
-
-JS_PUBLIC_API(bool)
-JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject onBehalfOf,
-                        JS::MutableHandleValue vp)
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj, id);
+
+    return GetProperty(cx, obj, obj, id, vp);
+}
+
+JS_PUBLIC_API(bool)
+JS_ForwardGetPropertyTo(JSContext* cx, HandleObject obj, HandleId id, HandleValue onBehalfOf,
+                        MutableHandleValue vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id, onBehalfOf);
 
     return GetProperty(cx, obj, onBehalfOf, id, vp);
 }
 
 JS_PUBLIC_API(bool)
-JS_GetElement(JSContext* cx, HandleObject objArg, uint32_t index, MutableHandleValue vp)
-{
-    return JS_ForwardGetElementTo(cx, objArg, index, objArg, vp);
+JS_GetElement(JSContext* cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
+{
+    AssertHeapIsIdle(cx);
+    CHECK_REQUEST(cx);
+    assertSameCompartment(cx, obj);
+
+    return GetElement(cx, obj, obj, index, vp);
 }
 
 JS_PUBLIC_API(bool)
 JS_ForwardGetElementTo(JSContext* cx, HandleObject obj, uint32_t index, HandleObject onBehalfOf,
                        MutableHandleValue vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2848,17 +2848,17 @@ JS_GetPropertyDescriptor(JSContext* cx, 
 
 extern JS_PUBLIC_API(bool)
 JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
-JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject onBehalfOf,
+JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue onBehalfOf,
                         JS::MutableHandleValue vp);
 
 extern JS_PUBLIC_API(bool)
 JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v);
 
 extern JS_PUBLIC_API(bool)
 JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
 
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -823,17 +823,17 @@ bool
 xpc::SandboxProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
                                  JS::Handle<jsid> id, bool* bp) const
 {
     return BaseProxyHandler::hasOwn(cx, proxy, id, bp);
 }
 
 bool
 xpc::SandboxProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy,
-                              JS::Handle<JSObject*> receiver,
+                              JS::Handle<JS::Value> receiver,
                               JS::Handle<jsid> id,
                               JS::MutableHandle<Value> vp) const
 {
     return BaseProxyHandler::get(cx, proxy, receiver, id, vp);
 }
 
 bool
 xpc::SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy,
--- a/js/xpconnect/wrappers/AddonWrapper.cpp
+++ b/js/xpconnect/wrappers/AddonWrapper.cpp
@@ -164,31 +164,28 @@ AddonWrapper<Base>::getOwnPropertyDescri
     if (desc.object())
         return true;
 
     return Base::getOwnPropertyDescriptor(cx, wrapper, id, desc);
 }
 
 template<typename Base>
 bool
-AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
+AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<Value> receiver,
                         JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const
 {
     Rooted<JSPropertyDescriptor> desc(cx);
     if (!InterposeProperty(cx, wrapper, nullptr, id, &desc))
         return false;
 
     if (!desc.object())
         return Base::get(cx, wrapper, receiver, id, vp);
 
     if (desc.getter()) {
-        MOZ_ASSERT(desc.hasGetterObject());
-        AutoValueVector args(cx);
-        RootedValue fval(cx, ObjectValue(*desc.getterObject()));
-        return JS_CallFunctionValue(cx, receiver, fval, args, vp);
+        return Call(cx, receiver, desc.getterObject(), HandleValueArray::empty(), vp);
     } else {
         vp.set(desc.value());
         return true;
     }
 }
 
 template<typename Base>
 bool
--- a/js/xpconnect/wrappers/AddonWrapper.h
+++ b/js/xpconnect/wrappers/AddonWrapper.h
@@ -31,17 +31,17 @@ class AddonWrapper : public Base {
     virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                           JS::Handle<jsid> id,
                                           JS::MutableHandle<JSPropertyDescriptor> desc) const override;
     virtual bool defineProperty(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
                                 JS::Handle<JSPropertyDescriptor> desc,
                                 JS::ObjectOpResult& result) const override;
     virtual bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id,
                          JS::ObjectOpResult& result) const override;
-    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
+    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JS::Value> receiver,
                      JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
     virtual bool set(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
                      JS::HandleValue receiver, JS::ObjectOpResult& result) const override;
     virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
                       const JS::CallArgs& args) const override;
 
     virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                        JS::Handle<jsid> id,
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp
@@ -45,18 +45,17 @@ WaiveXrayWrapper::getOwnPropertyDescript
                                            HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc)
                                            const
 {
     return CrossCompartmentWrapper::getOwnPropertyDescriptor(cx, wrapper, id, desc) &&
            WrapperFactory::WaiveXrayAndWrap(cx, desc.value()) && WaiveAccessors(cx, desc);
 }
 
 bool
-WaiveXrayWrapper::get(JSContext* cx, HandleObject wrapper,
-                      HandleObject receiver, HandleId id,
+WaiveXrayWrapper::get(JSContext* cx, HandleObject wrapper, HandleValue receiver, HandleId id,
                       MutableHandleValue vp) const
 {
     return CrossCompartmentWrapper::get(cx, wrapper, receiver, id, vp) &&
            WrapperFactory::WaiveXrayAndWrap(cx, vp);
 }
 
 bool
 WaiveXrayWrapper::enumerate(JSContext* cx, HandleObject proxy,
--- a/js/xpconnect/wrappers/WaiveXrayWrapper.h
+++ b/js/xpconnect/wrappers/WaiveXrayWrapper.h
@@ -17,17 +17,17 @@ class WaiveXrayWrapper : public js::Cros
   public:
     explicit MOZ_CONSTEXPR WaiveXrayWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags) { }
 
     virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                           JS::Handle<jsid> id,
                                           JS::MutableHandle<JSPropertyDescriptor> desc) const override;
     virtual bool getPrototype(JSContext* cx, JS::Handle<JSObject*> wrapper,
                               JS::MutableHandle<JSObject*> protop) const override;
-    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
+    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JS::Value> receiver,
                      JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
     virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
                       const JS::CallArgs& args) const override;
     virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper,
                            const JS::CallArgs& args) const override;
 
     virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
                            JS::MutableHandle<JSObject*> objp) const override;
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -2087,23 +2087,28 @@ XrayWrapper<Base, Traits>::delete_(JSCon
     }
 
     return Traits::singleton.delete_(cx, wrapper, id, result);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::get(JSContext* cx, HandleObject wrapper,
-                               HandleObject receiver, HandleId id,
+                               HandleValue receiver, HandleId id,
                                MutableHandleValue vp) const
 {
     // Skip our Base if it isn't already ProxyHandler.
     // NB: None of the functions we call are prepared for the receiver not
     // being the wrapper, so ignore the receiver here.
-    return js::BaseProxyHandler::get(cx, wrapper, Traits::HasPrototype ? receiver : wrapper, id, vp);
+    RootedValue thisv(cx);
+    if (Traits::HasPrototype)
+      thisv = receiver;
+    else
+      thisv.setObject(*wrapper);
+    return js::BaseProxyHandler::get(cx, wrapper, thisv, id, vp);
 }
 
 template <typename Base, typename Traits>
 bool
 XrayWrapper<Base, Traits>::set(JSContext* cx, HandleObject wrapper, HandleId id, HandleValue v,
                                HandleValue receiver, ObjectOpResult& result) const
 {
     MOZ_ASSERT(!Traits::HasPrototype);
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -441,17 +441,17 @@ class XrayWrapper : public Base {
                               JS::HandleObject proto, JS::ObjectOpResult& result) const override;
     virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject wrapper,
                                        bool* succeeded) const override;
     virtual bool preventExtensions(JSContext* cx, JS::Handle<JSObject*> wrapper,
                                    JS::ObjectOpResult& result) const override;
     virtual bool isExtensible(JSContext* cx, JS::Handle<JSObject*> wrapper, bool* extensible) const override;
     virtual bool has(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                      bool* bp) const override;
-    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
+    virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::HandleValue receiver,
                      JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
     virtual bool set(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
                      JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
                      JS::ObjectOpResult& result) const override;
     virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
                       const JS::CallArgs& args) const override;
     virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper,
                            const JS::CallArgs& args) const override;
@@ -515,17 +515,17 @@ public:
     virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
                                           JS::Handle<jsid> id,
                                           JS::MutableHandle<JSPropertyDescriptor> desc) const override;
 
     // We just forward the high-level methods to the BaseProxyHandler versions
     // which implement them in terms of lower-level methods.
     virtual bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
                      bool* bp) const override;
-    virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
+    virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::HandleValue receiver,
                      JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
     virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
                      JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
                      JS::ObjectOpResult& result) const override;
 
     virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
                                        JS::Handle<jsid> id,
                                        JS::MutableHandle<JSPropertyDescriptor> desc) const override;