Bug 1170771 - Remove ThisTranslator and support code. r?bz draft
authorAdrian Wielgosik <adrian.wielgosik@gmail.com>
Thu, 05 Apr 2018 12:49:24 +0200
changeset 778811 00515f0b4424b6233807ff164f5372e899a61857
parent 777984 110f32790d38a258cab722064aae40736478ef51
child 778812 7fa6940c20bdab80209d281e3c8da4c2933a61da
push id105584
push userbmo:adrian.wielgosik@gmail.com
push dateFri, 06 Apr 2018 21:49:19 +0000
reviewersbz
bugs1170771
milestone61.0a1
Bug 1170771 - Remove ThisTranslator and support code. r?bz MozReview-Commit-ID: Fv0F4RLCnkL
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
js/xpconnect/idl/nsIXPConnect.idl
js/xpconnect/src/XPCForwards.h
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCMaps.h
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -91,46 +91,19 @@ nsDOMClassInfo::Init()
   /* Errors that can trigger early returns are done first,
      otherwise nsDOMClassInfo is left in a half inited state. */
   static_assert(sizeof(uintptr_t) == sizeof(void*),
                 "BAD! You'll need to adjust the size of uintptr_t to the "
                 "size of a pointer on your platform.");
 
   NS_ENSURE_TRUE(!sIsInitialized, NS_ERROR_ALREADY_INITIALIZED);
 
-  nsCOMPtr<nsIXPCFunctionThisTranslator> elt = new nsEventListenerThisTranslator();
-  nsContentUtils::XPConnect()->SetFunctionThisTranslator(NS_GET_IID(nsIDOMEventListener), elt);
-
   sIsInitialized = true;
 
   return NS_OK;
 }
 
 // static
 void
 nsDOMClassInfo::ShutDown()
 {
   sIsInitialized = false;
 }
-
-// nsIDOMEventListener::HandleEvent() 'this' converter helper
-
-NS_INTERFACE_MAP_BEGIN(nsEventListenerThisTranslator)
-  NS_INTERFACE_MAP_ENTRY(nsIXPCFunctionThisTranslator)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-
-NS_IMPL_ADDREF(nsEventListenerThisTranslator)
-NS_IMPL_RELEASE(nsEventListenerThisTranslator)
-
-
-NS_IMETHODIMP
-nsEventListenerThisTranslator::TranslateThis(nsISupports *aInitialThis,
-                                             nsISupports **_retval)
-{
-  nsCOMPtr<nsIDOMEvent> event(do_QueryInterface(aInitialThis));
-  NS_ENSURE_TRUE(event, NS_ERROR_UNEXPECTED);
-
-  nsCOMPtr<EventTarget> target = event->InternalDOMEvent()->GetCurrentTarget();
-  target.forget(_retval);
-  return NS_OK;
-}
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -19,34 +19,9 @@ class nsDOMClassInfo
 public:
   static nsresult Init();
   static void ShutDown();
 
 protected:
   static bool sIsInitialized;
 };
 
-// Event handler 'this' translator class, this is called by XPConnect
-// when a "function interface" (nsIDOMEventListener) is called, this
-// class extracts 'this' fomr the first argument to the called
-// function (nsIDOMEventListener::HandleEvent(in nsIDOMEvent)), this
-// class will pass back nsIDOMEvent::currentTarget to be used as
-// 'this'.
-
-class nsEventListenerThisTranslator : public nsIXPCFunctionThisTranslator
-{
-  virtual ~nsEventListenerThisTranslator()
-  {
-  }
-
-public:
-  nsEventListenerThisTranslator()
-  {
-  }
-
-  // nsISupports
-  NS_DECL_ISUPPORTS
-
-  // nsIXPCFunctionThisTranslator
-  NS_DECL_NSIXPCFUNCTIONTHISTRANSLATOR
-};
-
 #endif /* nsDOMClassInfo_h___ */
--- a/js/xpconnect/idl/nsIXPConnect.idl
+++ b/js/xpconnect/idl/nsIXPConnect.idl
@@ -181,63 +181,16 @@ interface nsIXPConnectWrappedJSUnmarkGra
 [scriptable, uuid(254bb2e0-6439-11d4-8fe0-0010a4e73d9a)]
 interface nsIXPCWrappedJSObjectGetter : nsISupports
 {
     readonly attribute nsISupports neverCalled;
 };
 
 /***************************************************************************/
 
