Bug 1441217 - Use nsXPTMethodInfo instead of XPTMethodDescriptor in XPConnect. r=njn draft
authorAndrew McCreight <continuation@gmail.com>
Mon, 26 Feb 2018 08:19:02 -0800
changeset 759829 a30c0eaa9402df71d2b7105094c3918e36931182
parent 759828 4ee93db26e075b4a641f40f1abcd4bceffade098
child 759901 7be4e22947beb2f78293687ebfe33d0c0d779c9c
push id100478
push userbmo:continuation@gmail.com
push dateMon, 26 Feb 2018 17:27:08 +0000
reviewersnjn
bugs1441217
milestone60.0a1
Bug 1441217 - Use nsXPTMethodInfo instead of XPTMethodDescriptor in XPConnect. r=njn nsXPTMethodInfo is a nicer structure to use, and this paves the way for making the two types different, which will be needed if I make XPTMethodDescriptor statically allocated. Also, use the higher level accessor methods. MozReview-Commit-ID: JbRdLU5Wwyt
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/xpcprivate.h
xpcom/reflect/xptcall/xptcall.h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -43,23 +43,23 @@ using namespace JS;
 #endif // STRICT_CHECK_OF_UNICODE
 
 #define ILLEGAL_CHAR_RANGE(c) (0!=((c) & 0x80))
 
 /***********************************************************/
 
 // static
 bool
