Bug 683802 - Use an explicit indicator for direct vs indirect calling semantics. r=mrbkap
authorBobby Holley <bobbyholley@gmail.com>
Fri, 23 Sep 2011 14:50:28 -0700
changeset 78780 36aa31a60a664fdb3e4ce0b25c7f8e80937c68da
parent 78779 6e1f386c4065c1c0b4175cddd0674d8aa21b6a05
child 78781 5ab48d3bf0bd4ca4927916adfb73f11f5edc2f14
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs683802
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 683802 - Use an explicit indicator for direct vs indirect calling semantics. r=mrbkap
js/src/xpconnect/src/xpcwrappedjsclass.cpp
js/src/xpconnect/src/xpcwrappednative.cpp
xpcom/reflect/xptinfo/public/xptinfo.h
--- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp
+++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp
@@ -927,17 +927,17 @@ nsXPCWrappedJSClass::GetArraySizeFromPar
 
     const nsXPTParamInfo& arg_param = method->params[argnum];
     const nsXPTType& arg_type = arg_param.GetType();
 
     // The xpidl compiler ensures this. We reaffirm it for safety.
     if(arg_type.IsPointer() || arg_type.TagPart() != nsXPTType::T_U32)
         return JS_FALSE;
 
-    if(arg_param.IsOut())
+    if(arg_param.IsIndirect())
         *result = *(JSUint32*)nativeParams[argnum].val.p;
     else
         *result = nativeParams[argnum].val.u32;
 
     return JS_TRUE;
 }
 
 JSBool
@@ -968,17 +968,17 @@ nsXPCWrappedJSClass::GetInterfaceTypeFro
         if(NS_FAILED(rv))
             return JS_FALSE;
 
         const nsXPTParamInfo& arg_param = method->params[argnum];
         const nsXPTType& arg_type = arg_param.GetType();
         if(arg_type.IsPointer() &&
            arg_type.TagPart() == nsXPTType::T_IID)
         {
-            if(arg_param.IsOut())
+            if(arg_param.IsIndirect())
             {
                 nsID** p = (nsID**) nativeParams[argnum].val.p;
                 if(!p || !*p)
                     return JS_FALSE;
                 *result = **p;
             }
             else
             {
@@ -1504,18 +1504,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
         }
         else
             datum_type = type;
 
         if(param.IsIn())
         {
             nsXPTCMiniVariant* pv;
 
-            // Temporary hack - we'll abstract this away soon.
-            if(param.IsOut() || type.TagPart() == nsXPTType::T_JSVAL)
+            if(param.IsIndirect())
                 pv = (nsXPTCMiniVariant*) nativeParams[i].val.p;
             else
                 pv = &nativeParams[i];
 
             if(datum_type.IsInterfacePointer() &&
                !GetInterfaceTypeFromParam(cx, info, param, methodIndex,
                                           datum_type, nativeParams,
                                           &param_iid))
--- a/js/src/xpconnect/src/xpcwrappednative.cpp
+++ b/js/src/xpconnect/src/xpcwrappednative.cpp
@@ -2825,47 +2825,46 @@ CallMethodHelper::ConvertIndependentPara
     uint8 type_tag = type.TagPart();
     nsXPTCVariant* dp = GetDispatchParam(i);
     dp->type = type;
 
     // Handle dipper types separately.
     if(paramInfo.IsDipper())
         return HandleDipperParam(dp, paramInfo);
 
+    // Specify the correct storage/calling semantics.
+    if(paramInfo.IsIndirect())
+        dp->SetIndirect();
+
     if(type_tag == nsXPTType::T_INTERFACE)
     {
         dp->SetValIsInterface();
     }
 
     jsval src;
 
     if (!GetOutParamSource(i, &src))
         return JS_FALSE;
 
     // The JSVal proper is always stored within the 'val' union and passed
     // indirectly, regardless of in/out-ness.
     if(type_tag == nsXPTType::T_JSVAL)
     {
-        // Indicate the storage semantics.
-        dp->SetIndirect();
-
         // Assign the value
         JS_STATIC_ASSERT(sizeof(jsval) <= sizeof(dp->val));
         jsval *rootp = (jsval *)&dp->val;
         dp->ptr = rootp;
         *rootp = JSVAL_VOID;
         if(!JS_AddValueRoot(mCallContext, rootp))
             return JS_FALSE;
         dp->SetValIsJSRoot();
     }
 
     if(paramInfo.IsOut())
     {
-        dp->SetIndirect();
-
         if(type.IsPointer() &&
            type_tag != nsXPTType::T_INTERFACE &&
            !paramInfo.IsShared())
         {
             useAllocator = JS_TRUE;
             dp->SetValIsAllocated();
         }
 
@@ -2961,16 +2960,20 @@ CallMethodHelper::ConvertDependentParams
         PRBool isSizedString = isArray ?
             JS_FALSE :
             type.TagPart() == nsXPTType::T_PSTRING_SIZE_IS ||
             type.TagPart() == nsXPTType::T_PWSTRING_SIZE_IS;
 
         nsXPTCVariant* dp = GetDispatchParam(i);
         dp->type = type;
 
+        // Specify the correct storage/calling semantics.
+        if(paramInfo.IsIndirect())
+            dp->SetIndirect();
+
         if(isArray)
         {
             dp->SetValIsArray();
 
             if(NS_FAILED(mIFaceInfo->GetTypeForParam(mVTableIndex, &paramInfo, 1,
                                                      &datum_type)))
             {
                 Throw(NS_ERROR_XPC_CANT_GET_ARRAY_INFO, mCallContext);
@@ -2987,18 +2990,16 @@ CallMethodHelper::ConvertDependentParams
 
         jsval src;
 
         if (!GetOutParamSource(i, &src))
             return JS_FALSE;
 
         if(paramInfo.IsOut())
         {
-            dp->SetIndirect();
-
             if(datum_type.IsPointer() &&
                !datum_type.IsInterfacePointer() &&
                (isArray || !paramInfo.IsShared()))
             {
                 useAllocator = JS_TRUE;
                 dp->SetValIsAllocated();
             }
 
--- a/xpcom/reflect/xptinfo/public/xptinfo.h
+++ b/xpcom/reflect/xptinfo/public/xptinfo.h
@@ -155,16 +155,22 @@ public:
     PRBool IsIn()  const    {return 0 != (XPT_PD_IS_IN(flags));}
     PRBool IsOut() const    {return 0 != (XPT_PD_IS_OUT(flags));}
     PRBool IsRetval() const {return 0 != (XPT_PD_IS_RETVAL(flags));}
     PRBool IsShared() const {return 0 != (XPT_PD_IS_SHARED(flags));}
     PRBool IsDipper() const {return 0 != (XPT_PD_IS_DIPPER(flags));}
     PRBool IsOptional() const {return 0 != (XPT_PD_IS_OPTIONAL(flags));}
     const nsXPTType GetType() const {return type.prefix;}
 
+    // Whether this parameter is passed indirectly on the stack. This mainly
+    // applies to out/inout params, but we use it unconditionally for certain
+    // types.
+    PRBool IsIndirect() const {return IsOut() ||
+                               GetType().TagPart() == nsXPTType::T_JSVAL;}
+
     // NOTE: other activities on types are done via methods on nsIInterfaceInfo
 
 private:
     nsXPTParamInfo();   // no implementation
 // NO DATA - this a flyweight wrapper
 };
 
 class nsXPTMethodInfo : public XPTMethodDescriptor