Fix for 3326: Incorrect return value from native library in dalvik
Really a workaround for a gcc bug in 4.3.  Don't trust the C compiler
to properly clear high bits from < 32-bit JNI return values.
diff --git a/vm/JniInternal.h b/vm/JniInternal.h
index 36ff46b..df3ca54 100644
--- a/vm/JniInternal.h
+++ b/vm/JniInternal.h
@@ -74,13 +74,18 @@
  * Native function return type; used by dvmPlatformInvoke().
  *
  * This is part of Method.jniArgInfo, and must fit in 3 bits.
+ * Note: Assembly code in arch/<arch>/Call<arch>.S relies on
+ * the enum values defined here.
  */
 typedef enum DalvikJniReturnType {
     DALVIK_JNI_RETURN_VOID = 0,     /* must be zero */
-    DALVIK_JNI_RETURN_FLOAT,
-    DALVIK_JNI_RETURN_DOUBLE,
-    DALVIK_JNI_RETURN_S8,
-    DALVIK_JNI_RETURN_S4
+    DALVIK_JNI_RETURN_FLOAT = 1,
+    DALVIK_JNI_RETURN_DOUBLE = 2,
+    DALVIK_JNI_RETURN_S8 = 3,
+    DALVIK_JNI_RETURN_S4 = 4,
+    DALVIK_JNI_RETURN_S2 = 5,
+    DALVIK_JNI_RETURN_U2 = 6,
+    DALVIK_JNI_RETURN_S1 = 7
 } DalvikJniReturnType;
 
 #define DALVIK_JNI_NO_ARG_INFO  0x80000000
diff --git a/vm/arch/x86/Call386ABI.S b/vm/arch/x86/Call386ABI.S
index 9e32bdd..6cb680c 100644
--- a/vm/arch/x86/Call386ABI.S
+++ b/vm/arch/x86/Call386ABI.S
@@ -131,12 +131,31 @@
     /* Is FP? */
     cmpl     $2,%ebx
     jle      isFP
-    /* No need to distinguish between 32/64 - just save both */
+    cmpl     $4,%ebx  /* smaller than 32-bits? */
+    jg       isSmall
+storeRetval:
+    /* Blindly storing 64-bits won't hurt 32-bit case */
     movl     %eax,(%ecx)
     movl     %edx,4(%ecx)
     jmp      cleanUpAndExit
+isSmall:
+    cmpl     $7,%ebx  /* S1? */
+    jne      checkShort
+    movsbl   %al,%eax
+    movl     %eax,(%ecx)
+    jmp      cleanUpAndExit
+checkShort:
+    cmpl     $6,%eax  /* U2? */
+    jne      isSignedShort
+    movzwl   %ax,%eax
+    movl     %eax,(%ecx)
+    jmp      cleanUpAndExit
+isSignedShort:
+    /* Must be S2 */
+    movswl   %ax,%eax
+    jmp      cleanUpAndExit
 isFP:
-    /* Is single? */
+    /* Is Float? */
     cmpl    $1,%ebx
     je       saveFloat
     fstpl    (%ecx)
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 23ffb0b..a2c485f 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -2201,6 +2201,16 @@
     case 'J':
         returnType = DALVIK_JNI_RETURN_S8;
         break;
+    case 'Z':
+    case 'B':
+        returnType = DALVIK_JNI_RETURN_S1;
+        break;
+    case 'C':
+        returnType = DALVIK_JNI_RETURN_U2;
+        break;
+    case 'S':
+        returnType = DALVIK_JNI_RETURN_S2;
+        break;
     default:
         returnType = DALVIK_JNI_RETURN_S4;
         break;