summaryrefslogtreecommitdiff
path: root/src/main/java/com
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2007-01-28 21:25:21 +0000
committerBrian S. O'Neill <bronee@gmail.com>2007-01-28 21:25:21 +0000
commit27483a11b591e9aa02a7efdbcc8bb8cabe040b1e (patch)
treeb83098847f1cf393d6a5f00a40efe78ce3b82b75 /src/main/java/com
parent975fd9fec74313f52007ebb264a03ec68d33448d (diff)
Fixed bug when filtering against negative floating point values.
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java65
1 files changed, 62 insertions, 3 deletions
diff --git a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
index ea1baa8..4514865 100644
--- a/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
+++ b/src/main/java/com/amazon/carbonado/cursor/FilteredCursorGenerator.java
@@ -282,7 +282,7 @@ class FilteredCursorGenerator {
b.loadConstant(mPropertyOrdinal);
b.loadFromArray(OBJECT);
b.checkCast(type.toObjectType());
- b.convert(type.toObjectType(), fieldType, CodeAssembler.CONVERT_FP_BITS);
+ convertProperty(b, type.toObjectType(), fieldType);
b.storeField(fieldName, fieldType);
// Add code to load property value to stack.
@@ -457,10 +457,10 @@ class FilteredCursorGenerator {
// Floating point values are compared based on actual
// bits. This allows NaN to be considered in the comparison.
if (primitiveType == FLOAT) {
- b.convert(primitiveType, INT, CodeBuilder.CONVERT_FP_BITS);
+ convertProperty(b, primitiveType, INT);
primitiveType = INT;
} else if (primitiveType == DOUBLE) {
- b.convert(primitiveType, LONG, CodeBuilder.CONVERT_FP_BITS);
+ convertProperty(b, primitiveType, LONG);
primitiveType = LONG;
}
@@ -506,6 +506,65 @@ class FilteredCursorGenerator {
}
/**
+ * Converts property value on the stack.
+ */
+ private void convertProperty(CodeBuilder b, TypeDesc fromType, TypeDesc toType) {
+ TypeDesc fromPrimType = fromType.toPrimitiveType();
+
+ if (fromPrimType != TypeDesc.FLOAT && fromPrimType != TypeDesc.DOUBLE) {
+ // Not converting floating point, so just convert as normal.
+ b.convert(fromType, toType);
+ return;
+ }
+
+ TypeDesc toPrimType = toType.toPrimitiveType();
+
+ if (toPrimType != TypeDesc.INT && toPrimType != TypeDesc.LONG) {
+ // Floating point not being converted to bits, so just convert as normal.
+ b.convert(fromType, toType);
+ return;
+ }
+
+ Label done = b.createLabel();
+
+ if (!fromType.isPrimitive() && !toType.isPrimitive()) {
+ b.dup();
+ Label notNull = b.createLabel();
+ b.ifNullBranch(notNull, false);
+ // Need to replace one null with another null.
+ b.pop();
+ b.loadNull();
+ b.branch(done);
+ notNull.setLocation();
+ }
+
+ b.convert(fromType, toPrimType, CodeAssembler.CONVERT_FP_BITS);
+
+ Label box = b.createLabel();
+
+ // Floating point bits need to be flipped for negative values.
+
+ if (toPrimType == TypeDesc.INT) {
+ b.dup();
+ b.ifZeroComparisonBranch(box, ">=");
+ b.loadConstant(0x7fffffff);
+ b.math(Opcode.IXOR);
+ } else {
+ b.dup2();
+ b.loadConstant(0L);
+ b.math(Opcode.LCMP);
+ b.ifZeroComparisonBranch(box, ">=");
+ b.loadConstant(0x7fffffffffffffffL);
+ b.math(Opcode.LXOR);
+ }
+
+ box.setLocation();
+ b.convert(toPrimType, toType);
+
+ done.setLocation();
+ }
+
+ /**
* Defines boolean logic branching scope.
*/
private static class Scope {