-XPCConvert::IsMethodReflectable(const XPTMethodDescriptor& info)
+XPCConvert::IsMethodReflectable(const nsXPTMethodInfo& info)
 {
-    if (XPT_MD_IS_NOTXPCOM(info.flags) || XPT_MD_IS_HIDDEN(info.flags))
+    if (info.IsNotXPCOM() || info.IsHidden())
         return false;
 
-    for (int i = info.num_args-1; i >= 0; i--) {
-        const nsXPTParamInfo& param = info.params[i];
+    for (int i = info.GetParamCount() - 1; i >= 0; i--) {
+        const nsXPTParamInfo& param = info.GetParam(i);
         const nsXPTType& type = param.GetType();
 
         // Reflected methods can't use native types. All native types end up
         // getting tagged as void*, so this check is easy.
         if (type.TagPart() == nsXPTType::T_VOID)
             return false;
     }
     return true;
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -598,17 +598,17 @@ nsXPCWrappedJS::GetInterfaceInfo(nsIInte
     if (!info)
         return NS_ERROR_UNEXPECTED;
     info.forget(infoResult);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::CallMethod(uint16_t methodIndex,
-                           const XPTMethodDescriptor* info,
+                           const nsXPTMethodInfo* info,
                            nsXPTCMiniVariant* params)
 {
     // Do a release-mode assert against accessing nsXPCWrappedJS off-main-thread.
     MOZ_RELEASE_ASSERT(NS_IsMainThread(),
                        "nsXPCWrappedJS::CallMethod called off main thread");
 
     if (!IsValid())
         return NS_ERROR_UNEXPECTED;
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -708,48 +708,48 @@ nsXPCWrappedJSClass::GetRootJSObject(JSC
     JSObject* inner = js::UncheckedUnwrap(result);
     if (inner)
         return inner;
     return result;
 }
 
 bool
 nsXPCWrappedJSClass::GetArraySizeFromParam(JSContext* cx,
-                                           const XPTMethodDescriptor* method,
+                                           const nsXPTMethodInfo* method,
                                            const nsXPTParamInfo& param,
                                            uint16_t methodIndex,
                                            uint8_t paramIndex,
                                            nsXPTCMiniVariant* nativeParams,
                                            uint32_t* result) const
 {
     uint8_t argnum;
     nsresult rv;
 
     rv = mInfo->GetSizeIsArgNumberForParam(methodIndex, &param, 0, &argnum);
     if (NS_FAILED(rv))
         return false;
 
-    const nsXPTParamInfo& arg_param = method->params[argnum];
+    const nsXPTParamInfo& arg_param = method->GetParam(argnum);
 
     // This should be enforced by the xpidl compiler, but it's not.
     // See bug 695235.
     MOZ_ASSERT(arg_param.GetType().TagPart() == nsXPTType::T_U32,
                "size_is references parameter of invalid type.");
 
     if (arg_param.IsIndirect())
         *result = *(uint32_t*)nativeParams[argnum].val.p;
     else
         *result = nativeParams[argnum].val.u32;
 
     return true;
 }
 
 bool
 nsXPCWrappedJSClass::GetInterfaceTypeFromParam(JSContext* cx,
-                                               const XPTMethodDescriptor* method,
+                                               const nsXPTMethodInfo* method,
                                                const nsXPTParamInfo& param,
                                                uint16_t methodIndex,
                                                const nsXPTType& type,
                                                nsXPTCMiniVariant* nativeParams,
                                                nsID* result) const
 {
     uint8_t type_tag = type.TagPart();
 
@@ -761,17 +761,17 @@ nsXPCWrappedJSClass::GetInterfaceTypeFro
     } else if (type_tag == nsXPTType::T_INTERFACE_IS) {
         uint8_t argnum;
         nsresult rv;
         rv = mInfo->GetInterfaceIsArgNumberForParam(methodIndex,
                                                     &param, &argnum);
         if (NS_FAILED(rv))
             return false;
 
-        const nsXPTParamInfo& arg_param = method->params[argnum];
+        const nsXPTParamInfo& arg_param = method->GetParam(argnum);
         const nsXPTType& arg_type = arg_param.GetType();
 
         if (arg_type.TagPart() == nsXPTType::T_IID) {
             if (arg_param.IsIndirect()) {
                 nsID** p = (nsID**) nativeParams[argnum].val.p;
                 if (!p || !*p)
                     return false;
                 *result = **p;
@@ -823,17 +823,17 @@ nsXPCWrappedJSClass::CleanupPointerTypeO
 
 void
 nsXPCWrappedJSClass::CleanupOutparams(JSContext* cx, uint16_t methodIndex,
                                       const nsXPTMethodInfo* info, nsXPTCMiniVariant* nativeParams,
                                       bool inOutOnly, uint8_t n) const
 {
     // clean up any 'out' params handed in
     for (uint8_t i = 0; i < n; i++) {
-        const nsXPTParamInfo& param = info->params[i];
+        const nsXPTParamInfo& param = info->GetParam(i);
         if (!param.IsOut())
             continue;
 
         const nsXPTType& type = param.GetType();
         if (!type.deprecated_IsPointer())
             continue;
         void* p = nativeParams[i].val.p;
         if (!p)
@@ -1022,28 +1022,27 @@ nsXPCWrappedJSClass::CheckForException(X
             return pending_result;
         }
     }
     return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
-                                const XPTMethodDescriptor* info_,
+                                const nsXPTMethodInfo* info,
                                 nsXPTCMiniVariant* nativeParams)
 {
     Value* sp = nullptr;
     Value* argv = nullptr;
     uint8_t i;
     nsresult retval = NS_ERROR_FAILURE;
     bool success;
     bool readyToDoTheCall = false;
     nsID  param_iid;
-    const nsXPTMethodInfo* info = static_cast<const nsXPTMethodInfo*>(info_);
-    const char* name = info->name;
+    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
@@ -1081,32 +1080,32 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
 
     AutoValueVector args(cx);
     AutoScriptEvaluate scriptEval(cx);
 
     XPCJSContext* xpccx = ccx.GetContext();
     AutoSavePendingResult apr(xpccx);
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
-    uint8_t paramCount = info->num_args;
+    uint8_t paramCount = info->GetParamCount();
     uint8_t argc = paramCount -
-        (paramCount && XPT_PD_IS_RETVAL(info->params[paramCount-1].flags) ? 1 : 0);
+        (paramCount && XPT_PD_IS_RETVAL(info->GetParam(paramCount - 1).flags) ? 1 : 0);
 
     if (!scriptEval.StartEvaluating(obj))
         goto pre_call_clean_up;
 
     xpccx->SetPendingException(nullptr);
 
     // We use js_Invoke so that the gcthings we use as args will be rooted by
     // the engine as we do conversions and prepare to do the function call.
 
     // setup stack
 
     // if this isn't a function call then we don't need to push extra stuff
-    if (!(XPT_MD_IS_SETTER(info->flags) || XPT_MD_IS_GETTER(info->flags))) {
+    if (!(info->IsSetter() || info->IsGetter())) {
         // We get fval before allocating the stack to avoid gc badness that can
         // happen if the GetProperty call leaves our request and the gc runs
         // while the stack we allocate contains garbage.
 
         // If the interface is marked as a [function] then we will assume that
         // our JSObject is a function and not an object with a named method.
 
         bool isFunction;
@@ -1126,17 +1125,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
 
         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->params[0];
+                const nsXPTParamInfo& firstParam = info->GetParam(0);
                 if (firstParam.IsIn()) {
                     const nsXPTType& firstType = firstParam.GetType();
 
                     if (firstType.IsInterfacePointer()) {
                         nsIXPCFunctionThisTranslator* translator;
 
                         IID2ThisTranslatorMap* map =
                             mRuntime->GetThisTranslatorMap();
@@ -1190,17 +1189,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
 
     // build the args
     // NB: This assignment *looks* wrong because we haven't yet called our
     // function. However, we *have* already entered the compartmen that we're
     // about to call, and that's the global that we want here. In other words:
     // we're trusting the JS engine to come up with a good global to use for
     // our object (whatever it was).
     for (i = 0; i < argc; i++) {
-        const nsXPTParamInfo& param = info->params[i];
+        const nsXPTParamInfo& param = info->GetParam(i);
         const nsXPTType& type = param.GetType();
         nsXPTType datum_type;
         uint32_t array_count;
         bool isArray = type.IsArray();
         RootedValue val(cx, NullValue());
         bool isSizedString = isArray ?
                 false :
                 type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
@@ -1292,19 +1291,19 @@ pre_call_clean_up:
         return retval;
 
     // do the deed - note exceptions
 
     MOZ_ASSERT(!aes.HasException());
 
     RefPtr<Exception> syntheticException;
     RootedValue rval(cx);
-    if (XPT_MD_IS_GETTER(info->flags)) {
+    if (info->IsGetter()) {
         success = JS_GetProperty(cx, obj, name, &rval);
-    } else if (XPT_MD_IS_SETTER(info->flags)) {
+    } else if (info->IsSetter()) {
         rval = *argv;
         success = JS_SetProperty(cx, obj, name, rval);
     } else {
         if (!fval.isPrimitive()) {
             success = JS_CallFunctionValue(cx, thisObj, fval, args, &rval);
         } else {
             // The property was not an object so can't be a function.
             // Let's build and 'throw' an exception.
@@ -1335,17 +1334,17 @@ pre_call_clean_up:
     // NOTE: this is the total number of native params, not just the args
     // Convert independent params only.
     // When we later convert the dependent params (if any) we will know that
     // the params upon which they depend will have already been converted -
     // regardless of ordering.
 
     foundDependentParam = false;
     for (i = 0; i < paramCount; i++) {
-        const nsXPTParamInfo& param = info->params[i];
+        const nsXPTParamInfo& param = info->GetParam(i);
         MOZ_ASSERT(!param.IsShared(), "[shared] implies [noscript]!");
         if (!param.IsOut() && !param.IsDipper())
             continue;
 
         const nsXPTType& type = param.GetType();
         if (type.IsDependent()) {
             foundDependentParam = true;
             continue;
@@ -1384,17 +1383,17 @@ pre_call_clean_up:
         if (!XPCConvert::JSData2Native(&pv->val, val, type,
                                        &param_iid, nullptr))
             break;
     }
 
     // if any params were dependent, then we must iterate again to convert them.
     if (foundDependentParam && i == paramCount) {
         for (i = 0; i < paramCount; i++) {
-            const nsXPTParamInfo& param = info->params[i];
+            const nsXPTParamInfo& param = info->GetParam(i);
             if (!param.IsOut())
                 continue;
 
             const nsXPTType& type = param.GetType();
             if (!type.IsDependent())
                 continue;
 
             RootedValue val(cx);
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -1824,17 +1824,17 @@ public:
     static bool IsWrappedJS(nsISupports* aPtr);
 
     NS_IMETHOD DelegatedQueryInterface(nsXPCWrappedJS* self, REFNSIID aIID,
                                        void** aInstancePtr);
 
     JSObject* GetRootJSObject(JSContext* cx, JSObject* aJSObj);
 
     NS_IMETHOD CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
-                          const XPTMethodDescriptor* info,
+                          const nsXPTMethodInfo* info,
                           nsXPTCMiniVariant* params);
 
     JSObject*  CallQueryInterfaceOnJSObject(JSContext* cx,
                                             JSObject* jsobj, REFNSIID aIID);
 
     static nsresult BuildPropertyEnumerator(XPCCallContext& ccx,
                                             JSObject* aJSObj,
                                             nsISimpleEnumerator** aEnumerate);
@@ -1861,25 +1861,25 @@ private:
 
     bool IsReflectable(uint16_t i) const
         {return (bool)(mDescriptors[i/32] & (1 << (i%32)));}
     void SetReflectable(uint16_t i, bool b)
         {if (b) mDescriptors[i/32] |= (1 << (i%32));
          else mDescriptors[i/32] &= ~(1 << (i%32));}
 
     bool GetArraySizeFromParam(JSContext* cx,
-                               const XPTMethodDescriptor* method,
+                               const nsXPTMethodInfo* method,
                                const nsXPTParamInfo& param,
                                uint16_t methodIndex,
                                uint8_t paramIndex,
                                nsXPTCMiniVariant* params,
                                uint32_t* result) const;
 
     bool GetInterfaceTypeFromParam(JSContext* cx,
-                                   const XPTMethodDescriptor* method,
+                                   const nsXPTMethodInfo* method,
                                    const nsXPTParamInfo& param,
                                    uint16_t methodIndex,
                                    const nsXPTType& type,
                                    nsXPTCMiniVariant* params,
                                    nsID* result) const;
 
     static void CleanupPointerArray(const nsXPTType& datum_type,
                                     uint32_t array_count,
@@ -1916,17 +1916,17 @@ public:
     NS_DECL_NSIXPCONNECTWRAPPEDJS
     NS_DECL_NSIXPCONNECTWRAPPEDJSUNMARKGRAY
     NS_DECL_NSISUPPORTSWEAKREFERENCE
     NS_DECL_NSIPROPERTYBAG
 
     NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS_AMBIGUOUS(nsXPCWrappedJS, nsIXPConnectWrappedJS)
 
     NS_IMETHOD CallMethod(uint16_t methodIndex,
-                          const XPTMethodDescriptor* info,
+                          const nsXPTMethodInfo* info,
                           nsXPTCMiniVariant* params) override;
 
     /*
     * This is rarely called directly. Instead one usually calls
     * XPCConvert::JSObject2NativeInterface which will handles cases where the
     * JS object is already a wrapped native or a DOM object.
     */
 
@@ -2044,17 +2044,17 @@ private:
     nsCOMPtr<nsIVariant> mValue;
 };
 
 /***************************************************************************/
 // class here just for static methods
 class XPCConvert
 {
 public:
-    static bool IsMethodReflectable(const XPTMethodDescriptor& info);
+    static bool IsMethodReflectable(const nsXPTMethodInfo& info);
 
     /**
      * Convert a native object into a JS::Value.
      *
      * @param d [out] the resulting JS::Value
      * @param s the native object we're working with
      * @param type the type of object that s is
      * @param iid the interface of s that we want
--- a/xpcom/reflect/xptcall/xptcall.h
+++ b/xpcom/reflect/xptcall/xptcall.h
@@ -139,17 +139,17 @@ struct nsXPTCVariant : public nsXPTCMini
         }
     }
 };
 
 class nsIXPTCProxy : public nsISupports
 {
 public:
     NS_IMETHOD CallMethod(uint16_t aMethodIndex,
-                          const XPTMethodDescriptor *aInfo,
+                          const nsXPTMethodInfo *aInfo,
                           nsXPTCMiniVariant *aParams) = 0;
 };
 
 /**
  * This is a typedef to avoid confusion between the canonical
  * nsISupports* that provides object identity and an interface pointer
  * for inheriting interfaces that aren't known at compile-time.
  */