diff --git a/pom.xml b/pom.xml
index 28a9d7010..209289028 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,13 +61,13 @@
com.github.jnr
jffi
- 1.2.17
+ 1.2.18
compile
com.github.jnr
jffi
- 1.2.16
+ 1.2.18
runtime
native
@@ -169,7 +169,7 @@
org.apache.maven.plugins
maven-surefire-plugin
- 2.4.2
+ 3.0.0-M2
diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java
index 38f0d3354..04cfe9ae0 100755
--- a/src/main/java/jnr/ffi/Struct.java
+++ b/src/main/java/jnr/ffi/Struct.java
@@ -783,7 +783,7 @@ public Boolean() {
}
public final boolean get() {
- return (getMemory().getByte(offset()) & 0x1) != 0;
+ return getMemory().getByte(offset()) != 0;
}
public final void set(boolean value) {
@@ -800,7 +800,7 @@ public WBOOL() {
}
public final boolean get() {
- return (getMemory().getInt(offset()) & 0x1) != 0;
+ return getMemory().getInt(offset()) != 0;
}
public final void set(boolean value) {
@@ -814,7 +814,7 @@ public BOOL16() {
}
public final boolean get() {
- return (getMemory().getShort(offset()) & 0x1) != 0;
+ return getMemory().getShort(offset()) != 0;
}
public final void set(boolean value) {
diff --git a/src/main/java/jnr/ffi/StructLayout.java b/src/main/java/jnr/ffi/StructLayout.java
index a1b32cf0b..1dbe5329e 100644
--- a/src/main/java/jnr/ffi/StructLayout.java
+++ b/src/main/java/jnr/ffi/StructLayout.java
@@ -312,7 +312,7 @@ protected Boolean(Offset offset) {
}
public final boolean get(jnr.ffi.Pointer ptr) {
- return (ptr.getByte(offset()) & 0x1) != 0;
+ return ptr.getByte(offset()) != 0;
}
public final void set(jnr.ffi.Pointer ptr, boolean value) {
@@ -333,7 +333,7 @@ protected WBOOL(Offset offset) {
}
public final boolean get(jnr.ffi.Pointer ptr) {
- return (ptr.getInt(offset()) & 0x1) != 0;
+ return ptr.getInt(offset()) != 0;
}
public final void set(jnr.ffi.Pointer ptr, boolean value) {
@@ -341,6 +341,25 @@ public final void set(jnr.ffi.Pointer ptr, boolean value) {
}
}
+ public final class BOOL16 extends AbstractBoolean {
+ protected BOOL16() {
+ super(NativeType.SSHORT);
+ }
+
+ protected BOOL16(Offset offset) {
+ super(NativeType.SSHORT, offset);
+ }
+
+ public final boolean get(jnr.ffi.Pointer ptr) {
+ return ptr.getShort(offset()) != 0;
+ }
+
+ public final void set(jnr.ffi.Pointer ptr, boolean value) {
+ ptr.putShort(offset(), (short) (value ? 1 : 0));
+ }
+ }
+
+
/**
* Base class for all Number structure fields.
*/
diff --git a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java
index 3ca02c51c..d300192ce 100644
--- a/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java
+++ b/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java
@@ -20,6 +20,7 @@
import jnr.ffi.NativeType;
import jnr.ffi.provider.SigType;
+import org.objectweb.asm.Label;
public final class NumberUtil {
private NumberUtil() {}
@@ -143,7 +144,7 @@ public static void widen(SkinnyMethodAdapter mv, Class from, Class to, NativeTyp
public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) {
if (!from.equals(to)) {
- if (byte.class == to || short.class == to || char.class == to || int.class == to || boolean.class == to) {
+ if (byte.class == to || short.class == to || char.class == to || int.class == to) {
if (long.class == from) {
mv.l2i();
}
@@ -156,13 +157,29 @@ public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) {
} else if (char.class == to) {
mv.i2c();
-
- } else if (boolean.class == to) {
- // Ensure only 0x0 and 0x1 values are used for boolean
+ }
+ } else if (boolean.class == to) {
+ Label label_false_branch = new Label();
+ Label label_end = new Label();
+ if (long.class == from) {
+ mv.lconst_0();
+ mv.lcmp();
+ mv.ifeq(label_false_branch);
mv.iconst_1();
- mv.iand();
+ mv.go_to(label_end);
+ mv.label(label_false_branch);
+ mv.iconst_0();
+ mv.label(label_end);
+ } else {
+// mv.iconst_0();
+ mv.ifeq(label_false_branch);
+ mv.iconst_1();
+ mv.go_to(label_end);
+ mv.label(label_false_branch);
+ mv.iconst_0();
+ mv.label(label_end);
}
- }
+ }
}
}
diff --git a/src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java b/src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java
index d75416730..429eb9996 100644
--- a/src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java
+++ b/src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java
@@ -106,8 +106,8 @@ public void generate(AsmBuilder builder, String functionName, Function function,
}
Class nativeReturnType;
- wrapperNeeded |= resultType.getFromNativeConverter() != null || !resultType.effectiveJavaType().isPrimitive();
- if (resultType.effectiveJavaType().isPrimitive()) {
+ wrapperNeeded |= resultType.getFromNativeConverter() != null || !resultType.effectiveJavaType().isPrimitive() || boolean.class.equals(resultType.effectiveJavaType());
+ if (resultType.effectiveJavaType().isPrimitive() && !boolean.class.equals(resultType.effectiveJavaType())) {
nativeReturnType = resultType.effectiveJavaType();
} else {
nativeReturnType = getNativeClass(resultType.getNativeType());
diff --git a/src/test/java/jnr/ffi/NumberTest.java b/src/test/java/jnr/ffi/NumberTest.java
index 10f1c506f..2b217bf87 100644
--- a/src/test/java/jnr/ffi/NumberTest.java
+++ b/src/test/java/jnr/ffi/NumberTest.java
@@ -67,16 +67,38 @@ public static interface TestLib {
}
static TestLib testlib;
- public static interface TestBoolean {
+
+ public static interface Test_Boolean {
+
+ public Boolean ret_int8_t(byte l);
+ public Boolean ret_uint8_t(byte l);
+ public Boolean ret_int16_t(short l);
+ public Boolean ret_uint16_t(short l);
+ public Boolean ret_int32_t(int l);
+ public Boolean ret_uint32_t(int l);
+ public Boolean ret_int64_t(long l);
+ public Boolean ret_uint64_t(long l);
+ }
+ static Test_Boolean test_Boolean;
+ public static interface Test_boolean {
+
+ public boolean ret_int8_t(byte l);
+ public boolean ret_uint8_t(byte l);
+ public boolean ret_int16_t(short l);
+ public boolean ret_uint16_t(short l);
public boolean ret_int32_t(int l);
+ public boolean ret_uint32_t(int l);
+ public boolean ret_int64_t(long l);
+ public boolean ret_uint64_t(long l);
}
- static TestBoolean testboolean;
+ static Test_boolean test_boolean;
@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
- testboolean = TstUtil.loadTestLib(TestBoolean.class);
+ test_boolean = TstUtil.loadTestLib(Test_boolean.class);
+ test_Boolean = TstUtil.loadTestLib(Test_Boolean.class);
}
@AfterClass
@@ -352,9 +374,67 @@ public long n(long i1, long i2) {
}
@Test public void testBooleanFromInt() throws Exception {
- assertEquals(false, testboolean.ret_int32_t(0));
- assertEquals(true, testboolean.ret_int32_t(-1));
- assertEquals(true, testboolean.ret_int32_t(1));
- assertEquals(true, testboolean.ret_int32_t(2));
+ assertEquals(false, test_boolean.ret_int32_t(0));
+ assertEquals(true, test_boolean.ret_int32_t(-1));
+ assertEquals(true, test_boolean.ret_int32_t(1));
+ assertEquals(true, test_boolean.ret_int32_t(2));
+
+ int value = 0x00000001;
+ for (int i = 0; i < 32; i++) {
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_boolean.ret_int32_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_boolean.ret_uint32_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_Boolean.ret_int32_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_Boolean.ret_uint32_t(value));
+ value <<= 1;
+ }
}
+
+ @Test public void testBooleanFromByte() throws Exception {
+ assertEquals(false, test_boolean.ret_int32_t(0));
+ assertEquals(true, test_boolean.ret_int32_t(-1));
+ assertEquals(true, test_boolean.ret_int32_t(1));
+ assertEquals(true, test_boolean.ret_int32_t(2));
+
+ byte value = 0x01;
+ for (int i = 0; i < 8; i++) {
+ assertTrue(String.format("Must evaluate to true: 0x%02x", value), test_boolean.ret_int8_t((byte)value));
+ assertTrue(String.format("Must evaluate to true: 0x%02x", value), test_boolean.ret_uint8_t((byte)value));
+ assertTrue(String.format("Must evaluate to true: 0x%02x", value), test_Boolean.ret_int8_t((byte)value));
+ assertTrue(String.format("Must evaluate to true: 0x%02x", value), test_Boolean.ret_uint8_t((byte)value));
+ value <<= 1;
+ }
+ }
+
+ @Test public void testBooleanFromShort() throws Exception {
+ assertEquals(false, test_boolean.ret_int32_t(0));
+ assertEquals(true, test_boolean.ret_int32_t(-1));
+ assertEquals(true, test_boolean.ret_int32_t(1));
+ assertEquals(true, test_boolean.ret_int32_t(2));
+
+ short value = 0x0001;
+ for (int i = 0; i < 16; i++) {
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_boolean.ret_int16_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_boolean.ret_uint16_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_Boolean.ret_int16_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%04x", value), test_Boolean.ret_uint16_t(value));
+ value <<= 1;
+ }
+ }
+
+ @Test public void testBooleanFromLong() throws Exception {
+ assertEquals(false, test_boolean.ret_int64_t(0));
+ assertEquals(true, test_boolean.ret_int64_t(-1));
+ assertEquals(true, test_boolean.ret_int64_t(1));
+ assertEquals(true, test_boolean.ret_int64_t(2));
+
+ long value = 0x0000000000000001;
+ for (int i = 0; i < 32; i++) {
+ assertTrue(String.format("Must evaluate to true: 0x%016x", value), test_boolean.ret_int64_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%016x", value), test_boolean.ret_uint64_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%016x", value), test_Boolean.ret_int64_t(value));
+ assertTrue(String.format("Must evaluate to true: 0x%016x", value), test_Boolean.ret_uint64_t(value));
+ value <<= 1;
+ }
+ }
+
}