From 55fab4d8d91c2280dd75300177c8c70800dec291 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Wed, 5 Feb 2014 08:39:59 -0800 Subject: [PATCH] Bug 962604 - Add ActorDestroy handling to CPOWs (r=mrbkap) --- dom/bindings/BindingUtils.cpp | 2 +- dom/ipc/ContentParent.cpp | 2 +- js/ipc/JavaScriptParent.cpp | 68 ++++++++++++++++++++--------------- js/ipc/JavaScriptParent.h | 9 +++-- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 31c6cd7f00c9..b327bc7a350c 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1886,7 +1886,7 @@ InterfaceHasInstance(JSContext* cx, JS::Handle obj, JS::Rooted unwrapped(cx, js::CheckedUnwrap(instance, true)); if (unwrapped && jsipc::JavaScriptParent::IsCPOW(unwrapped)) { bool boolp = false; - if (!jsipc::JavaScriptParent::DOMInstanceOf(unwrapped, clasp->mPrototypeID, + if (!jsipc::JavaScriptParent::DOMInstanceOf(cx, unwrapped, clasp->mPrototypeID, clasp->mDepth, &boolp)) { return false; } diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 34b37f70b2f0..d4b6b4de8f3a 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2012,7 +2012,7 @@ ContentParent::AllocPJavaScriptParent() bool ContentParent::DeallocPJavaScriptParent(PJavaScriptParent *parent) { - static_cast(parent)->destroyFromContent(); + static_cast(parent)->decref(); return true; } diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp index 2ce295044241..6cf04cc765ce 100644 --- a/js/ipc/JavaScriptParent.cpp +++ b/js/ipc/JavaScriptParent.cpp @@ -95,10 +95,18 @@ class CPOWProxyHandler : public BaseProxyHandler CPOWProxyHandler CPOWProxyHandler::singleton; +#define FORWARD(call, args) \ + JavaScriptParent *parent = ParentOf(proxy); \ + if (!parent->active()) { \ + JS_ReportError(cx, "cannot use a CPOW whose process is gone"); \ + return false; \ + } \ + return parent->call args; + bool CPOWProxyHandler::preventExtensions(JSContext *cx, HandleObject proxy) { - return ParentOf(proxy)->preventExtensions(cx, proxy); + FORWARD(preventExtensions, (cx, proxy)); } bool @@ -117,7 +125,7 @@ bool CPOWProxyHandler::getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc, unsigned flags) { - return ParentOf(proxy)->getPropertyDescriptor(cx, proxy, id, desc, flags); + FORWARD(getPropertyDescriptor, (cx, proxy, id, desc, flags)); } bool @@ -145,7 +153,7 @@ CPOWProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc, unsigned flags) { - return ParentOf(proxy)->getOwnPropertyDescriptor(cx, proxy, id, desc, flags); + FORWARD(getOwnPropertyDescriptor, (cx, proxy, id, desc, flags)); } bool @@ -172,7 +180,7 @@ bool CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandle desc) { - return ParentOf(proxy)->defineProperty(cx, proxy, id, desc); + FORWARD(defineProperty, (cx, proxy, id, desc)); } bool @@ -199,7 +207,7 @@ JavaScriptParent::defineProperty(JSContext *cx, HandleObject proxy, HandleId id, bool CPOWProxyHandler::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props) { - return ParentOf(proxy)->getOwnPropertyNames(cx, proxy, props); + FORWARD(getOwnPropertyNames, (cx, proxy, props)); } bool @@ -211,7 +219,7 @@ JavaScriptParent::getOwnPropertyNames(JSContext *cx, HandleObject proxy, AutoIdV bool CPOWProxyHandler::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { - return ParentOf(proxy)->delete_(cx, proxy, id, bp); + FORWARD(delete_, (cx, proxy, id, bp)); } bool @@ -233,7 +241,7 @@ JavaScriptParent::delete_(JSContext *cx, HandleObject proxy, HandleId id, bool * bool CPOWProxyHandler::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &props) { - return ParentOf(proxy)->enumerate(cx, proxy, props); + FORWARD(enumerate, (cx, proxy, props)); } bool @@ -245,7 +253,7 @@ JavaScriptParent::enumerate(JSContext *cx, HandleObject proxy, AutoIdVector &pro bool CPOWProxyHandler::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { - return ParentOf(proxy)->has(cx, proxy, id, bp); + FORWARD(has, (cx, proxy, id, bp)); } bool @@ -267,7 +275,7 @@ JavaScriptParent::has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) bool CPOWProxyHandler::hasOwn(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) { - return ParentOf(proxy)->hasOwn(cx, proxy, id, bp); + FORWARD(hasOwn, (cx, proxy, id, bp)); } bool @@ -290,7 +298,7 @@ bool CPOWProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id, MutableHandleValue vp) { - return ParentOf(proxy)->get(cx, proxy, receiver, id, vp); + FORWARD(get, (cx, proxy, receiver, id, vp)); } bool @@ -319,7 +327,7 @@ bool CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver, JS::HandleId id, bool strict, JS::MutableHandleValue vp) { - return ParentOf(proxy)->set(cx, proxy, receiver, id, strict, vp); + FORWARD(set, (cx, proxy, receiver, id, strict, vp)); } bool @@ -351,7 +359,7 @@ JavaScriptParent::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject re bool CPOWProxyHandler::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) { - return ParentOf(proxy)->keys(cx, proxy, props); + FORWARD(keys, (cx, proxy, props)); } bool @@ -363,7 +371,7 @@ JavaScriptParent::keys(JSContext *cx, HandleObject proxy, AutoIdVector &props) bool CPOWProxyHandler::isExtensible(JSContext *cx, HandleObject proxy, bool *extensible) { - return ParentOf(proxy)->isExtensible(cx, proxy, extensible); + FORWARD(isExtensible, (cx, proxy, extensible)); } bool @@ -381,7 +389,7 @@ JavaScriptParent::isExtensible(JSContext *cx, HandleObject proxy, bool *extensib bool CPOWProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args) { - return ParentOf(proxy)->call(cx, proxy, args); + FORWARD(call, (cx, proxy, args)); } bool @@ -456,7 +464,7 @@ JavaScriptParent::call(JSContext *cx, HandleObject proxy, const CallArgs &args) bool CPOWProxyHandler::objectClassIs(HandleObject proxy, js::ESClassValue classValue, JSContext *cx) { - return ParentOf(proxy)->objectClassIs(cx, proxy, classValue); + FORWARD(objectClassIs, (cx, proxy, classValue)); } bool @@ -476,7 +484,10 @@ JavaScriptParent::objectClassIs(JSContext *cx, HandleObject proxy, js::ESClassVa const char * CPOWProxyHandler::className(JSContext *cx, HandleObject proxy) { - return ParentOf(proxy)->className(cx, proxy); + JavaScriptParent *parent = ParentOf(proxy); + if (!parent->active()) + return ""; + return parent->className(cx, proxy); } const char * @@ -486,7 +497,7 @@ JavaScriptParent::className(JSContext *cx, HandleObject proxy) nsString name; if (!CallClassName(objId, &name)) - return nullptr; + return ""; return ToNewCString(name); } @@ -634,10 +645,9 @@ JavaScriptParent::incref() } void -JavaScriptParent::destroyFromContent() +JavaScriptParent::ActorDestroy(ActorDestroyReason why) { inactive_ = true; - decref(); } /* static */ bool @@ -647,9 +657,12 @@ JavaScriptParent::IsCPOW(JSObject *obj) } /* static */ nsresult -JavaScriptParent::InstanceOf(JSObject *obj, const nsID *id, bool *bp) +JavaScriptParent::InstanceOf(JSObject *proxy, const nsID *id, bool *bp) { - return ParentOf(obj)->instanceOf(obj, id, bp); + JavaScriptParent *parent = ParentOf(proxy); + if (!parent->active()) + return NS_ERROR_UNEXPECTED; + return parent->instanceOf(proxy, id, bp); } nsresult @@ -671,24 +684,21 @@ JavaScriptParent::instanceOf(JSObject *obj, const nsID *id, bool *bp) } /* static */ bool -JavaScriptParent::DOMInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp) +JavaScriptParent::DOMInstanceOf(JSContext *cx, JSObject *proxy, int prototypeID, int depth, bool *bp) { - return ParentOf(obj)->domInstanceOf(obj, prototypeID, depth, bp); + FORWARD(domInstanceOf, (cx, proxy, prototypeID, depth, bp)); } bool -JavaScriptParent::domInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp) +JavaScriptParent::domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp) { ObjectId objId = idOf(obj); ReturnStatus status; if (!CallDOMInstanceOf(objId, prototypeID, depth, &status, bp)) - return false; + return ipcfail(cx); - if (status.type() != ReturnStatus::TReturnSuccess) - return false; - - return true; + return ok(cx, status); } mozilla::ipc::IProtocol* diff --git a/js/ipc/JavaScriptParent.h b/js/ipc/JavaScriptParent.h index 6bc60e5db480..06d1a2403042 100644 --- a/js/ipc/JavaScriptParent.h +++ b/js/ipc/JavaScriptParent.h @@ -59,9 +59,12 @@ class JavaScriptParent bool objectClassIs(JSContext *cx, JS::HandleObject obj, js::ESClassValue classValue); const char* className(JSContext *cx, JS::HandleObject proxy); + virtual void ActorDestroy(ActorDestroyReason why); + void decref(); void incref(); - void destroyFromContent(); + + bool active() { return !inactive_; } void drop(JSObject *obj); @@ -74,8 +77,8 @@ class JavaScriptParent * Check that |obj| is a DOM wrapper whose prototype chain contains * |prototypeID| at depth |depth|. */ - static bool DOMInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp); - bool domInstanceOf(JSObject *obj, int prototypeID, int depth, bool *bp); + static bool DOMInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp); + bool domInstanceOf(JSContext *cx, JSObject *obj, int prototypeID, int depth, bool *bp); mozilla::ipc::IProtocol* CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx) MOZ_OVERRIDE;