Bug 1498938 - Support [implicit_jscontext] XPIDL calls on Linux/PPC64.; r=froydnj
authorA. Wilcox <AWilcox@Wilcox-Tech.com>
Wed, 17 Oct 2018 23:12:51 +0000
changeset 490123 06e5a5bfd05ef276dce035af837f2ba76e9a55a4
parent 490122 0ef00ee6c5312035280635f06e4790abd8b13729
child 490124 3714d89762380c501cf13257d0c373260dc7de0e
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersfroydnj
bugs1498938
milestone64.0a1
Bug 1498938 - Support [implicit_jscontext] XPIDL calls on Linux/PPC64.; r=froydnj
xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp
--- a/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp
+++ b/xpcom/reflect/xptcall/md/unix/xptcstubs_ppc64_linux.cpp
@@ -61,43 +61,52 @@ PrepareAndDispatch(nsXPTCStubBase* self,
 
     NS_ASSERTION(dispatchParams,"no place for params");
     if (! dispatchParams)
         return NS_ERROR_OUT_OF_MEMORY;
 
     const uint8_t indexOfJSContext = info->IndexOfJSContext();
 
     uint64_t* ap = args;
+    uint32_t iCount = 0;
+    uint32_t fpCount = 0;
     uint64_t tempu64;
 
     for(i = 0; i < paramCount; i++) {
         const nsXPTParamInfo& param = info->GetParam(i);
         const nsXPTType& type = param.GetType();
         nsXPTCMiniVariant* dp = &dispatchParams[i];
 
-        MOZ_CRASH("NYI: support implicit JSContext*, bug 1475699");
+        if (i == indexOfJSContext) {
+            if (iCount < GPR_COUNT)
+                iCount++;
+            else
+                ap++;
+        }
 
         if (!param.IsOut() && type == nsXPTType::T_DOUBLE) {
-            if (i < FPR_COUNT)
-                dp->val.d = fprData[i];
+            if (fpCount < FPR_COUNT) {
+                dp->val.d = fprData[fpCount++];
+            }
             else
                 dp->val.d = *(double*) ap;
         } else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
-            if (i < FPR_COUNT)
-                dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles
+            if (fpCount < FPR_COUNT) {
+                dp->val.f = (float) fprData[fpCount++]; // in registers floats are passed as doubles
+            }
             else {
                 float *p = (float *)ap;
 #ifndef __LITTLE_ENDIAN__
                 p++;
 #endif
                 dp->val.f = *p;
             }
         } else { /* integer type or pointer */
-            if (i < GPR_COUNT)
-                tempu64 = gprData[i];
+            if (iCount < GPR_COUNT)
+                tempu64 = gprData[iCount];
             else
                 tempu64 = *ap;
 
             if (param.IsOut() || !type.IsArithmetic())
                 dp->val.p = (void*) tempu64;
             else if (type == nsXPTType::T_I8)
                 dp->val.i8  = (int8_t)   tempu64;
             else if (type == nsXPTType::T_I16)
@@ -119,17 +128,19 @@ PrepareAndDispatch(nsXPTCStubBase* self,
             else if (type == nsXPTType::T_CHAR)
                 dp->val.c   = (char)     tempu64;
             else if (type == nsXPTType::T_WCHAR)
                 dp->val.wc  = (wchar_t)  tempu64;
             else
                 NS_ERROR("bad type");
         }
 
-        if (i >= 7)
+        if (iCount < GPR_COUNT)
+            iCount++;  // gprs are skipped for fp args, so this always needs inc
+        else
             ap++;
     }
 
     nsresult result = self->mOuter->CallMethod((uint16_t) methodIndex, info,
                                                dispatchParams);
 
     if (dispatchParams != paramBuffer)
         delete [] dispatchParams;