-/*
- * This interface is implemented by outside code and registered with xpconnect
- * via nsIXPConnect::setFunctionThisTranslator.
- *
- * The reason this exists is to support calls to JavaScript event callbacks
- * needed by the DOM via xpconnect from C++ code.
- *
- * We've added support for wrapping JS function objects as xpcom interfaces
- * by declaring the given interface as a [function] interface. However, to
- * support the requirements of JS event callbacks we need to call the JS
- * function with the 'this' set as the JSObject for which the event is being
- * fired; e.g. a form node.
- *
- * We've decided that for all cases we care about the appropriate 'this' object
- * can be derived from the first param in the call to the callback. In the
- * event handler case the first param is an event object.
- *
- * Though we can't change all the JS code so that it would setup its own 'this',
- * we can add plugin 'helper' support to xpconnect. And that is what we have
- * here.
- *
- * The idea is that at startup time some code that cares about this issue
- * (e.g. the DOM helper code) can register a nsIXPCFunctionThisTranslator
- * object with xpconnect to handle calls to [function] interfaces of a given
- * iid. When xpconnect goes to invoke a method on a wrapped JSObject for
- * an interface marked as [function], xpconnect will check if the first param
- * of the method is an xpcom object pointer and if so it will check to see if a
- * nsIXPCFunctionThisTranslator has been registered for the given iid of the
- * interface being called. If so it will call the translator and get an
- * interface pointer to use as the 'this' for the call. If the translator
- * returns a non-null interface pointer (which it should then have addref'd
- * since it is being returned as an out param), xpconnect will attempt to build
- * a wrapper around the pointer and get a JSObject from that wrapper to use
- * as the 'this' for the call.
- *
- * If a null interface pointer is returned then xpconnect will use the default
- * 'this' - the same JSObject as the function object it is calling.
- */
-
-[uuid(f5f84b70-92eb-41f1-a1dd-2eaac0ed564c)]
-interface nsIXPCFunctionThisTranslator : nsISupports
-{
-    nsISupports TranslateThis(in nsISupports aInitialThis);
-};
-
-/***************************************************************************/
-
 
 %{ C++
 // For use with the service manager
 // {CB6593E0-F9B2-11d2-BDD6-000064657374}
 #define NS_XPCONNECT_CID \
 { 0xcb6593e0, 0xf9b2, 0x11d2, \
     { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
 %}
@@ -369,20 +322,16 @@ interface nsIXPConnect : nsISupports
     wrapJSAggregatedToNative(in nsISupports  aOuter,
                              in JSContextPtr aJSContext,
                              in JSObjectPtr  aJSObj,
                              in nsIIDRef     aIID,
                              [iid_is(aIID),retval] out nsQIResult result);
 
     // Methods added since mozilla 0.6....
 
-    void
-    setFunctionThisTranslator(in nsIIDRef aIID,
-                              in nsIXPCFunctionThisTranslator aTranslator);
-
     JSObjectPtr
     getWrappedNativePrototype(in JSContextPtr aJSContext,
                               in JSObjectPtr  aScope,
                               in nsIClassInfo aClassInfo);
 
     jsval variantToJS(in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value);
     nsIVariant JSToVariant(in JSContextPtr ctx, in jsval value);
 
--- a/js/xpconnect/src/XPCForwards.h
+++ b/js/xpconnect/src/XPCForwards.h
@@ -34,17 +34,16 @@ class XPCTraceableVariant;
 
 class JSObject2WrappedJSMap;
 class Native2WrappedNativeMap;
 class IID2WrappedJSClassMap;
 class IID2NativeInterfaceMap;
 class ClassInfo2NativeSetMap;
 class ClassInfo2WrappedNativeProtoMap;
 class NativeSetMap;
-class IID2ThisTranslatorMap;
 class XPCWrappedNativeProtoMap;
 class JSObject2JSObjectMap;
 
 class nsXPCComponents;
 class nsXPCComponents_Interfaces;
 class nsXPCComponents_InterfacesByID;
 class nsXPCComponents_Classes;
 class nsXPCComponents_ClassesByID;
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1046,19 +1046,16 @@ XPCJSRuntime::Shutdown(JSContext* cx)
     mIID2NativeInterfaceMap = nullptr;
 
     delete mClassInfo2NativeSetMap;
     mClassInfo2NativeSetMap = nullptr;
 
     delete mNativeSetMap;
     mNativeSetMap = nullptr;
 
-    delete mThisTranslatorMap;
-    mThisTranslatorMap = nullptr;
-
     delete mDyingWrappedNativeProtoMap;
     mDyingWrappedNativeProtoMap = nullptr;
 
     CycleCollectedJSRuntime::Shutdown(cx);
 }
 
 XPCJSRuntime::~XPCJSRuntime()
 {
@@ -2750,17 +2747,16 @@ static const JSWrapObjectCallbacks WrapO
 
 XPCJSRuntime::XPCJSRuntime(JSContext* aCx)
  : CycleCollectedJSRuntime(aCx),
    mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH)),
    mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_LENGTH)),
    mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_LENGTH)),
    mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)),
    mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH)),
