Java - unsigned long long marshalling improvements for negative numbers

Affects marshalling of negative numbers from Java to C only.
A cast to signed long long in the C layer will now result in the expected value.

Closes #623.
This commit is contained in:
William S Fulton 2016-03-31 18:42:08 +01:00
commit a15bbbaee5
5 changed files with 90 additions and 14 deletions

View file

@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.9 (in progress) Version 3.0.9 (in progress)
=========================== ===========================
2016-03-31: wsfulton
[Java] unsigned long long marshalling improvements when a negative number
is passed from Java to C. A cast to signed long long in the C layer will now
result in the expected value. No change for positive numbers passed to C.
Fixes #623.
2016-03-22: alexwarg 2016-03-22: alexwarg
[Lua] #398 Fix lua __getitem + inheritance [Lua] #398 Fix lua __getitem + inheritance
The new handling of classes in Lua (not merging methods into the derived classes) The new handling of classes in Lua (not merging methods into the derived classes)

View file

@ -3,7 +3,8 @@
// unsigned long long types map correctly to long and BigInteger respectively. // unsigned long long types map correctly to long and BigInteger respectively.
import long_long.*; import long_long.*;
import java.math.*; import java.math.BigInteger;
import java.util.ArrayList;
public class long_long_runme { public class long_long_runme {
@ -54,12 +55,57 @@ public class long_long_runme {
check_ull(testNumber); check_ull(testNumber);
testNumber = testNumber.add(BigInteger.ONE); testNumber = testNumber.add(BigInteger.ONE);
} }
try { try {
long_long.setUll(null); long_long.setUll(null);
throw new RuntimeException("null check failed"); throw new RuntimeException("null check failed");
} catch (NullPointerException e) { } catch (NullPointerException e) {
} }
// UnsignedToSigned - checks that a cast from unsigned long long to long long in C
// gives expected value (including -ve numbers)
long[] nums = {
0x00,
0xFF, 0x80, 0x7F, 0x01,
-0xFF, -0x80, -0x7F, -0x01,
0x100, 0x10000,
-0x100, -0x10000,
0xFFFF, 0xFF80, 0xFF7F, 0xFF01, 0xFF00,
-0xFFFF, -0xFF80, -0xFF7F, -0xFF01, -0xFF00,
0x7FFF, 0x7F80, 0x7F7F, 0x7F01, 0x7F00,
-0x7FFF, -0x7F80, -0x7F7F, -0x7F01, -0x7F00,
0x80FF, 0x8080, 0x807F, 0x8001, 0x8000,
-0x80FF, -0x8080, -0x807F, -0x8001, -0x8000,
Integer.MAX_VALUE, Integer.MIN_VALUE,
Integer.MAX_VALUE+1, Integer.MIN_VALUE-1,
Long.MAX_VALUE, Long.MIN_VALUE,
};
ArrayList<BigInteger> bigIntegers = new ArrayList<BigInteger>();
for (int i=0; i<nums.length; ++i) {
BigInteger bi = new BigInteger(new Long(nums[i]).toString());
bigIntegers.add(bi);
}
{
BigInteger bi = new BigInteger(new Long(Long.MAX_VALUE).toString());
bigIntegers.add(bi.add(BigInteger.ONE));
bi = new BigInteger(new Long(Long.MIN_VALUE).toString());
bigIntegers.add(bi.subtract(BigInteger.ONE));
}
boolean failed = false;
for (int i=0; i<bigIntegers.size(); ++i) {
BigInteger bi = (BigInteger)bigIntegers.get(i);
long longReturn = long_long.UnsignedToSigned(bi);
if (bi.longValue() != longReturn) {
System.err.println("Conversion to long failed, in:" + bi + " out:" + longReturn);
failed = true;
}
}
if (failed)
throw new RuntimeException("There were UnsignedToSigned failures");
} }
public static void check_ll(long ll) { public static void check_ll(long ll) {

View file

@ -38,3 +38,9 @@ unsigned long long ull;
#define lconst5 987654321LL #define lconst5 987654321LL
#define lconst6 987654321ULL #define lconst6 987654321ULL
%inline %{
long long UnsignedToSigned(unsigned long long ull) {
return (long long)ull;
}
%}

View file

@ -310,8 +310,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
bae = JCALL2(GetByteArrayElements, jenv, ba, 0); bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
$1 = 0; $1 = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
$1 = ($1 << 8) | ($1_type)(unsigned char)bae[i]; $1 = ($1_type)(signed char)bae[0];
for(i=1; i<sz; i++) {
$1 = ($1 << 8) | ($1_type)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
} }
@ -334,8 +337,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
bae = JCALL2(GetByteArrayElements, jenv, ba, 0); bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
$result = 0; $result = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
$result = ($result << 8) | ($1_type)(unsigned char)bae[i]; $result = ($1_type)(signed char)bae[0];
for(i=1; i<sz; i++) {
$result = ($result << 8) | ($1_type)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
} }
@ -552,8 +558,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
$1 = &temp; $1 = &temp;
temp = 0; temp = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
} }
@ -578,8 +587,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
$result = &temp; $result = &temp;
temp = 0; temp = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
} }

View file

@ -109,8 +109,11 @@ INPUT_TYPEMAP(double, jdouble, double, "D");
bae = JCALL2(GetByteArrayElements, jenv, ba, 0); bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
temp = 0; temp = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
$1 = &temp; $1 = &temp;
@ -416,8 +419,11 @@ INOUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArr
bae = JCALL2(GetByteArrayElements, jenv, ba, 0); bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba); sz = JCALL1(GetArrayLength, jenv, ba);
temp = 0; temp = 0;
for(i=0; i<sz; i++) { if (sz > 0) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i]; temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
} }
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
$1 = &temp; $1 = &temp;