Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix boolean return bugs fixes #170 #123 #138 #183

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jffi</artifactId>
<version>1.2.17</version>
<version>1.2.18</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jffi</artifactId>
<version>1.2.16</version>
<version>1.2.18</version>
<scope>runtime</scope>
<classifier>native</classifier>
</dependency>
Expand Down Expand Up @@ -169,7 +169,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4.2</version>
<version>3.0.0-M2</version>
<configuration>
<systemProperties>
<property>
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/jnr/ffi/Struct.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/jnr/ffi/StructLayout.java
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -333,14 +333,33 @@ 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) {
ptr.putInt(offset(), value ? 1 : 0);
}
}

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.
*/
Expand Down
29 changes: 23 additions & 6 deletions src/main/java/jnr/ffi/provider/jffi/NumberUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import jnr.ffi.NativeType;
import jnr.ffi.provider.SigType;
import org.objectweb.asm.Label;

public final class NumberUtil {
private NumberUtil() {}
Expand Down Expand Up @@ -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();
}
Expand All @@ -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);
}
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
94 changes: 87 additions & 7 deletions src/test/java/jnr/ffi/NumberTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}

}