From: Mike Hommey <mh@glandium.org>
Date: Mon, 8 Feb 2010 09:54:43 +0100
Subject: Fix xptcinvoke on ARM

https://bugzilla.mozilla.org/show_bug.cgi?id=476903
---
 .../reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
index 780a862..dbb5005 100644
--- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
+++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp
@@ -126,24 +126,27 @@ invoke_copy_to_stack(PRUint32* d, PRUint32 paramCount, nsXPTCVariant* s)
             *((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.
+
         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   : *((PRInt32*) d) = s->val.c;           break;
+        case nsXPTType::T_WCHAR  : *((PRInt32*) d) = s->val.wc;          break;
         default:
             // all the others are plain pointer types
             *((void**)d) = s->val.p;
