From 27483a11b591e9aa02a7efdbcc8bb8cabe040b1e Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Sun, 28 Jan 2007 21:25:21 +0000 Subject: Fixed bug when filtering against negative floating point values. --- .../carbonado/cursor/FilteredCursorGenerator.java | 65 +++++++++++++++++++++- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'src/main/java') 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; } @@ -505,6 +505,65 @@ class FilteredCursorGenerator { return type; } + /** + * 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. */ -- cgit v1.2.3