diff --git a/.eslintignore b/.eslintignore index dc848d0650c1..e0be1073894c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -135,7 +135,6 @@ intl/l10n/ # Exclude everything but self-hosted JS js/ductwork/ js/examples/ -js/ipc/ js/public/ js/xpconnect/ js/src/devtools/ diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 7d80380106c3..6ff75a36c31f 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -68,7 +68,6 @@ #include "mozilla/dom/WorkerScope.h" #include "mozilla/dom/XrayExpandoClass.h" #include "mozilla/dom/WindowProxyHolder.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "ipc/ErrorIPCUtils.h" #include "mozilla/UseCounter.h" #include "mozilla/dom/DocGroup.h" @@ -2387,16 +2386,6 @@ bool InterfaceHasInstance(JSContext* cx, unsigned argc, JS::Value* vp) { return true; } - if (jsipc::IsWrappedCPOW(instance)) { - bool boolp = false; - if (!jsipc::DOMInstanceOf(cx, js::UncheckedUnwrap(instance), - clasp->mPrototypeID, clasp->mDepth, &boolp)) { - return false; - } - args.rval().setBoolean(boolp); - return true; - } - if (IsRemoteObjectProxy(instance, clasp->mPrototypeID)) { args.rval().setBoolean(true); return true; diff --git a/dom/ipc/CPOWManagerGetter.h b/dom/ipc/CPOWManagerGetter.h deleted file mode 100644 index 594cf0335173..000000000000 --- a/dom/ipc/CPOWManagerGetter.h +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_CPOWManagerGetter_h -#define mozilla_dom_CPOWManagerGetter_h - -namespace mozilla { - -namespace jsipc { -class CPOWManager; -} /* namespace jsipc */ - -namespace dom { - -class CPOWManagerGetter { - public: - virtual mozilla::jsipc::CPOWManager* GetCPOWManager() = 0; -}; - -} /* namespace dom */ -} /* namespace mozilla */ - -#endif /* mozilla_dom_CPOWManagerGetter_h */ diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 7f3314a63f56..0545cabe1a32 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -81,8 +81,6 @@ #include "mozilla/ipc/PParentToChildStreamChild.h" #include "mozilla/intl/LocaleService.h" #include "mozilla/ipc/TestShellChild.h" -// Needed for NewJavaScriptChild and ReleaseJavaScriptChild -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/layers/APZChild.h" #include "mozilla/layers/CompositorManagerChild.h" #include "mozilla/layers/ContentProcessController.h" @@ -1301,9 +1299,6 @@ void ContentChild::InitXPCOM( RecvBidiKeyboardNotify(aXPCOMInit.isLangRTL(), aXPCOMInit.haveBidiKeyboards()); - // Create the CPOW manager as soon as possible. - SendPJavaScriptConstructor(); - if (aXPCOMInit.domainPolicy().active()) { nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); MOZ_ASSERT(ssm); @@ -1691,17 +1686,6 @@ static void FirstIdle(void) { ContentChild::GetSingleton()->SendFirstIdle(); } -mozilla::jsipc::PJavaScriptChild* ContentChild::AllocPJavaScriptChild() { - MOZ_ASSERT(ManagedPJavaScriptChild().IsEmpty()); - - return jsipc::NewJavaScriptChild(); -} - -bool ContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild) { - jsipc::ReleaseJavaScriptChild(aChild); - return true; -} - mozilla::ipc::IPCResult ContentChild::RecvConstructBrowser( ManagedEndpoint&& aBrowserEp, ManagedEndpoint&& aWindowEp, const TabId& aTabId, @@ -3509,7 +3493,6 @@ mozilla::ipc::IPCResult ContentChild::RecvSessionStorageData( return IPC_OK(); } - mozilla::ipc::IPCResult ContentChild::RecvOnAllowAccessFor( const MaybeDiscarded& aContext, const nsCString& aTrackingOrigin, uint32_t aCookieBehavior, diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index d7704bfdbb3a..2f65b908370c 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -289,10 +289,6 @@ class ContentChild final : public PContentChild, mozilla::ipc::IPCResult RecvClearImageCache(const bool& privateLoader, const bool& chrome); - mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild(); - - bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*); - PRemoteSpellcheckEngineChild* AllocPRemoteSpellcheckEngineChild(); bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*); @@ -794,7 +790,7 @@ class ContentChild final : public PContentChild, mozilla::ipc::IPCResult RecvHistoryCommitLength( const MaybeDiscarded& aContext, uint32_t aLength); -private: + private: #ifdef NIGHTLY_BUILD virtual PContentChild::Result OnMessageReceived(const Message& aMsg) override; #else diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 61581d1921b8..efe822cb1224 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -137,8 +137,6 @@ #include "mozilla/ipc/IPCStreamUtils.h" #include "mozilla/ipc/PChildToParentStreamParent.h" #include "mozilla/ipc/TestShellParent.h" -// Needed for NewJavaScriptChild and ReleaseJavaScriptChild -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/layers/LayerTreeOwnerTracker.h" @@ -3127,16 +3125,6 @@ mozilla::ipc::IPCResult ContentParent::RecvInitBackground( return IPC_OK(); } -mozilla::jsipc::PJavaScriptParent* ContentParent::AllocPJavaScriptParent() { - MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty()); - return jsipc::NewJavaScriptParent(); -} - -bool ContentParent::DeallocPJavaScriptParent(PJavaScriptParent* parent) { - jsipc::ReleaseJavaScriptParent(parent); - return true; -} - bool ContentParent::CanOpenBrowser(const IPCTabContext& aContext) { // (PopupIPCTabContext lets the child process prove that it has access to // the app it's trying to open.) @@ -6380,7 +6368,7 @@ mozilla::ipc::IPCResult ContentParent::RecvHistoryGo( HistoryGoResolver&& aResolveRequestedIndex) { if (!aContext.IsDiscarded()) { nsSHistory* shistory = - static_cast(aContext.get_canonical()->GetSessionHistory()); + static_cast(aContext.get_canonical()->GetSessionHistory()); nsTArray loadResults; nsresult rv = shistory->GotoIndex(aOffset, loadResults); if (NS_FAILED(rv)) { diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 1b0da2550c32..ab9d58fc80f2 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -101,10 +101,6 @@ class ProtocolFuzzerHelper; class SharedPreferenceSerializer; } // namespace ipc -namespace jsipc { -class PJavaScriptParent; -} // namespace jsipc - namespace layers { struct TextureFactoryIdentifier; } // namespace layers @@ -461,13 +457,6 @@ class ContentParent final PHeapSnapshotTempFileHelperParent* AllocPHeapSnapshotTempFileHelperParent(); - PJavaScriptParent* AllocPJavaScriptParent(); - - virtual mozilla::ipc::IPCResult RecvPJavaScriptConstructor( - PJavaScriptParent* aActor) override { - return PContentParent::RecvPJavaScriptConstructor(aActor); - } - PRemoteSpellcheckEngineParent* AllocPRemoteSpellcheckEngineParent(); mozilla::ipc::IPCResult RecvRecordingDeviceEvents( @@ -875,8 +864,6 @@ class ContentParent final mozilla::ipc::IPCResult RecvAddPerformanceMetrics( const nsID& aID, nsTArray&& aMetrics); - bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*); - bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*); mozilla::ipc::IPCResult RecvConstructPopupBrowser( diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index 49e8d8a77782..fb751b87824d 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -24,7 +24,6 @@ include protocol PBrowserBridge; include DOMTypes; include IPCBlob; include IPCStream; -include JavaScriptTypes; include URIParams; include PPrintingTypes; include PTabContext; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index a4fffdf277a1..1115c2057e6d 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -33,7 +33,6 @@ include protocol POfflineCacheUpdate; include protocol PSpeechSynthesis; #endif include protocol PTestShell; -include protocol PJavaScript; include protocol PRemoteSpellcheckEngine; include protocol PWebBrowserPersistDocument; include protocol PWebrtcGlobal; @@ -48,7 +47,6 @@ include protocol PScriptCache; include protocol PSessionStorageObserver; include protocol PBenchmarkStorage; include DOMTypes; -include JavaScriptTypes; include IPCBlob; include IPCStream; include PTabContext; @@ -392,7 +390,6 @@ nested(upto inside_cpow) sync protocol PContent manages PSpeechSynthesis; #endif manages PTestShell; - manages PJavaScript; manages PRemoteSpellcheckEngine; manages PWebBrowserPersistDocument; manages PWebrtcGlobal; @@ -923,8 +920,6 @@ parent: sync LaunchRDDProcess() returns (nsresult rv, Endpoint aEndpoint); - async PJavaScript(); - async PRemoteSpellcheckEngine(); async InitCrashReporter(NativeThreadId tid); diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 0aebb760c5ad..023bf989f486 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -50,7 +50,6 @@ EXPORTS.mozilla.dom += [ 'ContentParent.h', 'ContentProcess.h', 'ContentProcessManager.h', - 'CPOWManagerGetter.h', 'CSPMessageUtils.h', 'DocShellMessageUtils.h', 'EffectsInfo.h', diff --git a/ipc/ipdl/ipdl/direct_call.py b/ipc/ipdl/ipdl/direct_call.py index 768edb1d8a35..37aaa092d004 100644 --- a/ipc/ipdl/ipdl/direct_call.py +++ b/ipc/ipdl/ipdl/direct_call.py @@ -438,8 +438,6 @@ DIRECT_CALL_OVERRIDES = { # set() of (Protocol, side) VIRTUAL_CALL_CLASSES = set([ # Defined as a strange template - ("PJavaScript", "child"), - ("PJavaScript", "parent"), ("PMedia", "parent"), ("PTexture", "parent"), diff --git a/ipc/ipdl/sync-messages.ini b/ipc/ipdl/sync-messages.ini index bc1a4395a01a..88ad49d169e8 100644 --- a/ipc/ipdl/sync-messages.ini +++ b/ipc/ipdl/sync-messages.ini @@ -614,48 +614,6 @@ platform = win description = Legacy a11y IPC platform = win -# CPOWs -[PJavaScript::PreventExtensions] -description = CPOW Implementation -[PJavaScript::GetOwnPropertyDescriptor] -description = CPOW Implementation -[PJavaScript::DefineProperty] -description = CPOW Implementation -[PJavaScript::Delete] -description = CPOW Implementation -[PJavaScript::Has] -description = CPOW Implementation -[PJavaScript::HasOwn] -description = CPOW Implementation -[PJavaScript::Get] -description = CPOW Implementation -[PJavaScript::Set] -description = CPOW Implementation -[PJavaScript::IsExtensible] -description = CPOW Implementation -[PJavaScript::CallOrConstruct] -description = CPOW Implementation -[PJavaScript::HasInstance] -description = CPOW Implementation -[PJavaScript::GetBuiltinClass] -description = CPOW Implementation -[PJavaScript::IsArray] -description = CPOW Implementation -[PJavaScript::ClassName] -description = CPOW Implementation -[PJavaScript::GetPrototype] -description = CPOW Implementation -[PJavaScript::GetPrototypeIfOrdinary] -description = CPOW Implementation -[PJavaScript::RegExpToShared] -description = CPOW Implementation -[PJavaScript::GetPropertyKeys] -description = CPOW Implementation -[PJavaScript::InstanceOf] -description = CPOW Implementation -[PJavaScript::DOMInstanceOf] -description = CPOW Implementation - # Plugins [PPluginWidget::Create] description = Legacy NPAPI IPC diff --git a/js/ipc/CpowHolder.h b/js/ipc/CpowHolder.h deleted file mode 100644 index 8e98f753430e..000000000000 --- a/js/ipc/CpowHolder.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_CpowHolder_h__ -#define mozilla_jsipc_CpowHolder_h__ - -#include "js/TypeDecls.h" - -namespace mozilla { -namespace jsipc { - -class CpowHolder { - public: - virtual bool ToObject(JSContext* cx, JS::MutableHandle objp) = 0; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif // mozilla_jsipc_CpowHolder_h__ diff --git a/js/ipc/CrossProcessObjectWrappers.h b/js/ipc/CrossProcessObjectWrappers.h deleted file mode 100644 index 9d4a5dfae327..000000000000 --- a/js/ipc/CrossProcessObjectWrappers.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_CrossProcessObjectWrappers_h__ -#define mozilla_jsipc_CrossProcessObjectWrappers_h__ - -#include "js/TypeDecls.h" -#include "mozilla/jsipc/CpowHolder.h" -#include "mozilla/jsipc/JavaScriptTypes.h" -#include "nsID.h" -#include "nsString.h" -#include "nsTArray.h" - -#ifdef XP_WIN -# undef GetClassName -# undef GetClassInfo -#endif - -namespace mozilla { - -namespace dom { -class CPOWManagerGetter; -} // namespace dom - -namespace jsipc { - -class PJavaScriptParent; -class PJavaScriptChild; - -class CPOWManager { - public: - virtual bool Unwrap(JSContext* cx, const nsTArray& aCpows, - JS::MutableHandleObject objp) = 0; - - virtual bool Wrap(JSContext* cx, JS::HandleObject aObj, - nsTArray* outCpows) = 0; -}; - -class CrossProcessCpowHolder : public CpowHolder { - public: - CrossProcessCpowHolder(dom::CPOWManagerGetter* managerGetter, - const nsTArray& cpows); - - ~CrossProcessCpowHolder(); - - bool ToObject(JSContext* cx, JS::MutableHandleObject objp) override; - - private: - CPOWManager* js_; - const nsTArray& cpows_; - bool unwrapped_; -}; - -CPOWManager* CPOWManagerFor(PJavaScriptParent* aParent); - -CPOWManager* CPOWManagerFor(PJavaScriptChild* aChild); - -bool IsCPOW(JSObject* obj); - -bool IsWrappedCPOW(JSObject* obj); - -nsresult InstanceOf(JSObject* obj, const nsID* id, bool* bp); - -bool DOMInstanceOf(JSContext* cx, JSObject* obj, int prototypeID, int depth, - bool* bp); - -PJavaScriptParent* NewJavaScriptParent(); - -void ReleaseJavaScriptParent(PJavaScriptParent* parent); - -PJavaScriptChild* NewJavaScriptChild(); - -void ReleaseJavaScriptChild(PJavaScriptChild* child); - -void AfterProcessTask(); - -} // namespace jsipc -} // namespace mozilla - -#endif // mozilla_jsipc_CrossProcessObjectWrappers_h__ diff --git a/js/ipc/JavaScriptBase.h b/js/ipc/JavaScriptBase.h deleted file mode 100644 index 27578bd05918..000000000000 --- a/js/ipc/JavaScriptBase.h +++ /dev/null @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_JavaScriptBase_h__ -#define mozilla_jsipc_JavaScriptBase_h__ - -#include "WrapperAnswer.h" -#include "WrapperOwner.h" -#include "mozilla/dom/DOMTypes.h" -#include "mozilla/jsipc/PJavaScript.h" - -namespace mozilla { -namespace jsipc { - -template -class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base { - using Answer = WrapperAnswer; - - public: - virtual ~JavaScriptBase() = default; - - virtual void ActorDestroy(WrapperOwner::ActorDestroyReason why) override { - WrapperOwner::ActorDestroy(why); - } - - /*** IPC handlers ***/ - - mozilla::ipc::IPCResult RecvPreventExtensions(const uint64_t& objId, - ReturnStatus* rs) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvPreventExtensions(obj.value(), rs)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvGetOwnPropertyDescriptor( - const uint64_t& objId, const JSIDVariant& id, ReturnStatus* rs, - PPropertyDescriptor* out) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvGetOwnPropertyDescriptor(obj.value(), id, rs, out)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvDefineProperty(const uint64_t& objId, - const JSIDVariant& id, - const PPropertyDescriptor& flags, - ReturnStatus* rs) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvDefineProperty(obj.value(), id, flags, rs)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvDelete(const uint64_t& objId, - const JSIDVariant& id, - ReturnStatus* rs) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvDelete(obj.value(), id, rs)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - mozilla::ipc::IPCResult RecvHas(const uint64_t& objId, const JSIDVariant& id, - ReturnStatus* rs, bool* bp) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvHas(obj.value(), id, rs, bp)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvHasOwn(const uint64_t& objId, - const JSIDVariant& id, ReturnStatus* rs, - bool* bp) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvHasOwn(obj.value(), id, rs, bp)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvGet(const uint64_t& objId, - const JSVariant& receiverVar, - const JSIDVariant& id, ReturnStatus* rs, - JSVariant* result) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvGet(obj.value(), receiverVar, id, rs, result)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvSet(const uint64_t& objId, const JSIDVariant& id, - const JSVariant& value, - const JSVariant& receiverVar, - ReturnStatus* rs) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvSet(obj.value(), id, value, receiverVar, rs)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - mozilla::ipc::IPCResult RecvIsExtensible(const uint64_t& objId, - ReturnStatus* rs, - bool* result) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvIsExtensible(obj.value(), rs, result)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvCallOrConstruct( - const uint64_t& objId, nsTArray&& argv, const bool& construct, - ReturnStatus* rs, JSVariant* result, - nsTArray* outparams) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvCallOrConstruct(obj.value(), std::move(argv), construct, - rs, result, outparams)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvHasInstance(const uint64_t& objId, - const JSVariant& v, ReturnStatus* rs, - bool* bp) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvHasInstance(obj.value(), v, rs, bp)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvGetBuiltinClass(const uint64_t& objId, - ReturnStatus* rs, - uint32_t* classValue) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvGetBuiltinClass(obj.value(), rs, classValue)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvIsArray(const uint64_t& objId, ReturnStatus* rs, - uint32_t* answer) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvIsArray(obj.value(), rs, answer)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvClassName(const uint64_t& objId, - nsCString* result) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvClassName(obj.value(), result)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvGetPrototype( - const uint64_t& objId, ReturnStatus* rs, - ObjectOrNullVariant* result) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvGetPrototype(obj.value(), rs, result)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvGetPrototypeIfOrdinary( - const uint64_t& objId, ReturnStatus* rs, bool* isOrdinary, - ObjectOrNullVariant* result) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvGetPrototypeIfOrdinary( - obj.value(), rs, isOrdinary, result)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvRegExpToShared(const uint64_t& objId, - ReturnStatus* rs, nsString* source, - uint32_t* flags) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvRegExpToShared(obj.value(), rs, source, flags)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - mozilla::ipc::IPCResult RecvGetPropertyKeys( - const uint64_t& objId, const uint32_t& flags, ReturnStatus* rs, - nsTArray* ids) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvGetPropertyKeys(obj.value(), flags, rs, ids)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvInstanceOf(const uint64_t& objId, - const JSIID& iid, ReturnStatus* rs, - bool* instanceof) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvInstanceOf(obj.value(), iid, rs, instanceof)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - mozilla::ipc::IPCResult RecvDOMInstanceOf(const uint64_t& objId, - const int& prototypeID, - const int& depth, ReturnStatus* rs, - bool* instanceof) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || - !Answer::RecvDOMInstanceOf(obj.value(), prototypeID, depth, rs, - instanceof)) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - mozilla::ipc::IPCResult RecvDropObject(const uint64_t& objId) override { - Maybe obj(ObjectId::deserialize(objId)); - if (obj.isNothing() || !Answer::RecvDropObject(obj.value())) { - return IPC_FAIL_NO_REASON(this); - } - return IPC_OK(); - } - - /*** Dummy call handlers ***/ - - bool SendDropObject(const ObjectId& objId) override { - return Base::SendDropObject(objId.serialize()); - } - bool SendPreventExtensions(const ObjectId& objId, ReturnStatus* rs) override { - return Base::SendPreventExtensions(objId.serialize(), rs); - } - bool SendGetOwnPropertyDescriptor(const ObjectId& objId, - const JSIDVariant& id, ReturnStatus* rs, - PPropertyDescriptor* out) override { - return Base::SendGetOwnPropertyDescriptor(objId.serialize(), id, rs, out); - } - bool SendDefineProperty(const ObjectId& objId, const JSIDVariant& id, - const PPropertyDescriptor& flags, - ReturnStatus* rs) override { - return Base::SendDefineProperty(objId.serialize(), id, flags, rs); - } - bool SendDelete(const ObjectId& objId, const JSIDVariant& id, - ReturnStatus* rs) override { - return Base::SendDelete(objId.serialize(), id, rs); - } - - bool SendHas(const ObjectId& objId, const JSIDVariant& id, ReturnStatus* rs, - bool* bp) override { - return Base::SendHas(objId.serialize(), id, rs, bp); - } - bool SendHasOwn(const ObjectId& objId, const JSIDVariant& id, - ReturnStatus* rs, bool* bp) override { - return Base::SendHasOwn(objId.serialize(), id, rs, bp); - } - bool SendGet(const ObjectId& objId, const JSVariant& receiverVar, - const JSIDVariant& id, ReturnStatus* rs, - JSVariant* result) override { - 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) override { - return Base::SendSet(objId.serialize(), id, value, receiverVar, rs); - } - - bool SendIsExtensible(const ObjectId& objId, ReturnStatus* rs, - bool* result) override { - return Base::SendIsExtensible(objId.serialize(), rs, result); - } - bool SendCallOrConstruct(const ObjectId& objId, const nsTArray& argv, - const bool& construct, ReturnStatus* rs, - JSVariant* result, - nsTArray* outparams) override { - return Base::SendCallOrConstruct(objId.serialize(), argv, construct, rs, - result, outparams); - } - bool SendHasInstance(const ObjectId& objId, const JSVariant& v, - ReturnStatus* rs, bool* bp) override { - return Base::SendHasInstance(objId.serialize(), v, rs, bp); - } - bool SendGetBuiltinClass(const ObjectId& objId, ReturnStatus* rs, - uint32_t* classValue) override { - return Base::SendGetBuiltinClass(objId.serialize(), rs, classValue); - } - bool SendIsArray(const ObjectId& objId, ReturnStatus* rs, - uint32_t* answer) override { - return Base::SendIsArray(objId.serialize(), rs, answer); - } - bool SendClassName(const ObjectId& objId, nsCString* result) override { - return Base::SendClassName(objId.serialize(), result); - } - bool SendGetPrototype(const ObjectId& objId, ReturnStatus* rs, - ObjectOrNullVariant* result) override { - return Base::SendGetPrototype(objId.serialize(), rs, result); - } - bool SendGetPrototypeIfOrdinary(const ObjectId& objId, ReturnStatus* rs, - bool* isOrdinary, - ObjectOrNullVariant* result) override { - return Base::SendGetPrototypeIfOrdinary(objId.serialize(), rs, isOrdinary, - result); - } - - bool SendRegExpToShared(const ObjectId& objId, ReturnStatus* rs, - nsString* source, uint32_t* flags) override { - return Base::SendRegExpToShared(objId.serialize(), rs, source, flags); - } - - bool SendGetPropertyKeys(const ObjectId& objId, const uint32_t& flags, - ReturnStatus* rs, - nsTArray* ids) override { - return Base::SendGetPropertyKeys(objId.serialize(), flags, rs, ids); - } - bool SendInstanceOf(const ObjectId& objId, const JSIID& iid, ReturnStatus* rs, - bool* instanceof) override { - return Base::SendInstanceOf(objId.serialize(), iid, rs, instanceof); - } - bool SendDOMInstanceOf(const ObjectId& objId, const int& prototypeID, - const int& depth, ReturnStatus* rs, - bool* instanceof) override { - return Base::SendDOMInstanceOf(objId.serialize(), prototypeID, depth, rs, - instanceof); - } - - /* The following code is needed to suppress a bogus MSVC warning (C4250). */ - - virtual bool toObjectVariant(JSContext* cx, JSObject* obj, - ObjectVariant* objVarp) override { - return WrapperOwner::toObjectVariant(cx, obj, objVarp); - } - virtual JSObject* fromObjectVariant(JSContext* cx, - const ObjectVariant& objVar) override { - return WrapperOwner::fromObjectVariant(cx, objVar); - } -}; - -} // namespace jsipc -} // namespace mozilla - -#endif diff --git a/js/ipc/JavaScriptChild.cpp b/js/ipc/JavaScriptChild.cpp deleted file mode 100644 index 0712e9089df5..000000000000 --- a/js/ipc/JavaScriptChild.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "JavaScriptChild.h" -#include "mozilla/dom/BindingUtils.h" -#include "mozilla/ipc/MessageChannel.h" -#include "nsContentUtils.h" -#include "xpcprivate.h" -#include "jsfriendapi.h" -#include "AccessCheck.h" - -using namespace JS; -using namespace mozilla; -using namespace mozilla::jsipc; - -using mozilla::AutoSafeJSContext; - -static void UpdateChildWeakPointersBeforeSweepingZoneGroup(JSContext* cx, - void* data) { - static_cast(data)->updateWeakPointers(); -} - -static void TraceChild(JSTracer* trc, void* data) { - static_cast(data)->trace(trc); -} - -JavaScriptChild::~JavaScriptChild() { - JSContext* cx = dom::danger::GetJSContext(); - JS_RemoveWeakPointerZonesCallback( - cx, UpdateChildWeakPointersBeforeSweepingZoneGroup); - JS_RemoveExtraGCRootsTracer(cx, TraceChild, this); -} - -bool JavaScriptChild::init() { - JSContext* cx = dom::danger::GetJSContext(); - JS_AddWeakPointerZonesCallback( - cx, UpdateChildWeakPointersBeforeSweepingZoneGroup, this); - JS_AddExtraGCRootsTracer(cx, TraceChild, this); - return true; -} - -void JavaScriptChild::trace(JSTracer* trc) { - objects_.trace(trc, strongReferenceObjIdMinimum_); -} - -void JavaScriptChild::updateWeakPointers() { - objects_.sweep(); - unwaivedObjectIds_.sweep(); - waivedObjectIds_.sweep(); -} - -JSObject* JavaScriptChild::scopeForTargetObjects() { - // CPOWs from the parent need to point into the child's privileged junk - // scope so that they can benefit from XrayWrappers in the child. - return xpc::PrivilegedJunkScope(); -} - -mozilla::ipc::IPCResult JavaScriptChild::RecvDropTemporaryStrongReferences( - const uint64_t& upToObjId) { - strongReferenceObjIdMinimum_ = upToObjId + 1; - return IPC_OK(); -} - -PJavaScriptChild* mozilla::jsipc::NewJavaScriptChild() { - JavaScriptChild* child = new JavaScriptChild(); - if (!child->init()) { - delete child; - return nullptr; - } - return child; -} - -void mozilla::jsipc::ReleaseJavaScriptChild(PJavaScriptChild* child) { - static_cast(child)->decref(); -} diff --git a/js/ipc/JavaScriptChild.h b/js/ipc/JavaScriptChild.h deleted file mode 100644 index f13e40b00668..000000000000 --- a/js/ipc/JavaScriptChild.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_JavaScriptChild_h_ -#define mozilla_jsipc_JavaScriptChild_h_ - -#include "JavaScriptBase.h" -#include "mozilla/jsipc/PJavaScriptChild.h" - -namespace mozilla { -namespace jsipc { - -class JavaScriptChild : public JavaScriptBase { - public: - JavaScriptChild() : strongReferenceObjIdMinimum_(0) {} - virtual ~JavaScriptChild(); - - bool init(); - void trace(JSTracer* trc); - void updateWeakPointers(); - - void drop(JSObject* obj); - - bool allowMessage(JSContext* cx) override { return true; } - - protected: - virtual bool isParent() override { return false; } - virtual JSObject* scopeForTargetObjects() override; - - mozilla::ipc::IPCResult RecvDropTemporaryStrongReferences( - const uint64_t& upToObjId) override; - - private: - bool fail(JSContext* cx, ReturnStatus* rs); - bool ok(ReturnStatus* rs); - - // JavaScriptChild will keep strong references to JS objects that are - // referenced by the parent only if their ID is >= - // strongReferenceObjIdMinimum_. - uint64_t strongReferenceObjIdMinimum_; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif diff --git a/js/ipc/JavaScriptLogging.h b/js/ipc/JavaScriptLogging.h deleted file mode 100644 index 07cec89dd974..000000000000 --- a/js/ipc/JavaScriptLogging.h +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_JavaScriptLogging__ -#define mozilla_jsipc_JavaScriptLogging__ - -#include "nsString.h" -#include "nsPrintfCString.h" -#include "jsfriendapi.h" -#include "js/Wrapper.h" - -namespace mozilla { -namespace jsipc { - -#define LOG(...) \ - PR_BEGIN_MACRO \ - if (LoggingEnabled()) { \ - Logging log(this, cx); \ - log.print(__VA_ARGS__); \ - } \ - PR_END_MACRO - -#define LOG_STACK() \ - PR_BEGIN_MACRO \ - if (StackLoggingEnabled()) { \ - js::DumpBacktrace(cx); \ - } \ - PR_END_MACRO - -struct ReceiverObj { - ObjectId id; - explicit ReceiverObj(ObjectId id) : id(id) {} -}; - -struct InVariant { - JSVariant variant; - explicit InVariant(const JSVariant& variant) : variant(variant) {} -}; - -struct OutVariant { - JSVariant variant; - explicit OutVariant(const JSVariant& variant) : variant(variant) {} -}; - -struct Identifier { - JSIDVariant variant; - explicit Identifier(const JSIDVariant& variant) : variant(variant) {} -}; - -class Logging { - public: - Logging(JavaScriptShared* shared, JSContext* cx) : shared(shared), cx(cx) {} - - void print(const nsCString& str) { - const char* side = shared->isParent() ? "from child" : "from parent"; - printf("CPOW %s: %s\n", side, str.get()); - } - - void print(const char* str) { print(nsCString(str)); } - template - void print(const char* fmt, const T1& a1) { - nsAutoCString tmp1; - format(a1, tmp1); - print(nsPrintfCString(fmt, tmp1.get())); - } - template - void print(const char* fmt, const T1& a1, const T2& a2) { - nsAutoCString tmp1; - nsAutoCString tmp2; - format(a1, tmp1); - format(a2, tmp2); - print(nsPrintfCString(fmt, tmp1.get(), tmp2.get())); - } - template - void print(const char* fmt, const T1& a1, const T2& a2, const T3& a3) { - nsAutoCString tmp1; - nsAutoCString tmp2; - nsAutoCString tmp3; - format(a1, tmp1); - format(a2, tmp2); - format(a3, tmp3); - print(nsPrintfCString(fmt, tmp1.get(), tmp2.get(), tmp3.get())); - } - - void format(const nsString& str, nsCString& out) { - out = NS_ConvertUTF16toUTF8(str); - } - - void formatObject(bool incoming, bool local, ObjectId id, nsCString& out) { - const char* side; - const char* objDesc; - void* ptr; - - if (local == incoming) { - JS::RootedObject obj(cx); - obj = shared->objects_.find(id); - obj = js::UncheckedUnwrap(obj, true); - - JSAutoRealm ar(cx, obj); - objDesc = js::ObjectClassName(cx, obj); - side = shared->isParent() ? "parent" : "child"; - ptr = obj; - } else { - objDesc = ""; - side = shared->isParent() ? "child" : "parent"; - ptr = nullptr; - } - - out = nsPrintfCString("<%s %s:%" PRIu64 ":%p>", side, objDesc, - id.serialNumber(), ptr); - } - - void format(const ReceiverObj& obj, nsCString& out) { - formatObject(true, true, obj.id, out); - } - - void format(const nsTArray& values, nsCString& out) { - nsAutoCString tmp; - out.Truncate(); - for (size_t i = 0; i < values.Length(); i++) { - if (i) { - out.AppendLiteral(", "); - } - if (values[i].type() == JSParam::Tvoid_t) { - out.AppendLiteral(""); - } else { - format(InVariant(values[i].get_JSVariant()), tmp); - out += tmp; - } - } - } - - void format(const InVariant& value, nsCString& out) { - format(true, value.variant, out); - } - - void format(const OutVariant& value, nsCString& out) { - format(false, value.variant, out); - } - - void format(bool incoming, const JSVariant& value, nsCString& out) { - switch (value.type()) { - case JSVariant::TUndefinedVariant: { - out = "undefined"; - break; - } - case JSVariant::TNullVariant: { - out = "null"; - break; - } - case JSVariant::TnsString: { - nsAutoCString tmp; - format(value.get_nsString(), tmp); - out = nsPrintfCString("\"%s\"", tmp.get()); - break; - } - case JSVariant::TObjectVariant: { - const ObjectVariant& ovar = value.get_ObjectVariant(); - if (ovar.type() == ObjectVariant::TLocalObject) { - Maybe objId( - ObjectId::deserialize(ovar.get_LocalObject().serializedId())); - MOZ_RELEASE_ASSERT(objId.isSome()); - formatObject(incoming, true, objId.value(), out); - } else { - Maybe objId( - ObjectId::deserialize(ovar.get_RemoteObject().serializedId())); - MOZ_RELEASE_ASSERT(objId.isSome()); - formatObject(incoming, false, objId.value(), out); - } - break; - } - case JSVariant::TSymbolVariant: { - out = ""; - break; - } - case JSVariant::Tdouble: { - out = nsPrintfCString("%.0f", value.get_double()); - break; - } - case JSVariant::Tbool: { - out = value.get_bool() ? "true" : "false"; - break; - } - case JSVariant::TJSIID: { - out = ""; - break; - } - default: { - out = ""; - break; - } - } - } - - void format(const Identifier& id, nsCString& out) { - switch (id.variant.type()) { - case JSIDVariant::TSymbolVariant: { - out = ""; - break; - } - case JSIDVariant::TnsString: { - nsAutoCString tmp; - format(id.variant.get_nsString(), tmp); - out = nsPrintfCString("\"%s\"", tmp.get()); - break; - } - case JSIDVariant::Tint32_t: { - out = nsPrintfCString("%d", id.variant.get_int32_t()); - break; - } - default: { - out = "Unknown"; - break; - } - } - } - - private: - JavaScriptShared* shared; - JSContext* cx; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif diff --git a/js/ipc/JavaScriptParent.cpp b/js/ipc/JavaScriptParent.cpp deleted file mode 100644 index 422999b7d3e8..000000000000 --- a/js/ipc/JavaScriptParent.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "JavaScriptParent.h" -#include "mozilla/dom/ContentParent.h" -#include "mozilla/dom/ScriptSettings.h" -#include "nsJSUtils.h" -#include "nsIConsoleService.h" -#include "nsIScriptError.h" -#include "jsfriendapi.h" -#include "js/Proxy.h" -#include "js/HeapAPI.h" -#include "js/Wrapper.h" -#include "xpcprivate.h" -#include "mozilla/Casting.h" -#include "mozilla/StaticPrefs_dom.h" -#include "mozilla/Telemetry.h" - -using namespace js; -using namespace JS; -using namespace mozilla; -using namespace mozilla::jsipc; -using namespace mozilla::dom; - -static void TraceParent(JSTracer* trc, void* data) { - static_cast(data)->trace(trc); -} - -JavaScriptParent::JavaScriptParent() : savedNextCPOWNumber_(1) { - JS_AddExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this); -} - -JavaScriptParent::~JavaScriptParent() { - JS_RemoveExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this); -} - -static bool ForbidUnsafeBrowserCPOWs() { - return StaticPrefs::dom_ipc_cpows_forbid_unsafe_from_browser(); -} - -bool JavaScriptParent::allowMessage(JSContext* cx) { - MOZ_ASSERT(cx); - - // If we're running browser code while running tests (in automation), - // then we allow all safe CPOWs and forbid unsafe CPOWs - // based on a pref (which defaults to forbidden). - // A normal (release) browser build will never allow CPOWs, - // except as a token to pass round. - - if (!xpc::IsInAutomation()) { - JS_ReportErrorASCII(cx, "CPOW usage forbidden"); - return false; - } - - MessageChannel* channel = GetIPCChannel(); - bool isSafe = channel->IsInTransaction(); - - if (isSafe) { - return true; - } - - nsIGlobalObject* global = dom::GetIncumbentGlobal(); - JS::Rooted jsGlobal( - cx, global ? global->GetGlobalJSObject() : nullptr); - if (jsGlobal) { - JSAutoRealm ar(cx, jsGlobal); - - if (ForbidUnsafeBrowserCPOWs()) { - JS_ReportErrorASCII(cx, "unsafe CPOW usage forbidden"); - return false; - } - } - - static bool disableUnsafeCPOWWarnings = - PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS"); - if (!disableUnsafeCPOWWarnings) { - nsCOMPtr console( - do_GetService(NS_CONSOLESERVICE_CONTRACTID)); - if (console) { - nsAutoString filename; - uint32_t lineno = 0, column = 0; - nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column); - nsCOMPtr error( - do_CreateInstance(NS_SCRIPTERROR_CONTRACTID)); - error->Init(NS_LITERAL_STRING("unsafe/forbidden CPOW usage"), filename, - EmptyString(), lineno, column, nsIScriptError::warningFlag, - "chrome javascript", false /* from private window */, - true /* from chrome context */); - console->LogMessage(error); - } else { - NS_WARNING("Unsafe synchronous IPC message"); - } - } - - return true; -} - -void JavaScriptParent::trace(JSTracer* trc) { - objects_.trace(trc); - unwaivedObjectIds_.trace(trc); - waivedObjectIds_.trace(trc); -} - -JSObject* JavaScriptParent::scopeForTargetObjects() { - // CPOWs from the child need to point into the parent's unprivileged junk - // scope so that a compromised child cannot compromise the parent. In - // practice, this means that a child process can only (a) hold parent - // objects alive and (b) invoke them if they are callable. - return xpc::UnprivilegedJunkScope(); -} - -void JavaScriptParent::afterProcessTask() { - if (savedNextCPOWNumber_ == nextCPOWNumber_) { - return; - } - - savedNextCPOWNumber_ = nextCPOWNumber_; - - MOZ_ASSERT(nextCPOWNumber_ > 0); - if (active()) { - Unused << SendDropTemporaryStrongReferences(nextCPOWNumber_ - 1); - } -} - -PJavaScriptParent* mozilla::jsipc::NewJavaScriptParent() { - return new JavaScriptParent(); -} - -void mozilla::jsipc::ReleaseJavaScriptParent(PJavaScriptParent* parent) { - static_cast(parent)->decref(); -} - -void mozilla::jsipc::AfterProcessTask() { - for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { - if (PJavaScriptParent* p = - LoneManagedOrNullAsserts(cp->ManagedPJavaScriptParent())) { - static_cast(p)->afterProcessTask(); - } - } -} diff --git a/js/ipc/JavaScriptParent.h b/js/ipc/JavaScriptParent.h deleted file mode 100644 index d13d39fd6381..000000000000 --- a/js/ipc/JavaScriptParent.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_JavaScriptParent__ -#define mozilla_jsipc_JavaScriptParent__ - -#include "JavaScriptBase.h" -#include "mozilla/jsipc/PJavaScriptParent.h" - -namespace mozilla { -namespace jsipc { - -class JavaScriptParent : public JavaScriptBase { - public: - JavaScriptParent(); - virtual ~JavaScriptParent(); - - void trace(JSTracer* trc); - - void drop(JSObject* obj); - - bool allowMessage(JSContext* cx) override; - void afterProcessTask(); - - protected: - virtual bool isParent() override { return true; } - virtual JSObject* scopeForTargetObjects() override; - - private: - uint64_t savedNextCPOWNumber_; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif // mozilla_jsipc_JavaScriptWrapper_h__ diff --git a/js/ipc/JavaScriptShared.cpp b/js/ipc/JavaScriptShared.cpp deleted file mode 100644 index 33bfad2862ca..000000000000 --- a/js/ipc/JavaScriptShared.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "JavaScriptShared.h" -#include "mozilla/dom/BindingUtils.h" -#include "mozilla/dom/CPOWManagerGetter.h" -#include "mozilla/dom/BrowserChild.h" -#include "jsfriendapi.h" -#include "js/Symbol.h" -#include "xpcprivate.h" -#include "WrapperFactory.h" -#include "mozilla/Preferences.h" - -using namespace js; -using namespace JS; -using namespace mozilla; -using namespace mozilla::jsipc; - -IdToObjectMap::IdToObjectMap() : table_(SystemAllocPolicy(), 32) {} - -void IdToObjectMap::trace(JSTracer* trc, uint64_t minimumId) { - for (Table::Range r(table_.all()); !r.empty(); r.popFront()) { - if (r.front().key().serialNumber() >= minimumId) { - JS::TraceEdge(trc, &r.front().value(), "ipc-object"); - } - } -} - -void IdToObjectMap::sweep() { - for (Table::Enum e(table_); !e.empty(); e.popFront()) { - JS::Heap* objp = &e.front().value(); - JS_UpdateWeakPointerAfterGC(objp); - if (!*objp) { - e.removeFront(); - } - } -} - -JSObject* IdToObjectMap::find(ObjectId id) { - Table::Ptr p = table_.lookup(id); - if (!p) { - return nullptr; - } - return p->value(); -} - -JSObject* IdToObjectMap::findPreserveColor(ObjectId id) { - Table::Ptr p = table_.lookup(id); - if (!p) { - return nullptr; - } - return p->value().unbarrieredGet(); -} - -bool IdToObjectMap::add(ObjectId id, JSObject* obj) { - return table_.put(id, obj); -} - -void IdToObjectMap::remove(ObjectId id) { table_.remove(id); } - -void IdToObjectMap::clear() { table_.clear(); } - -bool IdToObjectMap::empty() const { return table_.empty(); } - -#ifdef DEBUG -bool IdToObjectMap::has(const ObjectId& id, const JSObject* obj) const { - auto p = table_.lookup(id); - if (!p) { - return false; - } - return p->value() == obj; -} -#endif - -ObjectToIdMap::ObjectToIdMap() : table_(SystemAllocPolicy(), 32) {} - -void ObjectToIdMap::trace(JSTracer* trc) { table_.trace(trc); } - -void ObjectToIdMap::sweep() { table_.sweep(); } - -ObjectId ObjectToIdMap::find(JSObject* obj) { - Table::Ptr p = table_.lookup(obj); - if (!p) { - return ObjectId::nullId(); - } - return p->value(); -} - -bool ObjectToIdMap::add(JSContext* cx, JSObject* obj, ObjectId id) { - return table_.put(obj, id); -} - -void ObjectToIdMap::remove(JSObject* obj) { table_.remove(obj); } - -void ObjectToIdMap::clear() { table_.clear(); } - -bool JavaScriptShared::sLoggingInitialized; -bool JavaScriptShared::sLoggingEnabledByEnvVar; -bool JavaScriptShared::sStackLoggingEnabledByEnvVar; - -JavaScriptShared::JavaScriptShared() - : refcount_(1), nextSerialNumber_(1), nextCPOWNumber_(1) { - if (!sLoggingInitialized) { - sLoggingInitialized = true; - - if (PR_GetEnv("MOZ_CPOW_LOG")) { - sLoggingEnabledByEnvVar = true; - sStackLoggingEnabledByEnvVar = - !!strstr(PR_GetEnv("MOZ_CPOW_LOG"), "stacks"); - } - } -} - -JavaScriptShared::~JavaScriptShared() { MOZ_RELEASE_ASSERT(cpows_.empty()); } - -void JavaScriptShared::decref() { - refcount_--; - if (!refcount_) { - delete this; - } -} - -void JavaScriptShared::incref() { refcount_++; } - -bool JavaScriptShared::convertIdToGeckoString(JSContext* cx, JS::HandleId id, - nsString* to) { - RootedValue idval(cx); - if (!JS_IdToValue(cx, id, &idval)) { - return false; - } - - RootedString str(cx, ToString(cx, idval)); - if (!str) { - return false; - } - - return AssignJSString(cx, *to, str); -} - -bool JavaScriptShared::convertGeckoStringToId(JSContext* cx, - const nsString& from, - JS::MutableHandleId to) { - RootedString str(cx, - JS_NewUCStringCopyN(cx, from.BeginReading(), from.Length())); - if (!str) { - return false; - } - - return JS_StringToId(cx, str, to); -} - -bool JavaScriptShared::toVariant(JSContext* cx, JS::HandleValue from, - JSVariant* to) { - switch (JS_TypeOfValue(cx, from)) { - case JSTYPE_UNDEFINED: - *to = UndefinedVariant(); - return true; - - case JSTYPE_OBJECT: - case JSTYPE_FUNCTION: { - RootedObject obj(cx, from.toObjectOrNull()); - if (!obj) { - MOZ_ASSERT(from.isNull()); - *to = NullVariant(); - return true; - } - - Maybe id = xpc::JSValue2ID(cx, from); - if (id) { - JSIID iid; - ConvertID(*id, &iid); - *to = iid; - return true; - } - - ObjectVariant objVar; - if (!toObjectVariant(cx, obj, &objVar)) { - return false; - } - *to = objVar; - return true; - } - - case JSTYPE_SYMBOL: { - RootedSymbol sym(cx, from.toSymbol()); - - SymbolVariant symVar; - if (!toSymbolVariant(cx, sym, &symVar)) { - return false; - } - *to = symVar; - return true; - } - - case JSTYPE_STRING: { - nsAutoJSString autoStr; - if (!autoStr.init(cx, from)) { - return false; - } - *to = autoStr; - return true; - } - - case JSTYPE_NUMBER: - if (from.isInt32()) { - *to = double(from.toInt32()); - } else { - *to = from.toDouble(); - } - return true; - - case JSTYPE_BOOLEAN: - *to = from.toBoolean(); - return true; - - default: - MOZ_ASSERT(false); - return false; - } -} - -bool JavaScriptShared::fromVariant(JSContext* cx, const JSVariant& from, - MutableHandleValue to) { - switch (from.type()) { - case JSVariant::TUndefinedVariant: - to.set(UndefinedValue()); - return true; - - case JSVariant::TNullVariant: - to.set(NullValue()); - return true; - - case JSVariant::TObjectVariant: { - JSObject* obj = fromObjectVariant(cx, from.get_ObjectVariant()); - if (!obj) { - return false; - } - to.set(ObjectValue(*obj)); - return true; - } - - case JSVariant::TSymbolVariant: { - Symbol* sym = fromSymbolVariant(cx, from.get_SymbolVariant()); - if (!sym) { - return false; - } - to.setSymbol(sym); - return true; - } - - case JSVariant::Tdouble: - to.set(JS_NumberValue(from.get_double())); - return true; - - case JSVariant::Tbool: - to.setBoolean(from.get_bool()); - return true; - - case JSVariant::TnsString: { - const nsString& old = from.get_nsString(); - JSString* str = JS_NewUCStringCopyN(cx, old.BeginReading(), old.Length()); - if (!str) { - return false; - } - to.set(StringValue(str)); - return true; - } - - case JSVariant::TJSIID: { - nsID iid; - const JSIID& id = from.get_JSIID(); - ConvertID(id, &iid); - return xpc::ID2JSValue(cx, iid, to); - } - - default: - MOZ_CRASH("NYI"); - return false; - } -} - -bool JavaScriptShared::toJSIDVariant(JSContext* cx, HandleId from, - JSIDVariant* to) { - if (JSID_IS_STRING(from)) { - nsAutoJSString autoStr; - if (!autoStr.init(cx, JSID_TO_STRING(from))) { - return false; - } - *to = autoStr; - return true; - } - if (JSID_IS_INT(from)) { - *to = JSID_TO_INT(from); - return true; - } - if (JSID_IS_SYMBOL(from)) { - SymbolVariant symVar; - if (!toSymbolVariant(cx, JSID_TO_SYMBOL(from), &symVar)) { - return false; - } - *to = symVar; - return true; - } - MOZ_ASSERT(false); - return false; -} - -bool JavaScriptShared::fromJSIDVariant(JSContext* cx, const JSIDVariant& from, - MutableHandleId to) { - switch (from.type()) { - case JSIDVariant::TSymbolVariant: { - Symbol* sym = fromSymbolVariant(cx, from.get_SymbolVariant()); - if (!sym) { - return false; - } - to.set(SYMBOL_TO_JSID(sym)); - return true; - } - - case JSIDVariant::TnsString: - return convertGeckoStringToId(cx, from.get_nsString(), to); - - case JSIDVariant::Tint32_t: - to.set(INT_TO_JSID(from.get_int32_t())); - return true; - - default: - return false; - } -} - -bool JavaScriptShared::toSymbolVariant(JSContext* cx, JS::Symbol* symArg, - SymbolVariant* symVarp) { - RootedSymbol sym(cx, symArg); - MOZ_ASSERT(sym); - - SymbolCode code = GetSymbolCode(sym); - if (static_cast(code) < WellKnownSymbolLimit) { - *symVarp = WellKnownSymbol(static_cast(code)); - return true; - } - if (code == SymbolCode::InSymbolRegistry) { - nsAutoJSString autoStr; - if (!autoStr.init(cx, GetSymbolDescription(sym))) { - return false; - } - *symVarp = RegisteredSymbol(autoStr); - return true; - } - - JS_ReportErrorASCII(cx, "unique symbol can't be used with CPOW"); - return false; -} - -JS::Symbol* JavaScriptShared::fromSymbolVariant(JSContext* cx, - const SymbolVariant& symVar) { - switch (symVar.type()) { - case SymbolVariant::TWellKnownSymbol: { - uint32_t which = symVar.get_WellKnownSymbol().which(); - if (which < WellKnownSymbolLimit) { - return GetWellKnownSymbol(cx, static_cast(which)); - } - MOZ_ASSERT(false, "bad child data"); - return nullptr; - } - - case SymbolVariant::TRegisteredSymbol: { - nsString key = symVar.get_RegisteredSymbol().key(); - RootedString str(cx, JS_NewUCStringCopyN(cx, key.get(), key.Length())); - if (!str) { - return nullptr; - } - return GetSymbolFor(cx, str); - } - - default: - return nullptr; - } -} - -/* static */ -void JavaScriptShared::ConvertID(const nsID& from, JSIID* to) { - to->m0() = from.m0; - to->m1() = from.m1; - to->m2() = from.m2; - to->m3_0() = from.m3[0]; - to->m3_1() = from.m3[1]; - to->m3_2() = from.m3[2]; - to->m3_3() = from.m3[3]; - to->m3_4() = from.m3[4]; - to->m3_5() = from.m3[5]; - to->m3_6() = from.m3[6]; - to->m3_7() = from.m3[7]; -} - -/* static */ -void JavaScriptShared::ConvertID(const JSIID& from, nsID* to) { - to->m0 = from.m0(); - to->m1 = from.m1(); - to->m2 = from.m2(); - to->m3[0] = from.m3_0(); - to->m3[1] = from.m3_1(); - to->m3[2] = from.m3_2(); - to->m3[3] = from.m3_3(); - to->m3[4] = from.m3_4(); - to->m3[5] = from.m3_5(); - to->m3[6] = from.m3_6(); - to->m3[7] = from.m3_7(); -} - -JSObject* JavaScriptShared::findCPOWById(const ObjectId& objId) { - JSObject* obj = findCPOWByIdPreserveColor(objId); - if (obj) { - JS::ExposeObjectToActiveJS(obj); - } - return obj; -} - -JSObject* JavaScriptShared::findCPOWByIdPreserveColor(const ObjectId& objId) { - JSObject* obj = cpows_.findPreserveColor(objId); - if (!obj) { - return nullptr; - } - - if (js::gc::EdgeNeedsSweepUnbarriered(&obj)) { - cpows_.remove(objId); - return nullptr; - } - - return obj; -} - -JSObject* JavaScriptShared::findObjectById(JSContext* cx, - const ObjectId& objId) { - RootedObject obj(cx, objects_.find(objId)); - if (!obj) { - JS_ReportErrorASCII(cx, "operation not possible on dead CPOW"); - return nullptr; - } - - // Each process has a dedicated compartment for CPOW targets. All CPOWs - // from the other process point to objects in this scope. From there, they - // can access objects in other compartments using cross-compartment - // wrappers. - JSAutoRealm ar(cx, scopeForTargetObjects()); - if (objId.hasXrayWaiver()) { - obj = js::ToWindowProxyIfWindow(obj); - MOZ_ASSERT(obj); - if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, &obj)) { - return nullptr; - } - } else { - if (!JS_WrapObject(cx, &obj)) { - return nullptr; - } - } - return obj; -} - -static const uint64_t UnknownPropertyOp = 1; - -bool JavaScriptShared::fromDescriptor(JSContext* cx, - Handle desc, - PPropertyDescriptor* out) { - out->attrs() = desc.attributes(); - if (!toVariant(cx, desc.value(), &out->value())) { - return false; - } - - if (!toObjectOrNullVariant(cx, desc.object(), &out->obj())) { - return false; - } - - if (!desc.getter()) { - out->getter() = 0; - } else if (desc.hasGetterObject()) { - JSObject* getter = desc.getterObject(); - ObjectVariant objVar; - if (!toObjectVariant(cx, getter, &objVar)) { - return false; - } - out->getter() = objVar; - } else { - out->getter() = UnknownPropertyOp; - } - - if (!desc.setter()) { - out->setter() = 0; - } else if (desc.hasSetterObject()) { - JSObject* setter = desc.setterObject(); - ObjectVariant objVar; - if (!toObjectVariant(cx, setter, &objVar)) { - return false; - } - out->setter() = objVar; - } else { - out->setter() = UnknownPropertyOp; - } - - return true; -} - -bool UnknownPropertyStub(JSContext* cx, HandleObject obj, HandleId id, - MutableHandleValue vp) { - JS_ReportErrorASCII(cx, "getter could not be wrapped via CPOWs"); - return false; -} - -bool UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, - HandleValue v, ObjectOpResult& result) { - JS_ReportErrorASCII(cx, "setter could not be wrapped via CPOWs"); - return false; -} - -bool JavaScriptShared::toDescriptor(JSContext* cx, - const PPropertyDescriptor& in, - MutableHandle out) { - out.setAttributes(in.attrs()); - if (!fromVariant(cx, in.value(), out.value())) { - return false; - } - out.object().set(fromObjectOrNullVariant(cx, in.obj())); - - if (in.getter().type() == GetterSetter::Tuint64_t && - !in.getter().get_uint64_t()) { - out.setGetter(nullptr); - } else if (in.attrs() & JSPROP_GETTER) { - Rooted getter(cx); - getter = fromObjectVariant(cx, in.getter().get_ObjectVariant()); - if (!getter) { - return false; - } - out.setGetter(JS_DATA_TO_FUNC_PTR(JSGetterOp, getter.get())); - } else { - out.setGetter(UnknownPropertyStub); - } - - if (in.setter().type() == GetterSetter::Tuint64_t && - !in.setter().get_uint64_t()) { - out.setSetter(nullptr); - } else if (in.attrs() & JSPROP_SETTER) { - Rooted setter(cx); - setter = fromObjectVariant(cx, in.setter().get_ObjectVariant()); - if (!setter) { - return false; - } - out.setSetter(JS_DATA_TO_FUNC_PTR(JSSetterOp, setter.get())); - } else { - out.setSetter(UnknownStrictPropertyStub); - } - - return true; -} - -bool JavaScriptShared::toObjectOrNullVariant(JSContext* cx, JSObject* obj, - ObjectOrNullVariant* objVarp) { - if (!obj) { - *objVarp = NullVariant(); - return true; - } - - ObjectVariant objVar; - if (!toObjectVariant(cx, obj, &objVar)) { - return false; - } - - *objVarp = objVar; - return true; -} - -JSObject* JavaScriptShared::fromObjectOrNullVariant( - JSContext* cx, const ObjectOrNullVariant& objVar) { - if (objVar.type() == ObjectOrNullVariant::TNullVariant) { - return nullptr; - } - - return fromObjectVariant(cx, objVar.get_ObjectVariant()); -} - -CrossProcessCpowHolder::CrossProcessCpowHolder( - dom::CPOWManagerGetter* managerGetter, const nsTArray& cpows) - : js_(nullptr), cpows_(cpows), unwrapped_(false) { - // Only instantiate the CPOW manager if we might need it later. - if (cpows.Length()) { - js_ = managerGetter->GetCPOWManager(); - } -} - -CrossProcessCpowHolder::~CrossProcessCpowHolder() { - if (cpows_.Length() && !unwrapped_) { - // This should only happen if a message manager message - // containing CPOWs gets ignored for some reason. We need to - // unwrap every incoming CPOW in this process to ensure that - // the corresponding part of the CPOW in the other process - // will eventually be collected. The scope for this object - // doesn't really matter, because it immediately becomes - // garbage. - AutoJSAPI jsapi; - if (!jsapi.Init(xpc::PrivilegedJunkScope())) { - return; - } - JSContext* cx = jsapi.cx(); - JS::Rooted cpows(cx); - js_->Unwrap(cx, cpows_, &cpows); - } -} - -bool CrossProcessCpowHolder::ToObject(JSContext* cx, - JS::MutableHandleObject objp) { - unwrapped_ = true; - - if (!cpows_.Length()) { - return true; - } - - return js_->Unwrap(cx, cpows_, objp); -} - -bool JavaScriptShared::Unwrap(JSContext* cx, const nsTArray& aCpows, - JS::MutableHandleObject objp) { - objp.set(nullptr); - - if (!aCpows.Length()) { - return true; - } - - RootedObject obj(cx, JS_NewPlainObject(cx)); - if (!obj) { - return false; - } - - RootedValue v(cx); - RootedString str(cx); - for (size_t i = 0; i < aCpows.Length(); i++) { - const nsString& name = aCpows[i].name(); - - if (!fromVariant(cx, aCpows[i].value(), &v)) { - return false; - } - - if (!JS_DefineUCProperty(cx, obj, name.BeginReading(), name.Length(), v, - JSPROP_ENUMERATE)) { - return false; - } - } - - objp.set(obj); - return true; -} - -bool JavaScriptShared::Wrap(JSContext* cx, HandleObject aObj, - nsTArray* outCpows) { - if (!aObj) { - return true; - } - - Rooted ids(cx, IdVector(cx)); - if (!JS_Enumerate(cx, aObj, &ids)) { - return false; - } - - RootedId id(cx); - RootedValue v(cx); - for (size_t i = 0; i < ids.length(); i++) { - id = ids[i]; - - nsString str; - if (!convertIdToGeckoString(cx, id, &str)) { - return false; - } - - if (!JS_GetPropertyById(cx, aObj, id, &v)) { - return false; - } - - JSVariant var; - if (!toVariant(cx, v, &var)) { - return false; - } - - outCpows->AppendElement(CpowEntry(str, var)); - } - - return true; -} - -CPOWManager* mozilla::jsipc::CPOWManagerFor(PJavaScriptParent* aParent) { - return static_cast(aParent); -} - -CPOWManager* mozilla::jsipc::CPOWManagerFor(PJavaScriptChild* aChild) { - return static_cast(aChild); -} diff --git a/js/ipc/JavaScriptShared.h b/js/ipc/JavaScriptShared.h deleted file mode 100644 index 2fb5191b1e62..000000000000 --- a/js/ipc/JavaScriptShared.h +++ /dev/null @@ -1,255 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_JavaScriptShared_h__ -#define mozilla_jsipc_JavaScriptShared_h__ - -#include "mozilla/HashFunctions.h" -#include "mozilla/dom/DOMTypes.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" -#include "mozilla/jsipc/PJavaScript.h" -#include "mozilla/StaticPrefs_dom.h" -#include "js/GCHashTable.h" -#include "nsJSUtils.h" - -namespace mozilla { -namespace jsipc { - -class ObjectId { - public: - // Use 47 bits at most, to be safe, since jsval privates are encoded as - // doubles. See bug 1065811 comment 12 for an explanation. - static const size_t SERIAL_NUMBER_BITS = 47; - static const size_t FLAG_BITS = 1; - static const uint64_t SERIAL_NUMBER_MAX = - (uint64_t(1) << SERIAL_NUMBER_BITS) - 1; - - explicit ObjectId(uint64_t serialNumber, bool hasXrayWaiver) - : serialNumber_(serialNumber), hasXrayWaiver_(hasXrayWaiver) { - if (isInvalidSerialNumber(serialNumber)) { - MOZ_CRASH("Bad CPOW Id"); - } - } - - bool operator==(const ObjectId& other) const { - bool equal = serialNumber() == other.serialNumber(); - MOZ_ASSERT_IF(equal, hasXrayWaiver() == other.hasXrayWaiver()); - return equal; - } - - bool isNull() { return !serialNumber_; } - - uint64_t serialNumber() const { return serialNumber_; } - bool hasXrayWaiver() const { return hasXrayWaiver_; } - uint64_t serialize() const { - MOZ_ASSERT(serialNumber(), "Don't send a null ObjectId over IPC"); - return uint64_t((serialNumber() << FLAG_BITS) | - ((hasXrayWaiver() ? 1 : 0) << 0)); - } - - static ObjectId nullId() { return ObjectId(); } - static Maybe deserialize(uint64_t data) { - if (isInvalidSerialNumber(data >> FLAG_BITS)) { - return Nothing(); - } - return Some(ObjectId(data >> FLAG_BITS, data & 1)); - } - - // For use with StructGCPolicy. - void trace(JSTracer*) const {} - bool needsSweep() const { return false; } - - private: - ObjectId() : serialNumber_(0), hasXrayWaiver_(false) {} - - static bool isInvalidSerialNumber(uint64_t aSerialNumber) { - return aSerialNumber == 0 || aSerialNumber > SERIAL_NUMBER_MAX; - } - - uint64_t serialNumber_ : SERIAL_NUMBER_BITS; - bool hasXrayWaiver_ : 1; -}; - -class JavaScriptShared; - -// DefaultHasher requires that T coerce to an integral type. We could make -// ObjectId do that, but doing so would weaken our type invariants, so we just -// reimplement it manually. -struct ObjectIdHasher { - using Lookup = ObjectId; - static js::HashNumber hash(const Lookup& l) { - return mozilla::HashGeneric(l.serialize()); - } - static bool match(const ObjectId& k, const ObjectId& l) { return k == l; } - static void rekey(ObjectId& k, const ObjectId& newKey) { k = newKey; } -}; - -// Map ids -> JSObjects -class IdToObjectMap { - typedef js::HashMap, ObjectIdHasher, - js::SystemAllocPolicy> - Table; - - public: - IdToObjectMap(); - - void trace(JSTracer* trc, uint64_t minimumId = 0); - void sweep(); - - bool add(ObjectId id, JSObject* obj); - JSObject* find(ObjectId id); - JSObject* findPreserveColor(ObjectId id); - void remove(ObjectId id); - - void clear(); - bool empty() const; - -#ifdef DEBUG - bool has(const ObjectId& id, const JSObject* obj) const; -#endif - - private: - Table table_; -}; - -// Map JSObjects -> ids -class ObjectToIdMap { - using Hasher = js::MovableCellHasher>; - using Table = JS::GCHashMap, ObjectId, Hasher, - js::SystemAllocPolicy>; - - public: - ObjectToIdMap(); - - void trace(JSTracer* trc); - void sweep(); - - bool add(JSContext* cx, JSObject* obj, ObjectId id); - ObjectId find(JSObject* obj); - void remove(JSObject* obj); - void clear(); - - private: - Table table_; -}; - -class Logging; - -class JavaScriptShared : public CPOWManager { - public: - JavaScriptShared(); - virtual ~JavaScriptShared(); - - void decref(); - void incref(); - - bool Unwrap(JSContext* cx, const nsTArray& aCpows, - JS::MutableHandleObject objp) override; - bool Wrap(JSContext* cx, JS::HandleObject aObj, - nsTArray* outCpows) override; - - protected: - bool toVariant(JSContext* cx, JS::HandleValue from, JSVariant* to); - bool fromVariant(JSContext* cx, const JSVariant& from, - JS::MutableHandleValue to); - - bool toJSIDVariant(JSContext* cx, JS::HandleId from, JSIDVariant* to); - bool fromJSIDVariant(JSContext* cx, const JSIDVariant& from, - JS::MutableHandleId to); - - bool toSymbolVariant(JSContext* cx, JS::Symbol* sym, SymbolVariant* symVarp); - JS::Symbol* fromSymbolVariant(JSContext* cx, const SymbolVariant& symVar); - - bool fromDescriptor(JSContext* cx, JS::Handle desc, - PPropertyDescriptor* out); - bool toDescriptor(JSContext* cx, const PPropertyDescriptor& in, - JS::MutableHandle out); - - bool toObjectOrNullVariant(JSContext* cx, JSObject* obj, - ObjectOrNullVariant* objVarp); - JSObject* fromObjectOrNullVariant(JSContext* cx, - const ObjectOrNullVariant& objVar); - - bool convertIdToGeckoString(JSContext* cx, JS::HandleId id, nsString* to); - bool convertGeckoStringToId(JSContext* cx, const nsString& from, - JS::MutableHandleId id); - - virtual bool toObjectVariant(JSContext* cx, JSObject* obj, - ObjectVariant* objVarp) = 0; - virtual JSObject* fromObjectVariant(JSContext* cx, - const ObjectVariant& objVar) = 0; - - static void ConvertID(const nsID& from, JSIID* to); - static void ConvertID(const JSIID& from, nsID* to); - - JSObject* findCPOWById(const ObjectId& objId); - JSObject* findCPOWByIdPreserveColor(const ObjectId& objId); - JSObject* findObjectById(JSContext* cx, const ObjectId& objId); - -#ifdef DEBUG - bool hasCPOW(const ObjectId& objId, const JSObject* obj) { - MOZ_ASSERT(obj); - return findCPOWByIdPreserveColor(objId) == obj; - } -#endif - - static bool LoggingEnabled() { - return sLoggingEnabledByEnvVar || StaticPrefs::dom_ipc_cpows_log_enabled(); - } - static bool StackLoggingEnabled() { - return sStackLoggingEnabledByEnvVar || - StaticPrefs::dom_ipc_cpows_log_stack(); - } - - friend class Logging; - - virtual bool isParent() = 0; - - virtual JSObject* scopeForTargetObjects() = 0; - - protected: - uintptr_t refcount_; - - IdToObjectMap objects_; - IdToObjectMap cpows_; - - uint64_t nextSerialNumber_; - - // nextCPOWNumber_ should be the value of nextSerialNumber_ in the other - // process. The next new CPOW we get should have this serial number. - uint64_t nextCPOWNumber_; - - // CPOW references can be weak, and any object we store in a map may be - // GCed (at which point the CPOW will report itself "dead" to the owner). - // This means that we don't want to store any js::Wrappers in the CPOW map, - // because CPOW will die if the wrapper is GCed, even if the underlying - // object is still alive. - // - // This presents a tricky situation for Xray waivers, since they're normally - // represented as a special same-compartment wrapper. We have to strip them - // off before putting them in the id-to-object and object-to-id maps, so we - // need a way of distinguishing them at lookup-time. - // - // For the id-to-object map, we encode waiver-or-not information into the id - // itself, which lets us do the right thing when accessing the object. - // - // For the object-to-id map, we just keep two maps, one for each type. - ObjectToIdMap unwaivedObjectIds_; - ObjectToIdMap waivedObjectIds_; - ObjectToIdMap& objectIdMap(bool waiver) { - return waiver ? waivedObjectIds_ : unwaivedObjectIds_; - } - - static bool sLoggingInitialized; - static bool sLoggingEnabledByEnvVar; - static bool sStackLoggingEnabledByEnvVar; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif diff --git a/js/ipc/JavaScriptTypes.ipdlh b/js/ipc/JavaScriptTypes.ipdlh deleted file mode 100644 index c8b46ce6dae7..000000000000 --- a/js/ipc/JavaScriptTypes.ipdlh +++ /dev/null @@ -1,155 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include DOMTypes; - -using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; - -namespace mozilla { -namespace jsipc { - -struct JSIID -{ - uint32_t m0; - uint16_t m1; - uint16_t m2; - uint8_t m3_0; - uint8_t m3_1; - uint8_t m3_2; - uint8_t m3_3; - uint8_t m3_4; - uint8_t m3_5; - uint8_t m3_6; - uint8_t m3_7; -}; - -struct LocalObject -{ - uint64_t serializedId; -}; - -struct RemoteObject -{ - uint64_t serializedId; - bool isCallable; - bool isConstructor; - bool isDOMObject; -}; - -union ObjectVariant -{ - LocalObject; - RemoteObject; -}; - -struct WellKnownSymbol -{ - uint32_t which; -}; - -struct RegisteredSymbol -{ - nsString key; -}; - -union SymbolVariant -{ - WellKnownSymbol; - RegisteredSymbol; -}; - -struct UndefinedVariant {}; -struct NullVariant {}; - -union ObjectOrNullVariant -{ - ObjectVariant; - NullVariant; -}; - -union JSVariant -{ - UndefinedVariant; - NullVariant; - ObjectVariant; - SymbolVariant; - nsString; /* StringValue(x) */ - double; /* NumberValue(x) */ - bool; /* BooleanValue(x) */ - JSIID; /* XPC nsIID */ -}; - -union JSIDVariant -{ - SymbolVariant; - nsString; - int32_t; -}; - -struct ReturnSuccess -{ -}; - -struct ReturnDeadCPOW -{ -}; - -struct ReturnException -{ - JSVariant exn; -}; - -struct ReturnObjectOpResult -{ - uint32_t code; -}; - -union ReturnStatus -{ - ReturnSuccess; - ReturnDeadCPOW; - ReturnException; - ReturnObjectOpResult; -}; - -union JSParam -{ - void_t; /* value is strictly an xpc out param */ - JSVariant; /* actual value to pass through */ -}; - -union GetterSetter -{ - uint64_t; - ObjectVariant; -}; - -struct PPropertyDescriptor -{ - ObjectOrNullVariant obj; - uint32_t attrs; - JSVariant value; - - // How to interpret these values depends on whether JSPROP_GETTER/SETTER - // are set. If set, the corresponding value is a CPOW or 0 for NULL. - // Otherwise, the following table is used: - // - // 0 - NULL - // 1 - Default getter or setter. - // 2 - Unknown - GetterSetter getter; - GetterSetter setter; -}; - -struct CpowEntry -{ - nsString name; - JSVariant value; -}; - -} -} diff --git a/js/ipc/PJavaScript.ipdl b/js/ipc/PJavaScript.ipdl deleted file mode 100644 index 8d8f035fce06..000000000000 --- a/js/ipc/PJavaScript.ipdl +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include protocol PContent; -include DOMTypes; -include JavaScriptTypes; - -using struct mozilla::void_t from "ipc/IPCMessageUtils.h"; - -namespace mozilla { -namespace jsipc { - -nested(upto inside_sync) sync protocol PJavaScript -{ - manager PContent; - -both: - // Sent when a CPOW has been finalized and table entries can be freed up. - async DropObject(uint64_t objId); - - // These roughly map to the ProxyHandler hooks that CPOWs need. - nested(inside_sync) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs); - nested(inside_sync) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result); - nested(inside_sync) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs); - nested(inside_sync) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs); - - nested(inside_sync) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); - nested(inside_sync) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has); - nested(inside_sync) sync Get(uint64_t objId, JSVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result); - nested(inside_sync) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs); - - nested(inside_sync) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result); - nested(inside_sync) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams); - nested(inside_sync) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has); - nested(inside_sync) sync GetBuiltinClass(uint64_t objId) returns (ReturnStatus rs, uint32_t classValue); - nested(inside_sync) sync IsArray(uint64_t objId) returns (ReturnStatus rs, uint32_t ans); - nested(inside_sync) sync ClassName(uint64_t objId) returns (nsCString name); - nested(inside_sync) sync GetPrototype(uint64_t objId) returns (ReturnStatus rs, ObjectOrNullVariant result); - nested(inside_sync) sync GetPrototypeIfOrdinary(uint64_t objId) returns (ReturnStatus rs, bool isOrdinary, ObjectOrNullVariant result); - nested(inside_sync) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags); - - nested(inside_sync) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, JSIDVariant[] ids); - nested(inside_sync) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof); - nested(inside_sync) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof); - -parent: - async __delete__(); - -child: - async DropTemporaryStrongReferences(uint64_t upToObjId); -}; - -} -} diff --git a/js/ipc/WrapperAnswer.cpp b/js/ipc/WrapperAnswer.cpp deleted file mode 100644 index 8a18e168ef53..000000000000 --- a/js/ipc/WrapperAnswer.cpp +++ /dev/null @@ -1,892 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WrapperAnswer.h" -#include "JavaScriptLogging.h" -#include "mozilla/dom/BindingUtils.h" -#include "mozilla/dom/ScriptSettings.h" -#include "xpcprivate.h" -#include "js/Class.h" -#include "js/RegExp.h" -#include "jsfriendapi.h" - -using namespace JS; -using namespace mozilla; -using namespace mozilla::jsipc; - -// Note - Using AutoJSAPI (rather than AutoEntryScript) for a trap means -// that we don't expect it to run script. For most of these traps that will only -// happen if the target is a scripted proxy, which is probably something that we -// don't want to support over CPOWs. When enough code is fixed up, the long-term -// plan is to have the JS engine throw if it encounters script when it isn't -// expecting it. -using mozilla::dom::AutoEntryScript; -using mozilla::dom::AutoJSAPI; - -using xpc::IsInAutomation; - -static void MaybeForceDebugGC() { - static bool sEnvVarInitialized = false; - static bool sDebugGCs = false; - - if (!sEnvVarInitialized) { - sDebugGCs = !!PR_GetEnv("MOZ_DEBUG_DEAD_CPOWS"); - } - - if (sDebugGCs) { - JSContext* cx = XPCJSContext::Get()->Context(); - PrepareForFullGC(cx); - NonIncrementalGC(cx, GC_NORMAL, GCReason::COMPONENT_UTILS); - } -} - -bool WrapperAnswer::fail(AutoJSAPI& jsapi, ReturnStatus* rs) { - // By default, we set |undefined| unless we can get a more meaningful - // exception. - *rs = ReturnStatus(ReturnException(JSVariant(UndefinedVariant()))); - - // Note we always return true from this function, since this propagates - // to the IPC code, and we don't want a JS failure to cause the death - // of the child process. - - JSContext* cx = jsapi.cx(); - RootedValue exn(cx); - if (!jsapi.HasException()) { - return true; - } - - if (!jsapi.StealException(&exn)) { - return true; - } - - // If this fails, we still don't want to exit. Just return an invalid - // exception. - (void)toVariant(cx, exn, &rs->get_ReturnException().exn()); - return true; -} - -bool WrapperAnswer::ok(ReturnStatus* rs) { - *rs = ReturnStatus(ReturnSuccess()); - return true; -} - -bool WrapperAnswer::ok(ReturnStatus* rs, const JS::ObjectOpResult& result) { - *rs = result ? ReturnStatus(ReturnSuccess()) - : ReturnStatus(ReturnObjectOpResult(result.failureCode())); - return true; -} - -bool WrapperAnswer::deadCPOW(AutoJSAPI& jsapi, ReturnStatus* rs) { - JSContext* cx = jsapi.cx(); - JS_ClearPendingException(cx); - *rs = ReturnStatus(ReturnDeadCPOW()); - return true; -} - -bool WrapperAnswer::RecvPreventExtensions(const ObjectId& objId, - ReturnStatus* rs) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - ObjectOpResult success; - if (!JS_PreventExtensions(cx, obj, success)) { - return fail(jsapi, rs); - } - - LOG("%s.preventExtensions()", ReceiverObj(objId)); - return ok(rs, success); -} - -static void EmptyDesc(PPropertyDescriptor* desc) { - desc->obj() = LocalObject(0); - desc->attrs() = 0; - desc->value() = UndefinedVariant(); - desc->getter() = 0; - desc->setter() = 0; -} - -bool WrapperAnswer::RecvGetOwnPropertyDescriptor(const ObjectId& objId, - const JSIDVariant& idVar, - ReturnStatus* rs, - PPropertyDescriptor* out) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - EmptyDesc(out); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.getOwnPropertyDescriptor(%s)", ReceiverObj(objId), Identifier(idVar)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - return fail(jsapi, rs); - } - - Rooted desc(cx); - if (!JS_GetOwnPropertyDescriptorById(cx, obj, id, &desc)) { - return fail(jsapi, rs); - } - - if (!fromDescriptor(cx, desc, out)) { - return fail(jsapi, rs); - } - - return ok(rs); -} - -bool WrapperAnswer::RecvDefineProperty(const ObjectId& objId, - const JSIDVariant& idVar, - const PPropertyDescriptor& descriptor, - ReturnStatus* rs) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("define %s[%s]", ReceiverObj(objId), Identifier(idVar)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - return fail(jsapi, rs); - } - - Rooted desc(cx); - if (!toDescriptor(cx, descriptor, &desc)) { - return fail(jsapi, rs); - } - - ObjectOpResult success; - if (!JS_DefinePropertyById(cx, obj, id, desc, success)) { - return fail(jsapi, rs); - } - return ok(rs, success); -} - -bool WrapperAnswer::RecvDelete(const ObjectId& objId, const JSIDVariant& idVar, - ReturnStatus* rs) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("delete %s[%s]", ReceiverObj(objId), Identifier(idVar)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - return fail(jsapi, rs); - } - - ObjectOpResult success; - if (!JS_DeletePropertyById(cx, obj, id, success)) { - return fail(jsapi, rs); - } - return ok(rs, success); -} - -bool WrapperAnswer::RecvHas(const ObjectId& objId, const JSIDVariant& idVar, - ReturnStatus* rs, bool* foundp) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - *foundp = false; - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.has(%s)", ReceiverObj(objId), Identifier(idVar)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - return fail(jsapi, rs); - } - - if (!JS_HasPropertyById(cx, obj, id, foundp)) { - return fail(jsapi, rs); - } - return ok(rs); -} - -bool WrapperAnswer::RecvHasOwn(const ObjectId& objId, const JSIDVariant& idVar, - ReturnStatus* rs, bool* foundp) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - *foundp = false; - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.hasOwn(%s)", ReceiverObj(objId), Identifier(idVar)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - 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 JSVariant& receiverVar, - const JSIDVariant& idVar, ReturnStatus* rs, - JSVariant* result) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - // We may run scripted getters. - AutoEntryScript aes(scopeForTargetObjects(), - "Cross-Process Object Wrapper 'get'"); - 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 deadCPOW(aes, rs); - } - - 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)) { - return fail(aes, rs); - } - - if (!toVariant(cx, val, result)) { - return fail(aes, rs); - } - - LOG("get %s.%s = %s", ReceiverObj(objId), Identifier(idVar), - OutVariant(*result)); - - return ok(rs); -} - -bool WrapperAnswer::RecvSet(const ObjectId& objId, const JSIDVariant& idVar, - const JSVariant& value, - const JSVariant& receiverVar, ReturnStatus* rs) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - // We may run scripted setters. - AutoEntryScript aes(scopeForTargetObjects(), - "Cross-Process Object Wrapper 'set'"); - JSContext* cx = aes.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(aes, rs); - } - - LOG("set %s[%s] = %s", ReceiverObj(objId), Identifier(idVar), - InVariant(value)); - - RootedId id(cx); - if (!fromJSIDVariant(cx, idVar, &id)) { - return fail(aes, rs); - } - - RootedValue val(cx); - if (!fromVariant(cx, value, &val)) { - return fail(aes, rs); - } - - RootedValue receiver(cx); - if (!fromVariant(cx, receiverVar, &receiver)) { - return fail(aes, rs); - } - - ObjectOpResult result; - if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiver, result)) { - return fail(aes, rs); - } - - return ok(rs, result); -} - -bool WrapperAnswer::RecvIsExtensible(const ObjectId& objId, ReturnStatus* rs, - bool* result) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - *result = false; - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.isExtensible()", ReceiverObj(objId)); - - bool extensible; - if (!JS_IsExtensible(cx, obj, &extensible)) { - return fail(jsapi, rs); - } - - *result = !!extensible; - return ok(rs); -} - -bool WrapperAnswer::RecvCallOrConstruct(const ObjectId& objId, - nsTArray&& argv, - const bool& construct, ReturnStatus* rs, - JSVariant* result, - nsTArray* outparams) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoEntryScript aes(scopeForTargetObjects(), - "Cross-Process Object Wrapper call/construct"); - 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 deadCPOW(aes, rs); - } - - MOZ_ASSERT(argv.Length() >= 2); - - RootedValue objv(cx); - if (!fromVariant(cx, argv[0], &objv)) { - return fail(aes, rs); - } - - *result = JSVariant(UndefinedVariant()); - - RootedValueVector vals(cx); - RootedValueVector outobjects(cx); - for (size_t i = 0; i < argv.Length(); i++) { - if (argv[i].type() == JSParam::Tvoid_t) { - // This is an outparam. - RootedObject obj(cx, xpc::NewOutObject(cx)); - if (!obj) { - return fail(aes, rs); - } - if (!outobjects.append(ObjectValue(*obj))) { - return fail(aes, rs); - } - if (!vals.append(ObjectValue(*obj))) { - return fail(aes, rs); - } - } else { - RootedValue v(cx); - if (!fromVariant(cx, argv[i].get_JSVariant(), &v)) { - return fail(aes, rs); - } - if (!vals.append(v)) { - return fail(aes, rs); - } - } - } - - RootedValue rval(cx); - { - HandleValueArray args = - HandleValueArray::subarray(vals, 2, vals.length() - 2); - if (construct) { - RootedObject obj(cx); - if (!JS::Construct(cx, vals[0], args, &obj)) { - return fail(aes, rs); - } - rval.setObject(*obj); - } else { - if (!JS::Call(cx, vals[1], vals[0], args, &rval)) return fail(aes, rs); - } - } - - if (!toVariant(cx, rval, result)) { - return fail(aes, rs); - } - - // Prefill everything with a dummy jsval. - for (size_t i = 0; i < outobjects.length(); i++) { - outparams->AppendElement(JSParam(void_t())); - } - - // Go through each argument that was an outparam, retrieve the "value" - // field, and add it to a temporary list. We need to do this separately - // because the outparams vector is not rooted. - vals.clear(); - for (size_t i = 0; i < outobjects.length(); i++) { - RootedObject obj(cx, &outobjects[i].toObject()); - - RootedValue v(cx); - bool found; - if (JS_HasProperty(cx, obj, "value", &found)) { - if (!JS_GetProperty(cx, obj, "value", &v)) { - return fail(aes, rs); - } - } else { - v = UndefinedValue(); - } - if (!vals.append(v)) { - return fail(aes, rs); - } - } - - // Copy the outparams. If any outparam is already set to a void_t, we - // treat this as the outparam never having been set. - for (size_t i = 0; i < vals.length(); i++) { - JSVariant variant; - if (!toVariant(cx, vals[i], &variant)) { - return fail(aes, rs); - } - outparams->ReplaceElementAt(i, JSParam(variant)); - } - - LOG("%s.call(%s) = %s", ReceiverObj(objId), argv, OutVariant(*result)); - - return ok(rs); -} - -bool WrapperAnswer::RecvHasInstance(const ObjectId& objId, - const JSVariant& vVar, ReturnStatus* rs, - bool* bp) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.hasInstance(%s)", ReceiverObj(objId), InVariant(vVar)); - - RootedValue val(cx); - if (!fromVariant(cx, vVar, &val)) { - return fail(jsapi, rs); - } - - if (!JS_HasInstance(cx, obj, val, bp)) { - return fail(jsapi, rs); - } - - return ok(rs); -} - -bool WrapperAnswer::RecvGetBuiltinClass(const ObjectId& objId, ReturnStatus* rs, - uint32_t* classValue) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - *classValue = uint32_t(js::ESClass::Other); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.getBuiltinClass()", ReceiverObj(objId)); - - js::ESClass cls; - if (!js::GetBuiltinClass(cx, obj, &cls)) { - return fail(jsapi, rs); - } - - *classValue = uint32_t(cls); - return ok(rs); -} - -bool WrapperAnswer::RecvIsArray(const ObjectId& objId, ReturnStatus* rs, - uint32_t* ans) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - *ans = uint32_t(IsArrayAnswer::NotArray); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.isArray()", ReceiverObj(objId)); - - IsArrayAnswer answer; - if (!JS::IsArray(cx, obj, &answer)) { - return fail(jsapi, rs); - } - - *ans = uint32_t(answer); - return ok(rs); -} - -bool WrapperAnswer::RecvClassName(const ObjectId& objId, nsCString* name) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - // This is very unfortunate, but we have no choice. - *name = ""; - return true; - } - - LOG("%s.className()", ReceiverObj(objId)); - - *name = js::ObjectClassName(cx, obj); - return true; -} - -bool WrapperAnswer::RecvGetPrototype(const ObjectId& objId, ReturnStatus* rs, - ObjectOrNullVariant* result) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - *result = NullVariant(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - JS::RootedObject proto(cx); - if (!JS_GetPrototype(cx, obj, &proto)) { - return fail(jsapi, rs); - } - - if (!toObjectOrNullVariant(cx, proto, result)) { - return fail(jsapi, rs); - } - - LOG("getPrototype(%s)", ReceiverObj(objId)); - - return ok(rs); -} - -bool WrapperAnswer::RecvGetPrototypeIfOrdinary(const ObjectId& objId, - ReturnStatus* rs, - bool* isOrdinary, - ObjectOrNullVariant* result) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - *result = NullVariant(); - *isOrdinary = false; - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - JS::RootedObject proto(cx); - if (!JS_GetPrototypeIfOrdinary(cx, obj, isOrdinary, &proto)) { - return fail(jsapi, rs); - } - - if (!toObjectOrNullVariant(cx, proto, result)) { - return fail(jsapi, rs); - } - - LOG("getPrototypeIfOrdinary(%s)", ReceiverObj(objId)); - - return ok(rs); -} - -bool WrapperAnswer::RecvRegExpToShared(const ObjectId& objId, ReturnStatus* rs, - nsString* source, uint32_t* flags) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - RootedString sourceJSStr(cx, JS::GetRegExpSource(cx, obj)); - if (!sourceJSStr) { - return fail(jsapi, rs); - } - nsAutoJSString sourceStr; - if (!sourceStr.init(cx, sourceJSStr)) { - return fail(jsapi, rs); - } - source->Assign(sourceStr); - - *flags = JS::GetRegExpFlags(cx, obj).value(); - - return ok(rs); -} - -bool WrapperAnswer::RecvGetPropertyKeys(const ObjectId& objId, - const uint32_t& flags, ReturnStatus* rs, - nsTArray* ids) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.getPropertyKeys()", ReceiverObj(objId)); - - RootedIdVector props(cx); - if (!js::GetPropertyKeys(cx, obj, flags, &props)) { - return fail(jsapi, rs); - } - - for (size_t i = 0; i < props.length(); i++) { - JSIDVariant id; - if (!toJSIDVariant(cx, props[i], &id)) { - return fail(jsapi, rs); - } - - ids->AppendElement(id); - } - - return ok(rs); -} - -bool WrapperAnswer::RecvInstanceOf(const ObjectId& objId, const JSIID& iid, - ReturnStatus* rs, bool* instanceof) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - - * instanceof = false; - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.instanceOf()", ReceiverObj(objId)); - - nsID nsiid; - ConvertID(iid, &nsiid); - - nsresult rv = xpc::HasInstance(cx, obj, &nsiid, instanceof); - if (rv != NS_OK) { - return fail(jsapi, rs); - } - - return ok(rs); -} - -bool WrapperAnswer::RecvDOMInstanceOf(const ObjectId& objId, - const int& prototypeID, const int& depth, - ReturnStatus* rs, bool* instanceof) { - if (!IsInAutomation()) { - return false; - } - - MaybeForceDebugGC(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects()))) { - return false; - } - JSContext* cx = jsapi.cx(); - * instanceof = false; - - RootedObject obj(cx, findObjectById(cx, objId)); - if (!obj) { - return deadCPOW(jsapi, rs); - } - - LOG("%s.domInstanceOf()", ReceiverObj(objId)); - - bool tmp; - if (!mozilla::dom::InterfaceHasInstance(cx, prototypeID, depth, obj, &tmp)) { - return fail(jsapi, rs); - } - * instanceof = tmp; - - return ok(rs); -} - -bool WrapperAnswer::RecvDropObject(const ObjectId& objId) { - JSObject* obj = objects_.findPreserveColor(objId); - if (obj) { - objectIdMap(objId.hasXrayWaiver()).remove(obj); - objects_.remove(objId); - } - return true; -} diff --git a/js/ipc/WrapperAnswer.h b/js/ipc/WrapperAnswer.h deleted file mode 100644 index d4dd7202f660..000000000000 --- a/js/ipc/WrapperAnswer.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_WrapperAnswer_h_ -#define mozilla_jsipc_WrapperAnswer_h_ - -#include "JavaScriptShared.h" - -namespace mozilla { - -namespace dom { -class AutoJSAPI; -} // namespace dom - -namespace jsipc { - -class WrapperAnswer : public virtual JavaScriptShared { - public: - bool RecvPreventExtensions(const ObjectId& objId, ReturnStatus* rs); - bool RecvGetOwnPropertyDescriptor(const ObjectId& objId, - const JSIDVariant& id, ReturnStatus* rs, - PPropertyDescriptor* out); - 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 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, nsTArray&& argv, - const bool& construct, ReturnStatus* rs, - JSVariant* result, nsTArray* outparams); - bool RecvHasInstance(const ObjectId& objId, const JSVariant& v, - ReturnStatus* rs, bool* bp); - bool RecvGetBuiltinClass(const ObjectId& objId, ReturnStatus* rs, - uint32_t* classValue); - bool RecvIsArray(const ObjectId& objId, ReturnStatus* rs, uint32_t* ans); - bool RecvClassName(const ObjectId& objId, nsCString* result); - bool RecvGetPrototype(const ObjectId& objId, ReturnStatus* rs, - ObjectOrNullVariant* result); - bool RecvGetPrototypeIfOrdinary(const ObjectId& objId, ReturnStatus* rs, - bool* isOrdinary, - ObjectOrNullVariant* result); - bool RecvRegExpToShared(const ObjectId& objId, ReturnStatus* rs, - nsString* source, uint32_t* flags); - - bool RecvGetPropertyKeys(const ObjectId& objId, const uint32_t& flags, - ReturnStatus* rs, nsTArray* ids); - bool RecvInstanceOf(const ObjectId& objId, const JSIID& iid, ReturnStatus* rs, - bool* instanceof); - bool RecvDOMInstanceOf(const ObjectId& objId, const int& prototypeID, - const int& depth, ReturnStatus* rs, bool* instanceof); - - bool RecvDropObject(const ObjectId& objId); - - private: - bool fail(dom::AutoJSAPI& jsapi, ReturnStatus* rs); - bool ok(ReturnStatus* rs); - bool ok(ReturnStatus* rs, const JS::ObjectOpResult& result); - bool deadCPOW(dom::AutoJSAPI& jsapi, ReturnStatus* rs); -}; - -} // namespace jsipc -} // namespace mozilla - -#endif diff --git a/js/ipc/WrapperOwner.cpp b/js/ipc/WrapperOwner.cpp deleted file mode 100644 index 6f4f21719367..000000000000 --- a/js/ipc/WrapperOwner.cpp +++ /dev/null @@ -1,1073 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=4 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "WrapperOwner.h" -#include "JavaScriptLogging.h" -#include "mozilla/Unused.h" -#include "mozilla/dom/BindingUtils.h" -#include "jsfriendapi.h" -#include "js/CharacterEncoding.h" -#include "js/RegExp.h" -#include "js/RegExpFlags.h" -#include "xpcprivate.h" -#include "WrapperFactory.h" - -#include "nsIDocShellTreeItem.h" -#include "mozilla/dom/Document.h" - -using namespace js; -using namespace JS; -using namespace mozilla; -using namespace mozilla::jsipc; - -struct AuxCPOWData { - ObjectId id; - bool isCallable; - bool isConstructor; - - // The class name for WrapperOwner::className, below. - nsCString className; - - AuxCPOWData(ObjectId id, bool isCallable, bool isConstructor) - : id(id), isCallable(isCallable), isConstructor(isConstructor) {} -}; - -WrapperOwner::WrapperOwner() : inactive_(false) {} - -static inline AuxCPOWData* AuxCPOWDataOf(JSObject* obj) { - MOZ_ASSERT(IsCPOW(obj)); - return static_cast(GetProxyReservedSlot(obj, 1).toPrivate()); -} - -static inline WrapperOwner* OwnerOf(JSObject* obj) { - MOZ_ASSERT(IsCPOW(obj)); - return reinterpret_cast( - GetProxyReservedSlot(obj, 0).toPrivate()); -} - -ObjectId WrapperOwner::idOfUnchecked(JSObject* obj) { - MOZ_ASSERT(IsCPOW(obj)); - - AuxCPOWData* aux = AuxCPOWDataOf(obj); - MOZ_ASSERT(!aux->id.isNull()); - return aux->id; -} - -ObjectId WrapperOwner::idOf(JSObject* obj) { - ObjectId objId = idOfUnchecked(obj); - MOZ_ASSERT(hasCPOW(objId, obj)); - return objId; -} - -class CPOWProxyHandler : public BaseProxyHandler { - public: - constexpr CPOWProxyHandler() : BaseProxyHandler(&family) {} - - virtual bool finalizeInBackground(const Value& priv) const override { - return false; - } - - virtual bool getOwnPropertyDescriptor( - JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id, - Handle desc, - ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) const override; - virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const override; - virtual bool enumerate(JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) 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, 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 hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const override; - virtual bool getOwnEnumerablePropertyKeys( - JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) const override; - virtual bool hasInstance(JSContext* cx, HandleObject proxy, - MutableHandleValue v, bool* bp) const override; - virtual bool getBuiltinClass(JSContext* cx, HandleObject obj, - js::ESClass* cls) const override; - virtual bool isArray(JSContext* cx, HandleObject obj, - IsArrayAnswer* answer) const override; - virtual const char* className(JSContext* cx, - HandleObject proxy) const override; - virtual RegExpShared* regexp_toShared(JSContext* cx, - HandleObject proxy) const override; - virtual void finalize(JSFreeOp* fop, JSObject* proxy) const override; - virtual size_t objectMoved(JSObject* proxy, JSObject* old) const override; - virtual bool isCallable(JSObject* obj) const override; - virtual bool isConstructor(JSObject* obj) const override; - virtual bool getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject protop) const override; - virtual bool getPrototypeIfOrdinary( - JSContext* cx, HandleObject proxy, bool* isOrdinary, - MutableHandleObject protop) const override; - - static const char family; - static const CPOWProxyHandler singleton; -}; - -const char CPOWProxyHandler::family = 0; -const CPOWProxyHandler CPOWProxyHandler::singleton; - -#define FORWARD(call, args, failRetVal) \ - AUTO_PROFILER_LABEL(__func__, JS); \ - WrapperOwner* owner = OwnerOf(proxy); \ - if (!owner->active()) { \ - JS_ReportErrorASCII(cx, "cannot use a CPOW whose process is gone"); \ - return failRetVal; \ - } \ - if (!owner->allowMessage(cx)) { \ - return failRetVal; \ - } \ - { return owner->call args; } - -bool CPOWProxyHandler::getOwnPropertyDescriptor( - JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) const { - FORWARD(getOwnPropertyDescriptor, (cx, proxy, id, desc), false); -} - -bool WrapperOwner::getOwnPropertyDescriptor( - JSContext* cx, HandleObject proxy, HandleId id, - MutableHandle desc) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - ReturnStatus status; - PPropertyDescriptor result; - if (!SendGetOwnPropertyDescriptor(objId, idVar, &status, &result)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - return toDescriptor(cx, result, desc); -} - -bool CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, - HandleId id, - Handle desc, - ObjectOpResult& result) const { - FORWARD(defineProperty, (cx, proxy, id, desc, result), false); -} - -bool WrapperOwner::defineProperty(JSContext* cx, HandleObject proxy, - HandleId id, Handle desc, - ObjectOpResult& result) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - PPropertyDescriptor descriptor; - if (!fromDescriptor(cx, desc, &descriptor)) { - return false; - } - - ReturnStatus status; - if (!SendDefineProperty(objId, idVar, descriptor, &status)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status, result); -} - -bool CPOWProxyHandler::ownPropertyKeys(JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) const { - FORWARD(ownPropertyKeys, (cx, proxy, props), false); -} - -bool WrapperOwner::ownPropertyKeys(JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) { - return getPropertyKeys( - cx, proxy, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); -} - -bool CPOWProxyHandler::delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) const { - FORWARD(delete_, (cx, proxy, id, result), false); -} - -bool WrapperOwner::delete_(JSContext* cx, HandleObject proxy, HandleId id, - ObjectOpResult& result) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - ReturnStatus status; - if (!SendDelete(objId, idVar, &status)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status, result); -} - -bool CPOWProxyHandler::enumerate(JSContext* cx, HandleObject proxy, - MutableHandleIdVector props) const { - // Call the base hook. That will use our implementation of - // getOwnEnumerablePropertyKeys and follow the proto chain. - return BaseProxyHandler::enumerate(cx, proxy, props); -} - -bool CPOWProxyHandler::has(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const { - FORWARD(has, (cx, proxy, id, bp), false); -} - -bool WrapperOwner::has(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - ReturnStatus status; - if (!SendHas(objId, idVar, &status, bp)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status); -} - -bool CPOWProxyHandler::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) const { - FORWARD(hasOwn, (cx, proxy, id, bp), false); -} - -bool WrapperOwner::hasOwn(JSContext* cx, HandleObject proxy, HandleId id, - bool* bp) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - ReturnStatus status; - if (!SendHasOwn(objId, idVar, &status, bp)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return !!ok(cx, status); -} - -bool CPOWProxyHandler::get(JSContext* cx, HandleObject proxy, - HandleValue receiver, HandleId id, - MutableHandleValue vp) const { - FORWARD(get, (cx, proxy, receiver, id, vp), false); -} - -static bool CPOWToString(JSContext* cx, unsigned argc, Value* vp) { - CallArgs args = CallArgsFromVp(argc, vp); - RootedObject callee(cx, &args.callee()); - RootedValue cpowValue(cx); - if (!JS_GetProperty(cx, callee, "__cpow__", &cpowValue)) { - return false; - } - - if (!cpowValue.isObject() || !IsCPOW(&cpowValue.toObject())) { - JS_ReportErrorASCII(cx, "CPOWToString called on an incompatible object"); - return false; - } - - RootedObject proxy(cx, &cpowValue.toObject()); - FORWARD(toString, (cx, proxy, args), false); -} - -bool WrapperOwner::toString(JSContext* cx, HandleObject cpow, - JS::CallArgs& args) { - // Ask the other side to call its toString method. Update the callee so that - // it points to the CPOW and not to the synthesized CPOWToString function. - args.setCallee(ObjectValue(*cpow)); - if (!callOrConstruct(cx, cpow, args, false)) { - return false; - } - - if (!args.rval().isString()) { - return true; - } - - RootedString cpowResult(cx, args.rval().toString()); - nsAutoJSString toStringResult; - if (!toStringResult.init(cx, cpowResult)) { - return false; - } - - // We don't want to wrap toString() results for things like the location - // object, where toString() is supposed to return a URL and nothing else. - nsAutoString result; - if (toStringResult[0] == '[') { - result.AppendLiteral("[object CPOW "); - result += toStringResult; - result.AppendLiteral("]"); - } else { - result += toStringResult; - } - - JSString* str = JS_NewUCStringCopyN(cx, result.get(), result.Length()); - if (!str) { - return false; - } - - args.rval().setString(str); - return true; -} - -bool WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleValue receiver, - HandleId id, MutableHandleValue vp) { - ObjectId objId = idOf(proxy); - - JSVariant receiverVar; - if (!toVariant(cx, receiver, &receiverVar)) { - return false; - } - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - JSVariant val; - ReturnStatus status; - if (!SendGet(objId, receiverVar, idVar, &status, &val)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - if (!fromVariant(cx, val, vp)) { - return false; - } - - if (idVar.type() == JSIDVariant::TnsString && - idVar.get_nsString().EqualsLiteral("toString")) { - RootedFunction toString(cx, - JS_NewFunction(cx, CPOWToString, 0, 0, "toString")); - if (!toString) { - return false; - } - - RootedObject toStringObj(cx, JS_GetFunctionObject(toString)); - - if (!JS_DefineProperty(cx, toStringObj, "__cpow__", vp, - JSPROP_PERMANENT | JSPROP_READONLY)) { - return false; - } - - vp.set(ObjectValue(*toStringObj)); - } - - return true; -} - -bool CPOWProxyHandler::set(JSContext* cx, JS::HandleObject proxy, - JS::HandleId id, JS::HandleValue v, - JS::HandleValue receiver, - JS::ObjectOpResult& result) const { - FORWARD(set, (cx, proxy, id, v, receiver, result), false); -} - -bool WrapperOwner::set(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::HandleValue v, JS::HandleValue receiver, - JS::ObjectOpResult& result) { - ObjectId objId = idOf(proxy); - - JSIDVariant idVar; - if (!toJSIDVariant(cx, id, &idVar)) { - return false; - } - - JSVariant val; - if (!toVariant(cx, v, &val)) { - return false; - } - - JSVariant receiverVar; - if (!toVariant(cx, receiver, &receiverVar)) { - return false; - } - - ReturnStatus status; - if (!SendSet(objId, idVar, val, receiverVar, &status)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status, result); -} - -bool CPOWProxyHandler::getOwnEnumerablePropertyKeys( - JSContext* cx, HandleObject proxy, MutableHandleIdVector props) const { - FORWARD(getOwnEnumerablePropertyKeys, (cx, proxy, props), false); -} - -bool WrapperOwner::getOwnEnumerablePropertyKeys(JSContext* cx, - HandleObject proxy, - MutableHandleIdVector props) { - return getPropertyKeys(cx, proxy, JSITER_OWNONLY, props); -} - -bool CPOWProxyHandler::preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) const { - FORWARD(preventExtensions, (cx, proxy, result), false); -} - -bool WrapperOwner::preventExtensions(JSContext* cx, HandleObject proxy, - ObjectOpResult& result) { - ObjectId objId = idOf(proxy); - - ReturnStatus status; - if (!SendPreventExtensions(objId, &status)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status, result); -} - -bool CPOWProxyHandler::isExtensible(JSContext* cx, HandleObject proxy, - bool* extensible) const { - FORWARD(isExtensible, (cx, proxy, extensible), false); -} - -bool WrapperOwner::isExtensible(JSContext* cx, HandleObject proxy, - bool* extensible) { - ObjectId objId = idOf(proxy); - - ReturnStatus status; - if (!SendIsExtensible(objId, &status, extensible)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status); -} - -bool CPOWProxyHandler::call(JSContext* cx, HandleObject proxy, - const CallArgs& args) const { - FORWARD(callOrConstruct, (cx, proxy, args, false), false); -} - -bool CPOWProxyHandler::construct(JSContext* cx, HandleObject proxy, - const CallArgs& args) const { - FORWARD(callOrConstruct, (cx, proxy, args, true), false); -} - -bool WrapperOwner::callOrConstruct(JSContext* cx, HandleObject proxy, - const CallArgs& args, bool construct) { - ObjectId objId = idOf(proxy); - - nsTArray vals; - RootedValueVector outobjects(cx); - - RootedValue v(cx); - for (size_t i = 0; i < args.length() + 2; i++) { - // The |this| value for constructors is a magic value that we won't be - // able to convert, so skip it. - if (i == 1 && construct) { - v = UndefinedValue(); - } else { - v = args.base()[i]; - } - if (v.isObject()) { - RootedObject obj(cx, &v.toObject()); - if (xpc::IsOutObject(cx, obj)) { - // Make sure it is not an in-out object. - bool found; - if (!JS_HasProperty(cx, obj, "value", &found)) { - return false; - } - if (found) { - JS_ReportErrorASCII(cx, - "in-out objects cannot be sent via CPOWs yet"); - return false; - } - - vals.AppendElement(JSParam(void_t())); - if (!outobjects.append(ObjectValue(*obj))) { - return false; - } - continue; - } - } - JSVariant val; - if (!toVariant(cx, v, &val)) { - return false; - } - vals.AppendElement(JSParam(val)); - } - - JSVariant result; - ReturnStatus status; - nsTArray outparams; - if (!SendCallOrConstruct(objId, vals, construct, &status, &result, - &outparams)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - if (outparams.Length() != outobjects.length()) { - return ipcfail(cx); - } - - RootedObject obj(cx); - for (size_t i = 0; i < outparams.Length(); i++) { - // Don't bother doing anything for outparams that weren't set. - if (outparams[i].type() == JSParam::Tvoid_t) { - continue; - } - - // Take the value the child process returned, and set it on the XPC - // object. - if (!fromVariant(cx, outparams[i], &v)) { - return false; - } - - obj = &outobjects[i].toObject(); - if (!JS_SetProperty(cx, obj, "value", v)) { - return false; - } - } - - if (!fromVariant(cx, result, args.rval())) { - return false; - } - - return true; -} - -bool CPOWProxyHandler::hasInstance(JSContext* cx, HandleObject proxy, - MutableHandleValue v, bool* bp) const { - FORWARD(hasInstance, (cx, proxy, v, bp), false); -} - -bool WrapperOwner::hasInstance(JSContext* cx, HandleObject proxy, - MutableHandleValue v, bool* bp) { - ObjectId objId = idOf(proxy); - - JSVariant vVar; - if (!toVariant(cx, v, &vVar)) { - return false; - } - - ReturnStatus status; - if (!SendHasInstance(objId, vVar, &status, bp)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status); -} - -bool CPOWProxyHandler::getBuiltinClass(JSContext* cx, HandleObject proxy, - ESClass* cls) const { - FORWARD(getBuiltinClass, (cx, proxy, cls), false); -} - -bool WrapperOwner::getBuiltinClass(JSContext* cx, HandleObject proxy, - ESClass* cls) { - ObjectId objId = idOf(proxy); - - uint32_t classValue = uint32_t(ESClass::Other); - ReturnStatus status; - if (!SendGetBuiltinClass(objId, &status, &classValue)) { - return ipcfail(cx); - } - *cls = ESClass(classValue); - - LOG_STACK(); - - return ok(cx, status); -} - -bool CPOWProxyHandler::isArray(JSContext* cx, HandleObject proxy, - IsArrayAnswer* answer) const { - FORWARD(isArray, (cx, proxy, answer), false); -} - -bool WrapperOwner::isArray(JSContext* cx, HandleObject proxy, - IsArrayAnswer* answer) { - ObjectId objId = idOf(proxy); - - uint32_t ans; - ReturnStatus status; - if (!SendIsArray(objId, &status, &ans)) { - return ipcfail(cx); - } - - LOG_STACK(); - - *answer = IsArrayAnswer(ans); - MOZ_ASSERT(*answer == IsArrayAnswer::Array || - *answer == IsArrayAnswer::NotArray || - *answer == IsArrayAnswer::RevokedProxy); - - return ok(cx, status); -} - -const char* CPOWProxyHandler::className(JSContext* cx, - HandleObject proxy) const { - WrapperOwner* parent = OwnerOf(proxy); - if (!parent->active()) { - return ""; - } - return parent->className(cx, proxy); -} - -const char* WrapperOwner::className(JSContext* cx, HandleObject proxy) { - AuxCPOWData* data = AuxCPOWDataOf(proxy); - if (data->className.IsEmpty()) { - ObjectId objId = idOf(proxy); - - if (!SendClassName(objId, &data->className)) { - return ""; - } - - LOG_STACK(); - } - - return data->className.get(); -} - -bool CPOWProxyHandler::getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) const { - FORWARD(getPrototype, (cx, proxy, objp), false); -} - -bool WrapperOwner::getPrototype(JSContext* cx, HandleObject proxy, - MutableHandleObject objp) { - ObjectId objId = idOf(proxy); - - ObjectOrNullVariant val; - ReturnStatus status; - if (!SendGetPrototype(objId, &status, &val)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - objp.set(fromObjectOrNullVariant(cx, val)); - - return true; -} - -bool CPOWProxyHandler::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, - bool* isOrdinary, - MutableHandleObject objp) const { - FORWARD(getPrototypeIfOrdinary, (cx, proxy, isOrdinary, objp), false); -} - -bool WrapperOwner::getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, - bool* isOrdinary, - MutableHandleObject objp) { - ObjectId objId = idOf(proxy); - - ObjectOrNullVariant val; - ReturnStatus status; - if (!SendGetPrototypeIfOrdinary(objId, &status, isOrdinary, &val)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - objp.set(fromObjectOrNullVariant(cx, val)); - - return true; -} - -RegExpShared* CPOWProxyHandler::regexp_toShared(JSContext* cx, - HandleObject proxy) const { - FORWARD(regexp_toShared, (cx, proxy), nullptr); -} - -RegExpShared* WrapperOwner::regexp_toShared(JSContext* cx, HandleObject proxy) { - ObjectId objId = idOf(proxy); - - ReturnStatus status; - nsString source; - unsigned flags = 0; - if (!SendRegExpToShared(objId, &status, &source, &flags)) { - MOZ_ALWAYS_FALSE(ipcfail(cx)); - return nullptr; - } - LOG_STACK(); - - if (!ok(cx, status)) { - return nullptr; - } - - RootedObject regexp(cx); - regexp = JS::NewUCRegExpObject(cx, source.get(), source.Length(), - RegExpFlags(flags)); - if (!regexp) { - return nullptr; - } - - return js::RegExpToSharedNonInline(cx, regexp); -} - -void CPOWProxyHandler::finalize(JSFreeOp* fop, JSObject* proxy) const { - AuxCPOWData* aux = AuxCPOWDataOf(proxy); - - OwnerOf(proxy)->drop(proxy); - - if (aux) { - delete aux; - } -} - -size_t CPOWProxyHandler::objectMoved(JSObject* proxy, JSObject* old) const { - OwnerOf(proxy)->updatePointer(proxy, old); - return 0; -} - -bool CPOWProxyHandler::isCallable(JSObject* proxy) const { - AuxCPOWData* aux = AuxCPOWDataOf(proxy); - return aux->isCallable; -} - -bool CPOWProxyHandler::isConstructor(JSObject* proxy) const { - AuxCPOWData* aux = AuxCPOWDataOf(proxy); - return aux->isConstructor; -} - -void WrapperOwner::drop(JSObject* obj) { - // The association may have already been swept from the table but if it's - // there then remove it. - ObjectId objId = idOfUnchecked(obj); - if (cpows_.findPreserveColor(objId) == obj) { - cpows_.remove(objId); - } - - if (active()) { - Unused << SendDropObject(objId); - } - decref(); -} - -void WrapperOwner::updatePointer(JSObject* obj, const JSObject* old) { - ObjectId objId = idOfUnchecked(obj); - MOZ_ASSERT(hasCPOW(objId, old)); - cpows_.add(objId, obj); -} - -bool WrapperOwner::getPropertyKeys(JSContext* cx, HandleObject proxy, - uint32_t flags, - MutableHandleIdVector props) { - ObjectId objId = idOf(proxy); - - ReturnStatus status; - nsTArray ids; - if (!SendGetPropertyKeys(objId, flags, &status, &ids)) { - return ipcfail(cx); - } - - LOG_STACK(); - - if (!ok(cx, status)) { - return false; - } - - for (size_t i = 0; i < ids.Length(); i++) { - RootedId id(cx); - if (!fromJSIDVariant(cx, ids[i], &id)) { - return false; - } - if (!props.append(id)) { - return false; - } - } - - return true; -} - -namespace mozilla { -namespace jsipc { - -bool IsCPOW(JSObject* obj) { - return IsProxy(obj) && GetProxyHandler(obj) == &CPOWProxyHandler::singleton; -} - -bool IsWrappedCPOW(JSObject* obj) { - JSObject* unwrapped = js::UncheckedUnwrap(obj, true); - if (!unwrapped) { - return false; - } - return IsCPOW(unwrapped); -} - -nsresult InstanceOf(JSObject* proxy, const nsID* id, bool* bp) { - WrapperOwner* parent = OwnerOf(proxy); - if (!parent->active()) { - return NS_ERROR_UNEXPECTED; - } - return parent->instanceOf(proxy, id, bp); -} - -bool DOMInstanceOf(JSContext* cx, JSObject* proxyArg, int prototypeID, - int depth, bool* bp) { - RootedObject proxy(cx, proxyArg); - FORWARD(domInstanceOf, (cx, proxy, prototypeID, depth, bp), false); -} - -} /* namespace jsipc */ -} /* namespace mozilla */ - -nsresult WrapperOwner::instanceOf(JSObject* obj, const nsID* id, bool* bp) { - ObjectId objId = idOf(obj); - - JSIID iid; - ConvertID(*id, &iid); - - ReturnStatus status; - if (!SendInstanceOf(objId, iid, &status, bp)) { - return NS_ERROR_UNEXPECTED; - } - - if (status.type() != ReturnStatus::TReturnSuccess) { - return NS_ERROR_UNEXPECTED; - } - - return NS_OK; -} - -bool WrapperOwner::domInstanceOf(JSContext* cx, JSObject* obj, int prototypeID, - int depth, bool* bp) { - ObjectId objId = idOf(obj); - - ReturnStatus status; - if (!SendDOMInstanceOf(objId, prototypeID, depth, &status, bp)) { - return ipcfail(cx); - } - - LOG_STACK(); - - return ok(cx, status); -} - -void WrapperOwner::ActorDestroy(ActorDestroyReason why) { - inactive_ = true; - - objects_.clear(); - unwaivedObjectIds_.clear(); - waivedObjectIds_.clear(); -} - -bool WrapperOwner::ipcfail(JSContext* cx) { - JS_ReportErrorASCII(cx, "cross-process JS call failed"); - return false; -} - -bool WrapperOwner::ok(JSContext* cx, const ReturnStatus& status) { - if (status.type() == ReturnStatus::TReturnSuccess) { - return true; - } - - if (status.type() == ReturnStatus::TReturnDeadCPOW) { - JS_ReportErrorASCII(cx, "operation not possible on dead CPOW"); - return false; - } - - RootedValue exn(cx); - if (!fromVariant(cx, status.get_ReturnException().exn(), &exn)) { - return false; - } - - JS_SetPendingException(cx, exn); - return false; -} - -bool WrapperOwner::ok(JSContext* cx, const ReturnStatus& status, - ObjectOpResult& result) { - if (status.type() == ReturnStatus::TReturnObjectOpResult) { - return result.fail(status.get_ReturnObjectOpResult().code()); - } - if (!ok(cx, status)) { - return false; - } - return result.succeed(); -} - -static RemoteObject MakeRemoteObject(JSContext* cx, ObjectId id, - HandleObject obj) { - return RemoteObject(id.serialize(), JS::IsCallable(obj), - JS::IsConstructor(obj), dom::IsDOMObject(obj)); -} - -bool WrapperOwner::toObjectVariant(JSContext* cx, JSObject* objArg, - ObjectVariant* objVarp) { - RootedObject obj(cx, objArg); - MOZ_ASSERT(obj); - - // We always save objects unwrapped in the CPOW table. If we stored - // wrappers, then the wrapper might be GCed while the target remained alive. - // Whenever operating on an object that comes from the table, we wrap it - // in findObjectById. - unsigned wrapperFlags = 0; - obj = js::UncheckedUnwrap(obj, true, &wrapperFlags); - if (obj && IsCPOW(obj) && OwnerOf(obj) == this) { - *objVarp = LocalObject(idOf(obj).serialize()); - return true; - } - bool waiveXray = wrapperFlags & xpc::WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG; - - ObjectId id = objectIdMap(waiveXray).find(obj); - if (!id.isNull()) { - MOZ_ASSERT(id.hasXrayWaiver() == waiveXray); - *objVarp = MakeRemoteObject(cx, id, obj); - return true; - } - - // Need to call PreserveWrapper on |obj| in case it's a reflector. - // FIXME: What if it's an XPCWrappedNative? - if (mozilla::dom::IsDOMObject(obj)) { - mozilla::dom::TryPreserveWrapper(obj); - } - - id = ObjectId(nextSerialNumber_++, waiveXray); - if (!objects_.add(id, obj)) { - return false; - } - if (!objectIdMap(waiveXray).add(cx, obj, id)) { - return false; - } - - *objVarp = MakeRemoteObject(cx, id, obj); - return true; -} - -JSObject* WrapperOwner::fromObjectVariant(JSContext* cx, - const ObjectVariant& objVar) { - if (objVar.type() == ObjectVariant::TRemoteObject) { - return fromRemoteObjectVariant(cx, objVar.get_RemoteObject()); - } else { - return fromLocalObjectVariant(cx, objVar.get_LocalObject()); - } -} - -JSObject* WrapperOwner::fromRemoteObjectVariant(JSContext* cx, - const RemoteObject& objVar) { - Maybe maybeObjId(ObjectId::deserialize(objVar.serializedId())); - if (maybeObjId.isNothing()) { - return nullptr; - } - - ObjectId objId = maybeObjId.value(); - RootedObject obj(cx, findCPOWById(objId)); - if (!obj) { - // All CPOWs live in the privileged junk scope. - RootedObject junkScope(cx, xpc::PrivilegedJunkScope()); - JSAutoRealm ar(cx, junkScope); - RootedValue v(cx, UndefinedValue()); - // We need to setLazyProto for the getPrototype/getPrototypeIfOrdinary - // hooks. - ProxyOptions options; - options.setLazyProto(true); - obj = NewProxyObject(cx, &CPOWProxyHandler::singleton, v, nullptr, options); - if (!obj) { - return nullptr; - } - - if (!cpows_.add(objId, obj)) { - return nullptr; - } - - nextCPOWNumber_ = objId.serialNumber() + 1; - - // Incref once we know the decref will be called. - incref(); - - AuxCPOWData* aux = - new AuxCPOWData(objId, objVar.isCallable(), objVar.isConstructor()); - - SetProxyReservedSlot(obj, 0, PrivateValue(this)); - SetProxyReservedSlot(obj, 1, PrivateValue(aux)); - } - - if (!JS_WrapObject(cx, &obj)) { - return nullptr; - } - return obj; -} - -JSObject* WrapperOwner::fromLocalObjectVariant(JSContext* cx, - const LocalObject& objVar) { - Maybe id(ObjectId::deserialize(objVar.serializedId())); - if (id.isNothing()) { - return nullptr; - } - Rooted obj(cx, findObjectById(cx, id.value())); - if (!obj) { - return nullptr; - } - if (!JS_WrapObject(cx, &obj)) { - return nullptr; - } - return obj; -} diff --git a/js/ipc/WrapperOwner.h b/js/ipc/WrapperOwner.h deleted file mode 100644 index b6d3b777cb79..000000000000 --- a/js/ipc/WrapperOwner.h +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * vim: set ts=8 sw=2 et tw=80: - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_jsipc_WrapperOwner_h__ -#define mozilla_jsipc_WrapperOwner_h__ - -#include "JavaScriptShared.h" -#include "mozilla/ipc/ProtocolUtils.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" -#include "js/Class.h" -#include "js/Proxy.h" - -namespace mozilla { -namespace jsipc { - -class WrapperOwner : public virtual JavaScriptShared { - public: - using ActorDestroyReason = mozilla::ipc::IProtocol::ActorDestroyReason; - - WrapperOwner(); - - // Standard internal methods. - // (The traps should be in the same order like js/Proxy.h) - bool getOwnPropertyDescriptor(JSContext* cx, JS::HandleObject proxy, - JS::HandleId id, - JS::MutableHandle desc); - bool defineProperty(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, - JS::Handle desc, - JS::ObjectOpResult& result); - bool ownPropertyKeys(JSContext* cx, JS::HandleObject proxy, - JS::MutableHandleIdVector 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::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 hasOwn(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, bool* bp); - bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::HandleObject proxy, - JS::MutableHandleIdVector props); - bool hasInstance(JSContext* cx, JS::HandleObject proxy, - JS::MutableHandleValue v, bool* bp); - bool getBuiltinClass(JSContext* cx, JS::HandleObject proxy, js::ESClass* cls); - bool isArray(JSContext* cx, JS::HandleObject proxy, - JS::IsArrayAnswer* answer); - const char* className(JSContext* cx, JS::HandleObject proxy); - bool getPrototype(JSContext* cx, JS::HandleObject proxy, - JS::MutableHandleObject protop); - bool getPrototypeIfOrdinary(JSContext* cx, JS::HandleObject proxy, - bool* isOrdinary, JS::MutableHandleObject protop); - - js::RegExpShared* regexp_toShared(JSContext* cx, JS::HandleObject proxy); - - nsresult instanceOf(JSObject* obj, const nsID* id, bool* bp); - - bool toString(JSContext* cx, JS::HandleObject callee, JS::CallArgs& args); - - /* - * Check that |obj| is a DOM wrapper whose prototype chain contains - * |prototypeID| at depth |depth|. - */ - bool domInstanceOf(JSContext* cx, JSObject* obj, int prototypeID, int depth, - bool* bp); - - bool active() { return !inactive_; } - - virtual bool allowMessage(JSContext* cx) = 0; - - void drop(JSObject* obj); - void updatePointer(JSObject* obj, const JSObject* old); - - virtual void ActorDestroy(ActorDestroyReason why); - - virtual bool toObjectVariant(JSContext* cx, JSObject* obj, - ObjectVariant* objVarp) override; - virtual JSObject* fromObjectVariant(JSContext* cx, - const ObjectVariant& objVar) override; - JSObject* fromRemoteObjectVariant(JSContext* cx, const RemoteObject& objVar); - JSObject* fromLocalObjectVariant(JSContext* cx, const LocalObject& objVar); - - protected: - ObjectId idOf(JSObject* obj); - - private: - ObjectId idOfUnchecked(JSObject* obj); - - bool getPropertyKeys(JSContext* cx, JS::HandleObject proxy, uint32_t flags, - JS::MutableHandleIdVector props); - - // Catastrophic IPC failure. - bool ipcfail(JSContext* cx); - - // Check whether a return status is okay, and if not, propagate its error. - // - // If 'status' might be a ReturnObjectOpResult, which is only possible for - // a subset of the operations below, 'result' must be passed. - bool ok(JSContext* cx, const ReturnStatus& status, - JS::ObjectOpResult& result); - bool ok(JSContext* cx, const ReturnStatus& status); - - bool inactive_; - - /*** Dummy call handlers ***/ - public: - virtual bool SendDropObject(const ObjectId& objId) = 0; - virtual bool SendPreventExtensions(const ObjectId& objId, - ReturnStatus* rs) = 0; - virtual bool SendGetOwnPropertyDescriptor(const ObjectId& objId, - const JSIDVariant& id, - ReturnStatus* rs, - PPropertyDescriptor* out) = 0; - virtual bool SendDefineProperty(const ObjectId& objId, const JSIDVariant& id, - const PPropertyDescriptor& flags, - 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 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& argv, - const bool& construct, ReturnStatus* rs, - JSVariant* result, - nsTArray* outparams) = 0; - virtual bool SendHasInstance(const ObjectId& objId, const JSVariant& v, - ReturnStatus* rs, bool* bp) = 0; - virtual bool SendGetBuiltinClass(const ObjectId& objId, ReturnStatus* rs, - uint32_t* classValue) = 0; - virtual bool SendIsArray(const ObjectId& objId, ReturnStatus* rs, - uint32_t* answer) = 0; - virtual bool SendClassName(const ObjectId& objId, nsCString* result) = 0; - virtual bool SendGetPrototype(const ObjectId& objId, ReturnStatus* rs, - ObjectOrNullVariant* result) = 0; - virtual bool SendGetPrototypeIfOrdinary(const ObjectId& objId, - ReturnStatus* rs, bool* isOrdinary, - ObjectOrNullVariant* result) = 0; - virtual bool SendRegExpToShared(const ObjectId& objId, ReturnStatus* rs, - nsString* source, uint32_t* flags) = 0; - - virtual bool SendGetPropertyKeys(const ObjectId& objId, const uint32_t& flags, - ReturnStatus* rs, - nsTArray* ids) = 0; - virtual bool SendInstanceOf(const ObjectId& objId, const JSIID& iid, - ReturnStatus* rs, bool* instanceof) = 0; - virtual bool SendDOMInstanceOf(const ObjectId& objId, const int& prototypeID, - const int& depth, ReturnStatus* rs, - bool* instanceof) = 0; -}; - -} // namespace jsipc -} // namespace mozilla - -#endif // mozilla_jsipc_WrapperOwner_h__ diff --git a/js/ipc/moz.build b/js/ipc/moz.build deleted file mode 100644 index 72865894b089..000000000000 --- a/js/ipc/moz.build +++ /dev/null @@ -1,40 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -UNIFIED_SOURCES += [ - 'JavaScriptChild.cpp', - 'JavaScriptParent.cpp', - 'JavaScriptShared.cpp', - 'WrapperAnswer.cpp', - 'WrapperOwner.cpp', -] - -IPDL_SOURCES += [ - 'JavaScriptTypes.ipdlh', - 'PJavaScript.ipdl', -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' - -DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX'] - -EXPORTS.mozilla.jsipc = [ - 'CpowHolder.h', - 'CrossProcessObjectWrappers.h', -] - -LOCAL_INCLUDES += [ - '/dom/base', - '/js/ipc', - '/js/src', - '/js/xpconnect/src', - '/js/xpconnect/wrappers', -] - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-shadow'] diff --git a/js/public/Proxy.h b/js/public/Proxy.h index a14ab619663a..ce86f0c975ea 100644 --- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -58,9 +58,6 @@ class JS_FRIEND_API Wrapper; * - DOM objects with special property behavior, like named getters * (dom/bindings/Codegen.py generates these proxies from WebIDL) * - * - semi-transparent use of objects that live in other processes - * (CPOWs, implemented in js/ipc) - * * ### Proxies and internal methods * * ES2019 specifies 13 internal methods. The runtime semantics of just about diff --git a/js/src/devtools/rootAnalysis/build.js b/js/src/devtools/rootAnalysis/build.js index 34cf6f365627..902ae1e32f2b 100644 --- a/js/src/devtools/rootAnalysis/build.js +++ b/js/src/devtools/rootAnalysis/build.js @@ -9,7 +9,7 @@ set -e cd $SOURCE ./mach configure ./mach build export -./mach build -X nsprpub mfbt memory memory/mozalloc modules/zlib mozglue js/src xpcom/glue js/ductwork/debugger js/ipc js/xpconnect/loader js/xpconnect/wrappers js/xpconnect/src +./mach build -X nsprpub mfbt memory memory/mozalloc modules/zlib mozglue js/src xpcom/glue js/ductwork/debugger js/xpconnect/loader js/xpconnect/wrappers js/xpconnect/src status=$? echo "[[[[ build.js complete, exit code $status ]]]]" exit $status diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index ad8ad59506cf..bb310e45bb1d 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -30,7 +30,6 @@ #include "mozilla/dom/DOMException.h" #include "mozilla/dom/PrimitiveConversions.h" #include "mozilla/dom/Promise.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" using namespace xpc; using namespace mozilla; @@ -46,22 +45,6 @@ using namespace JS; #define ILLEGAL_CHAR_RANGE(c) (0 != ((c)&0x80)) -/***********************************************************/ - -static JSObject* UnwrapNativeCPOW(nsISupports* wrapper) { - nsCOMPtr underware = do_QueryInterface(wrapper); - if (underware) { - // The analysis falsely believes that ~nsCOMPtr can GC because it could - // drop the refcount to zero, but that can't happen here. - JS::AutoSuppressGCAnalysis nogc; - JSObject* mainObj = underware->GetJSObject(); - if (mainObj && mozilla::jsipc::IsWrappedCPOW(mainObj)) { - return mainObj; - } - } - return nullptr; -} - /***************************************************************************/ // static @@ -956,19 +939,6 @@ bool XPCConvert::NativeInterface2JSObject(JSContext* cx, MutableHandleValue d, } } - // Don't double wrap CPOWs. This is a temporary measure for compatibility - // with objects that don't provide necessary QIs (such as objects under - // the new DOM bindings). We expect the other side of the CPOW to have - // the appropriate wrappers in place. - RootedObject cpow(cx, UnwrapNativeCPOW(aHelper.Object())); - if (cpow) { - if (!JS_WrapObject(cx, &cpow)) { - return false; - } - d.setObject(*cpow); - return true; - } - // Go ahead and create an XPCWrappedNative for this object. RefPtr iface = XPCNativeInterface::GetNewOrUsed(cx, iid); if (!iface) { diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index b8d591539a08..bc0293b82a4e 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -44,7 +44,6 @@ #include "mozilla/dom/ScriptLoader.h" #include "mozilla/dom/WindowBinding.h" #include "mozilla/extensions/WebExtensionPolicy.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/ProcessHangMonitor.h" @@ -1341,7 +1340,6 @@ void XPCJSContext::AfterProcessTask(uint32_t aNewRecursionDepth) { MOZ_ASSERT(NS_IsMainThread()); nsJSContext::MaybePokeCC(); CycleCollectedJSContext::AfterProcessTask(aNewRecursionDepth); - mozilla::jsipc::AfterProcessTask(); // This exception might have been set if we called an XPCWrappedJS that threw, // but now we're returning to the event loop, so nothing is going to look at diff --git a/js/xpconnect/src/XPCJSID.cpp b/js/xpconnect/src/XPCJSID.cpp index 991ebda6f5b6..addc995977dd 100644 --- a/js/xpconnect/src/XPCJSID.cpp +++ b/js/xpconnect/src/XPCJSID.cpp @@ -9,7 +9,6 @@ #include "xpcprivate.h" #include "mozilla/dom/BindingUtils.h" #include "mozilla/Attributes.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "js/Symbol.h" using namespace mozilla::dom; @@ -370,7 +369,6 @@ static bool ID_Equals(JSContext* aCx, unsigned aArgc, Value* aVp) { */ static nsresult FindObjectForHasInstance(JSContext* cx, HandleObject objArg, MutableHandleObject target) { - using namespace mozilla::jsipc; RootedObject obj(cx, objArg), proto(cx); while (true) { // Try the object, or the wrappee if allowed. We want CheckedUnwrapDynamic @@ -378,7 +376,7 @@ static nsresult FindObjectForHasInstance(JSContext* cx, HandleObject objArg, // our current global. JSObject* o = js::IsWrapper(obj) ? js::CheckedUnwrapDynamic(obj, cx, false) : obj; - if (o && (IS_WN_REFLECTOR(o) || IsDOMObject(o) || IsCPOW(o))) { + if (o && (IS_WN_REFLECTOR(o) || IsDOMObject(o))) { target.set(o); return NS_OK; } @@ -410,10 +408,6 @@ nsresult HasInstance(JSContext* cx, HandleObject objArg, const nsID* iid, return NS_OK; } - if (mozilla::jsipc::IsCPOW(obj)) { - return mozilla::jsipc::InstanceOf(obj, iid, bp); - } - // Need to unwrap Window correctly here, so use ReflectorToISupportsDynamic. nsCOMPtr identity = ReflectorToISupportsDynamic(obj, cx); if (!identity) { diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 29201c51b2b6..d9a583a36fc1 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -57,7 +57,6 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/WindowBinding.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/ProcessHangMonitor.h" diff --git a/js/xpconnect/src/XPCWrappedJS.cpp b/js/xpconnect/src/XPCWrappedJS.cpp index 4dbd7727581f..1b4cb528f363 100644 --- a/js/xpconnect/src/XPCWrappedJS.cpp +++ b/js/xpconnect/src/XPCWrappedJS.cpp @@ -9,7 +9,6 @@ #include "xpcprivate.h" #include "mozilla/DeferredFinalize.h" #include "mozilla/Sprintf.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsCCUncollectableMarker.h" #include "nsContentUtils.h" #include "nsThreadUtils.h" diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 2022a90fe002..2086648ed049 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -20,7 +20,6 @@ #include "mozilla/dom/DOMException.h" #include "mozilla/dom/DOMExceptionBinding.h" #include "mozilla/dom/MozQueryInterface.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "jsapi.h" #include "jsfriendapi.h" diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index ffc7df8b1da5..60a4cab966ad 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -7,7 +7,6 @@ /* Wrapper object for reflecting native xpcom objects into JavaScript. */ #include "xpcprivate.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsWrapperCacheInlines.h" #include "XPCLog.h" #include "js/Array.h" // JS::GetArrayLength, JS::IsArrayObject @@ -1537,19 +1536,6 @@ bool CallMethodHelper::ConvertIndependentParam(uint8_t i) { param_iid = inner.GetInterface()->IID(); } - // Don't allow CPOWs to be passed to native code (in case they try to cast - // to a concrete type). - if (src.isObject() && jsipc::IsWrappedCPOW(&src.toObject()) && - type.Tag() == nsXPTType::T_INTERFACE && - !param_iid.Equals(NS_GET_IID(nsISupports))) { - // Allow passing CPOWs to XPCWrappedJS. - nsCOMPtr wrappedJS(do_QueryInterface(mCallee)); - if (!wrappedJS) { - ThrowBadParam(NS_ERROR_XPC_CANT_PASS_CPOW_TO_NATIVE, i, mCallContext); - return false; - } - } - nsresult err; if (!XPCConvert::JSData2Native(mCallContext, &dp->val, src, type, ¶m_iid, 0, &err)) { diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp index b65864602f05..6019b6e7070b 100644 --- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -19,7 +19,6 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/LocationBinding.h" #include "mozilla/dom/WindowBinding.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsJSUtils.h" #include "xpcprivate.h" @@ -100,16 +99,6 @@ bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, return true; } - // CPOWs use COWs (in the unprivileged junk scope) for all child->parent - // references. Without this test, the child process wouldn't be able to - // pass any objects at all to CPOWs. - if (mozilla::jsipc::IsWrappedCPOW(obj) && - js::GetObjectCompartment(wrapper) == - js::GetObjectCompartment(xpc::UnprivilegedJunkScope()) && - XRE_IsParentProcess()) { - return true; - } - // Same-origin wrappers are fine. if (AccessCheck::wrapperSubsumes(obj)) { return true; diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index ceb62ccd5556..4bb7647746f7 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -16,7 +16,6 @@ #include "XPCMaps.h" #include "mozilla/dom/BindingUtils.h" #include "jsfriendapi.h" -#include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "mozilla/Likely.h" #include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/MaybeCrossOriginObject.h" @@ -543,11 +542,8 @@ JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, // Special handling for chrome objects being exposed to content. else if (originIsChrome && !targetIsChrome) { // If this is a chrome function being exposed to content, we need to allow - // call (but nothing else). We allow CPOWs that purport to be function's - // here, but only in the content process. - if ((IdentifyStandardInstance(obj) == JSProto_Function || - (jsipc::IsCPOW(obj) && JS::IsCallable(obj) && - XRE_IsContentProcess()))) { + // call (but nothing else). + if ((IdentifyStandardInstance(obj) == JSProto_Function)) { wrapper = &FilteringWrapper::singleton; } diff --git a/toolkit/toolkit.mozbuild b/toolkit/toolkit.mozbuild index 299230cb3bde..d092b8b22346 100644 --- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -74,7 +74,6 @@ if CONFIG['MOZ_UPDATER'] and CONFIG['OS_TARGET'] != 'Android': DIRS += [ '/ipc', - '/js/ipc', '/hal', '/js/xpconnect', '/modules/libjar',