Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion 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 @@ -145,6 +146,22 @@ 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 (long.class == from) {
// long x = 0x100000000LL;
// boolean b = x != 0;
// IMO, return false only if the long is zero.
if (boolean.class == to) {
mv.lconst_0();
mv.lcmp();
Label a = new Label();
mv.ifeq(a);
mv.iconst_1();
Label b = new Label();
mv.go_to(b);
mv.label(a);
mv.iconst_0();
mv.label(b);
return;
}
mv.l2i();
}

Expand All @@ -159,8 +176,14 @@ public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) {

} else if (boolean.class == to) {
// Ensure only 0x0 and 0x1 values are used for boolean
Label l0 = new Label();
mv.ifeq(l0);
mv.iconst_1();
mv.iand();
Label l1 = new Label();
mv.go_to(l1);
mv.label(l0);
mv.iconst_0();
mv.label(l1);
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/test/java/jnr/ffi/NumberTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.Random;

import jnr.ffi.annotations.LongLong;
import jnr.ffi.provider.jffi.NoX86;
import jnr.ffi.types.*;
import org.junit.After;
import org.junit.AfterClass;
Expand Down Expand Up @@ -73,10 +74,18 @@ public static interface TestBoolean {
}
static TestBoolean testboolean;

@NoX86
public static interface TestBooleanNoX86 {
public @int32_t boolean ret_int32_t(@int32_t int l);
public @int64_t boolean ret_int64_t(@int64_t long l);
}
static TestBooleanNoX86 testBooleanNoX86;

@BeforeClass
public static void setUpClass() throws Exception {
testlib = TstUtil.loadTestLib(TestLib.class);
testboolean = TstUtil.loadTestLib(TestBoolean.class);
testBooleanNoX86 = TstUtil.loadTestLib(TestBooleanNoX86.class);
}

@AfterClass
Expand Down Expand Up @@ -357,4 +366,21 @@ public long n(long i1, long i2) {
assertEquals(true, testboolean.ret_int32_t(1));
assertEquals(true, testboolean.ret_int32_t(2));
}

@Test public void testBooleanFromIntNoX86() {
for (int i = -3; i <= 3; ++i) {
boolean expectResult = i != 0;
assertEquals("expect to boolean from '" + i + "'", expectResult, testBooleanNoX86.ret_int32_t(i));
}
}

@Test public void testBooleanFromLongNoX86() {
for (long i = -3; i <= 3; ++i) {
boolean expectResult = i != 0;
assertEquals("expect to boolean from '" + i + "'", expectResult, testBooleanNoX86.ret_int64_t(i));
}
long x = 0x100000000L;
assertEquals("expect to boolean from '" + x + "'", true, testBooleanNoX86.ret_int64_t(x));
}

}