-   mThisTranslatorMap(IID2ThisTranslatorMap::newMap(XPC_THIS_TRANSLATOR_MAP_LENGTH)),
    mDyingWrappedNativeProtoMap(XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_LENGTH)),
    mGCIsRunning(false),
    mNativesToReleaseArray(),
    mDoingFinalization(false),
    mVariantRoots(nullptr),
    mWrappedJSRoots(nullptr),
    mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite())
 {
@@ -2942,19 +2938,16 @@ XPCJSRuntime::DebugDump(int16_t depth)
         XPC_LOG_ALWAYS(("mIID2NativeInterfaceMap @ %p with %d interface(s)",
                         mIID2NativeInterfaceMap,
                         mIID2NativeInterfaceMap->Count()));
 
         XPC_LOG_ALWAYS(("mClassInfo2NativeSetMap @ %p with %d sets(s)",
                         mClassInfo2NativeSetMap,
                         mClassInfo2NativeSetMap->Count()));
 
-        XPC_LOG_ALWAYS(("mThisTranslatorMap @ %p with %d translator(s)",
-                        mThisTranslatorMap, mThisTranslatorMap->Count()));
-
         XPC_LOG_ALWAYS(("mNativeSetMap @ %p with %d sets(s)",
                         mNativeSetMap, mNativeSetMap->Count()));
 
         // iterate sets...
         if (depth && mNativeSetMap->Count()) {
             XPC_LOG_INDENT();
             for (auto i = mNativeSetMap->Iter(); !i.Done(); i.Next()) {
                 auto entry = static_cast<NativeSetMap::Entry*>(i.Get());
--- a/js/xpconnect/src/XPCMaps.cpp
+++ b/js/xpconnect/src/XPCMaps.cpp
@@ -334,53 +334,16 @@ NativeSetMap::SizeOfIncludingThis(mozill
     for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
         auto entry = static_cast<NativeSetMap::Entry*>(iter.Get());
         n += entry->key_value->SizeOfIncludingThis(mallocSizeOf);
     }
     return n;
 }
 
 /***************************************************************************/
-// implement IID2ThisTranslatorMap...
-
-bool
-IID2ThisTranslatorMap::Entry::Match(const PLDHashEntryHdr* entry,
-                                    const void* key)
-{
-    return ((const nsID*)key)->Equals(((Entry*)entry)->key);
-}
-
-void
-IID2ThisTranslatorMap::Entry::Clear(PLDHashTable* table, PLDHashEntryHdr* entry)
-{
-    static_cast<Entry*>(entry)->value = nullptr;
-    memset(entry, 0, table->EntrySize());
-}
-
-const struct PLDHashTableOps IID2ThisTranslatorMap::Entry::sOps =
-{
-    HashIIDPtrKey,
-    Match,
-    PLDHashTable::MoveEntryStub,
-    Clear
-};
-
-// static
-IID2ThisTranslatorMap*
-IID2ThisTranslatorMap::newMap(int length)
-{
-    return new IID2ThisTranslatorMap(length);
-}
-
-IID2ThisTranslatorMap::IID2ThisTranslatorMap(int length)
-  : mTable(&Entry::sOps, sizeof(Entry), length)
-{
-}
-
-/***************************************************************************/
 // implement XPCWrappedNativeProtoMap...
 
 // static
 XPCWrappedNativeProtoMap*
 XPCWrappedNativeProtoMap::newMap(int length)
 {
     return new XPCWrappedNativeProtoMap(length);
 }
--- a/js/xpconnect/src/XPCMaps.h
+++ b/js/xpconnect/src/XPCMaps.h
@@ -453,71 +453,16 @@ private:
     explicit NativeSetMap(int size);
 
 private:
     PLDHashTable mTable;
 };
 
 /***************************************************************************/
 
-class IID2ThisTranslatorMap
-{
-public:
-    struct Entry : public PLDHashEntryHdr
-    {
-        nsIID                                  key;
-        nsCOMPtr<nsIXPCFunctionThisTranslator> value;
-
-        static bool
-        Match(const PLDHashEntryHdr* entry, const void* key);
-
-        static void
-        Clear(PLDHashTable* table, PLDHashEntryHdr* entry);
-
-        static const struct PLDHashTableOps sOps;
-    };
-
-    static IID2ThisTranslatorMap* newMap(int length);
-
-    inline nsIXPCFunctionThisTranslator* Find(REFNSIID iid)
-    {
-        auto entry = static_cast<Entry*>(mTable.Search(&iid));
-        if (!entry) {
-            return nullptr;
-        }
-        return entry->value;
-    }
-
-    inline nsIXPCFunctionThisTranslator* Add(REFNSIID iid,
-                                             nsIXPCFunctionThisTranslator* obj)
-    {
-        auto entry = static_cast<Entry*>(mTable.Add(&iid, mozilla::fallible));
-        if (!entry)
-            return nullptr;
-        entry->value = obj;
-        entry->key = iid;
-        return obj;
-    }
-
-    inline void Remove(REFNSIID iid)
-    {
-        mTable.Remove(&iid);
-    }
-
-    inline uint32_t Count() { return mTable.EntryCount(); }
-
-private:
-    IID2ThisTranslatorMap();    // no implementation
-    explicit IID2ThisTranslatorMap(int size);
-private:
-    PLDHashTable mTable;
-};
-
-/***************************************************************************/
-
 class XPCWrappedNativeProtoMap
 {
 public:
     typedef PLDHashEntryStub Entry;
 
     static XPCWrappedNativeProtoMap* newMap(int length);
 
     inline XPCWrappedNativeProto* Add(XPCWrappedNativeProto* proto)
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -984,21 +984,16 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     uint8_t i;
     nsresult retval = NS_ERROR_FAILURE;
     bool success;
     bool readyToDoTheCall = false;
     nsID  param_iid;
     const char* name = info->GetName();
     bool foundDependentParam;
 
-    // Make sure not to set the callee on ccx until after we've gone through
-    // the whole nsIXPCFunctionThisTranslator bit.  That code uses ccx to
-    // convert natives to JSObjects, but we do NOT plan to pass those JSObjects
-    // to our real callee.
-    //
     // We're about to call into script via an XPCWrappedJS, so we need an
     // AutoEntryScript. This is probably Gecko-specific at this point, and
     // definitely will be when we turn off XPConnect for the web.
     nsIGlobalObject* nativeGlobal =
       NativeGlobal(js::GetGlobalForObjectCrossCompartment(wrapper->GetJSObject()));
     AutoEntryScript aes(nativeGlobal, "XPCWrappedJS method call",
                         /* aIsMainThread = */ true);
     XPCCallContext ccx(aes.cx());
@@ -1070,59 +1065,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
         //
         // In the normal (non-function) case we just lookup the property by
         // name and as long as the object has such a named property we go ahead
         // and try to make the call. If it turns out the named property is not
         // a callable object then the JS engine will throw an error and we'll
         // pass this along to the caller as an exception/result code.
 
         fval = ObjectValue(*obj);
-        if (isFunction &&
-            JS_TypeOfValue(ccx, fval) == JSTYPE_FUNCTION) {
-
-            // We may need to translate the 'this' for the function object.
-
-            if (paramCount) {
-                const nsXPTParamInfo& firstParam = info->GetParam(0);
-                if (firstParam.IsIn()) {
-                    const nsXPTType& firstType = firstParam.GetType();
-
-                    if (firstType.IsInterfacePointer()) {
-                        nsIXPCFunctionThisTranslator* translator;
-
-                        IID2ThisTranslatorMap* map =
-                            mRuntime->GetThisTranslatorMap();
-
-                        translator = map->Find(mIID);
-
-                        if (translator) {
-                            nsCOMPtr<nsISupports> newThis;
-                            if (NS_FAILED(translator->
-                                          TranslateThis((nsISupports*)nativeParams[0].val.p,
-                                                        getter_AddRefs(newThis)))) {
-                                goto pre_call_clean_up;
-                            }
-                            if (newThis) {
-                                RootedValue v(cx);
-                                xpcObjectHelper helper(newThis);
-                                bool ok =
-                                  XPCConvert::NativeInterface2JSObject(
-                                      &v, helper, nullptr, false, nullptr);
-                                if (!ok) {
-                                    goto pre_call_clean_up;
-                                }
-                                thisObj = v.toObjectOrNull();
-                                if (!JS_WrapObject(cx, &thisObj))
-                                    goto pre_call_clean_up;
-                            }
-                        }
-                    }
-                }
-            }
-        } else {
+        if (!isFunction || JS_TypeOfValue(ccx, fval) != JSTYPE_FUNCTION) {
             if (!JS_GetProperty(cx, obj, name, &fval))
                 goto pre_call_clean_up;
             // XXX We really want to factor out the error reporting better and
             // specifically report the failure to find a function with this name.
             // This is what we do below if the property is found but is not a
             // function. We just need to factor better so we can get to that
             // reporting path from here.
 
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -749,26 +749,16 @@ xpc::UnwrapReflectorToISupports(JSObject
     // this if non-null our thing will definitely be a DOM object, and we know
     // their QI to nsISupports doesn't do anything weird.
     nsCOMPtr<nsISupports> canonical =
         do_QueryInterface(mozilla::dom::UnwrapDOMObjectToISupports(reflector));
     return canonical.forget();
 }
 
 NS_IMETHODIMP
-nsXPConnect::SetFunctionThisTranslator(const nsIID & aIID,
-                                       nsIXPCFunctionThisTranslator* aTranslator)
-{
-    XPCJSRuntime* rt = GetRuntimeInstance();
-    IID2ThisTranslatorMap* map = rt->GetThisTranslatorMap();
-    map->Add(aIID, aTranslator);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsXPConnect::CreateSandbox(JSContext* cx, nsIPrincipal* principal,
                            JSObject** _retval)
 {
     *_retval = nullptr;
 
     RootedValue rval(cx);
     SandboxOptions options;
     nsresult rv = CreateSandboxObject(cx, &rval, principal, options);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -172,17 +172,16 @@ class Exception;
 #define XPC_JS_MAP_LENGTH                       32
 #define XPC_JS_CLASS_MAP_LENGTH                 32
 
 #define XPC_NATIVE_MAP_LENGTH                    8
 #define XPC_NATIVE_PROTO_MAP_LENGTH              8
 #define XPC_DYING_NATIVE_PROTO_MAP_LENGTH        8
 #define XPC_NATIVE_INTERFACE_MAP_LENGTH         32
 #define XPC_NATIVE_SET_MAP_LENGTH               32
-#define XPC_THIS_TRANSLATOR_MAP_LENGTH           4
 #define XPC_WRAPPER_MAP_LENGTH                   8
 
 /***************************************************************************/
 // data declarations...
 extern const char XPC_CONTEXT_STACK_CONTRACTID[];
 extern const char XPC_EXCEPTION_CONTRACTID[];
 extern const char XPC_CONSOLE_CONTRACTID[];
 extern const char XPC_SCRIPT_ERROR_CONTRACTID[];
@@ -545,19 +544,16 @@ public:
         {return mIID2NativeInterfaceMap;}
 
     ClassInfo2NativeSetMap* GetClassInfo2NativeSetMap() const
         {return mClassInfo2NativeSetMap;}
 
     NativeSetMap* GetNativeSetMap() const
         {return mNativeSetMap;}
 
-    IID2ThisTranslatorMap* GetThisTranslatorMap() const
-        {return mThisTranslatorMap;}
-
     XPCWrappedNativeProtoMap* GetDyingWrappedNativeProtoMap() const
         {return mDyingWrappedNativeProtoMap;}
 
     bool InitializeStrings(JSContext* cx);
 
     virtual bool
     DescribeCustomObjects(JSObject* aObject, const js::Class* aClasp,
                           char (&aName)[72]) const override;
@@ -649,17 +645,16 @@ private:
     jsid mStrIDs[XPCJSContext::IDX_TOTAL_COUNT];
     JS::Value mStrJSVals[XPCJSContext::IDX_TOTAL_COUNT];
 
     JSObject2WrappedJSMap*   mWrappedJSMap;
     IID2WrappedJSClassMap*   mWrappedJSClassMap;
     IID2NativeInterfaceMap*  mIID2NativeInterfaceMap;
     ClassInfo2NativeSetMap*  mClassInfo2NativeSetMap;
     NativeSetMap*            mNativeSetMap;
-    IID2ThisTranslatorMap*   mThisTranslatorMap;
     XPCWrappedNativeProtoMap* mDyingWrappedNativeProtoMap;
     bool mGCIsRunning;
     nsTArray<nsISupports*> mNativesToReleaseArray;
     bool mDoingFinalization;
     XPCRootSetElem* mVariantRoots;
     XPCRootSetElem* mWrappedJSRoots;
     nsTArray<xpcGCCallback> extraGCCallbacks;
     JS::GCSliceCallback mPrevGCSliceCallback;