b=476903; fix xptcinvoke on ARM; r=bsmedberg
authorVladimir Vukicevic <vladimir@pobox.com>
Thu, 26 Feb 2009 12:05:09 -0800
changeset 25563 6ac03fc09e48
parent 25562 16cf92dc8c6c
child 25564 d3bb2720024d
push id5609
push uservladimir@mozilla.com
push dateThu, 26 Feb 2009 20:13:07 +0000
treeherdermozilla-central@6ac03fc09e48 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs476903
milestone1.9.2a1pre
b=476903; fix xptcinvoke on ARM; r=bsmedberg
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
xpcom/reflect/xptcall/src/md/win32/xptcinvokece.cpp
--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
@@ -32,16 +32,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Platform specific code to invoke XPCOM methods on native objects */
 
+#include "prlog.h"
+
 #include "xptcprivate.h"
 
 #if !defined(LINUX) || !defined(__arm__)
 #error "This code is for Linux ARM only. Check that it works on your system, too.\nBeware that this code is highly compiler dependent."
 #endif
 
 
 
@@ -121,34 +123,40 @@ invoke_copy_to_stack(PRUint32* d, PRUint
 {
     for(PRUint32 i = 0; i < paramCount; i++, d++, s++)
     {
         if(s->IsPtrData())
         {
             *((void**)d) = s->ptr;
             continue;
         }
+        // According to the ARM EABI, integral types that are smaller than a word
+        // are to be sign/zero-extended to a full word and treated as 4-byte values.
+        // NOTE: on ARM/gcc, char is unsigned by default, and PRunichar is unisgned.
+        PR_STATIC_ASSERT(char(0xFF) == PRUint32(0xFF));
+        PR_STATIC_ASSERT(PRUnichar(0xFFFF) == PRUint32(0xFFFF));
+
         switch(s->type)
         {
-        case nsXPTType::T_I8     : *((PRInt8*)  d) = s->val.i8;          break;
-        case nsXPTType::T_I16    : *((PRInt16*) d) = s->val.i16;         break;
+        case nsXPTType::T_I8     : *((PRInt32*) d) = s->val.i8;          break;
+        case nsXPTType::T_I16    : *((PRInt32*) d) = s->val.i16;         break;
         case nsXPTType::T_I32    : *((PRInt32*) d) = s->val.i32;         break;
         case nsXPTType::T_I64    : d = DOUBLEWORD_ALIGN(d);
                                    *((PRInt64*) d) = s->val.i64; d++;    break;
-        case nsXPTType::T_U8     : *((PRUint8*) d) = s->val.u8;          break;
-        case nsXPTType::T_U16    : *((PRUint16*)d) = s->val.u16;         break;
+        case nsXPTType::T_U8     : *((PRUint32*)d) = s->val.u8;          break;
+        case nsXPTType::T_U16    : *((PRUint32*)d) = s->val.u16;         break;
         case nsXPTType::T_U32    : *((PRUint32*)d) = s->val.u32;         break;
         case nsXPTType::T_U64    : d = DOUBLEWORD_ALIGN(d);
                                    *((PRUint64*)d) = s->val.u64; d++;    break;
         case nsXPTType::T_FLOAT  : *((float*)   d) = s->val.f;           break;
         case nsXPTType::T_DOUBLE : d = DOUBLEWORD_ALIGN(d);
                                    *((double*)  d) = s->val.d;   d++;    break;
-        case nsXPTType::T_BOOL   : *((PRBool*)  d) = s->val.b;           break;
-        case nsXPTType::T_CHAR   : *((char*)    d) = s->val.c;           break;
-        case nsXPTType::T_WCHAR  : *((wchar_t*) d) = s->val.wc;          break;
+        case nsXPTType::T_BOOL   : *((PRInt32*) d) = s->val.b;           break;
+        case nsXPTType::T_CHAR   : *((PRUint32*)d) = s->val.c;           break;
+        case nsXPTType::T_WCHAR  : *((PRUint32*)d) = s->val.wc;          break;
         default:
             // all the others are plain pointer types
             *((void**)d) = s->val.p;
             break;
         }
     }
 }
 
--- a/xpcom/reflect/xptcall/src/md/win32/xptcinvokece.cpp
+++ b/xpcom/reflect/xptcall/src/md/win32/xptcinvokece.cpp
@@ -30,16 +30,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* Platform specific code to invoke XPCOM methods on native objects */
 
+#include "prlog.h"
+
 #include "xptcprivate.h"
 
 extern "C" nsresult
 asmXPTC_InvokeByIndex( nsISupports* that,
                        PRUint32 methodIndex,
   					   PRUint32 paramCount,
 					   nsXPTCVariant* params,
 					   PRUint32 pfn_CopyToStack,
@@ -54,31 +56,37 @@ invoke_copy_to_stack(PRUint32* d, PRUint
 {
   for(; paramCount > 0; paramCount--, d++, s++)
   {
     if(s->IsPtrData())
     {
       *((void**)d) = s->ptr;
       continue;
     }
+    // According to the ARM EABI, integral types that are smaller than a word
+    // are to be sign/zero-extended to a full word and treated as 4-byte values.
+    // NOTE: on ARM/CE, char is signed, but PRunichar is unsigned.
+    PR_STATIC_ASSERT(char(0xFF) < 0);
+    PR_STATIC_ASSERT(PRUnichar(0xFFFF) == PRUint32(0xFFFF));
+
     switch(s->type)
     {
-      case nsXPTType::T_I8     : *((PRInt8*)  d) = s->val.i8;          break;
-      case nsXPTType::T_I16    : *((PRInt16*) d) = s->val.i16;         break;
+      case nsXPTType::T_I8     : *((PRInt32*) d) = s->val.i8;          break;
+      case nsXPTType::T_I16    : *((PRInt32*) d) = s->val.i16;         break;
       case nsXPTType::T_I32    : *((PRInt32*) d) = s->val.i32;         break;
       case nsXPTType::T_I64    : *((PRInt64*) d) = s->val.i64; d++;    break;
-      case nsXPTType::T_U8     : *((PRUint8*) d) = s->val.u8;          break;
-      case nsXPTType::T_U16    : *((PRUint16*)d) = s->val.u16;         break;
+      case nsXPTType::T_U8     : *((PRUint32*)d) = s->val.u8;          break;
+      case nsXPTType::T_U16    : *((PRUint32*)d) = s->val.u16;         break;
       case nsXPTType::T_U32    : *((PRUint32*)d) = s->val.u32;         break;
       case nsXPTType::T_U64    : *((PRUint64*)d) = s->val.u64; d++;    break;
       case nsXPTType::T_FLOAT  : *((float*)   d) = s->val.f;           break;
       case nsXPTType::T_DOUBLE : *((double*)  d) = s->val.d;   d++;    break;
-      case nsXPTType::T_BOOL   : *((PRBool*)  d) = s->val.b;           break;
-      case nsXPTType::T_CHAR   : *((char*)    d) = s->val.c;           break;
-      case nsXPTType::T_WCHAR  : *((wchar_t*) d) = s->val.wc;          break;
+      case nsXPTType::T_BOOL   : *((PRInt32*) d) = s->val.b;           break;
+      case nsXPTType::T_CHAR   : *((PRInt32*) d) = s->val.c;           break;
+      case nsXPTType::T_WCHAR  : *((PRUint32*)d) = s->val.wc;          break;
       default:
         // all the others are plain pointer types
         *((void**)d) = s->val.p;
         break;
     }
   }
 }