# HG changeset patch # User Lubomir Nerad # Date 1361978682 -3600 # Node ID 6f8683517f1f186954e7acb5edfc9d27662edaf9 # Parent 42bc1e89134dda2def7bfd2fc464004a3244940e Conversion fixes diff -r 42bc1e89134d -r 6f8683517f1f rt/emul/mini/src/main/java/java/io/DataInputStream.java --- a/rt/emul/mini/src/main/java/java/io/DataInputStream.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/emul/mini/src/main/java/java/io/DataInputStream.java Wed Feb 27 16:24:42 2013 +0100 @@ -468,42 +468,8 @@ * @see java.lang.Double#longBitsToDouble(long) */ public final double readDouble() throws IOException { - int hi = readInt(); - int low = readInt(); - return toDouble(hi, low); - } - - @JavaScriptBody(args={ "hi", "low" }, - body= - "if (low == 0) {\n" - + " if (hi === 0x7ff00000) return Number.POSITIVE_INFINITY;\n" - + " if (hi === 0xfff00000) return Number.NEGATIVE_INFINITY;\n" - + "}\n" - + "if (hi >= 0x7ff00000 && hi <= 0x7fffffff) return Number.NaN;\n" - + "if (hi >= 0xfff00000 && hi <= 0xffffffff) return Number.NaN;\n" - + "var s = (hi & 0x80000000) === 0 ? 1 : -1;\n" - + "var e = (hi >> 20) & 0x7ff;\n" - + "var to32 = low >> 0;\n" - + "if (e === 0) {\n" - + " if (to32 & 0x80000000) {\n" - + " hi = hi << 1 + 1; low = low << 1;\n" - + " } else {\n" - + " hi = hi << 1; low = low << 1;\n" - + " }\n" - + "} else {\n" - + " hi = (hi & 0xfffff) | 0x100000;\n" - + "}\n" - + "to32 = low >> 0;\n" - + "var m = Math.pow(2.0, 32) * hi + to32;\n" - + "var r = s * m * Math.pow(2.0, e - 1075);\n" - + "//throw 'exp: ' + e + ' sign: ' + s + ' hi:' + hi + ' low: ' + low + ' m: ' + m + ' r: ' + r;\n" - + "return r;\n" - ) - private static double toDouble(int hi, int low) { - long both = hi; - both = (both << 32) & low; - return Double.doubleToLongBits(both); - } + return Double.longBitsToDouble(readLong()); + } private char lineBuffer[]; diff -r 42bc1e89134d -r 6f8683517f1f rt/emul/mini/src/main/java/java/lang/Double.java --- a/rt/emul/mini/src/main/java/java/lang/Double.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/emul/mini/src/main/java/java/lang/Double.java Wed Feb 27 16:24:42 2013 +0100 @@ -920,6 +920,26 @@ * @return the {@code double} floating-point value with the same * bit pattern. */ + @JavaScriptBody(args={ "bits" }, + body= + "var hi = bits.high32();\n" + + "var s = (hi & 0x80000000) === 0 ? 1 : -1;\n" + + "var e = (hi >> 20) & 0x7ff;\n" + + "if (e === 0x7ff) {\n" + + " if ((bits == 0) && ((hi & 0xfffff) === 0)) {\n" + + " return (s > 0) ? Number.POSITIVE_INFINITY" + + " : Number.NEGATIVE_INFINITY;\n" + + " }\n" + + " return Number.NaN;\n" + + "}\n" + + "var m = (hi & 0xfffff).next32(bits);\n" + + "if (e === 0) {\n" + + " m = m.shl64(1);\n" + + "} else {\n" + + " m.hi = m.high32() | 0x100000;\n" + + "}\n" + + "return s * m.toFP() * Math.pow(2.0, e - 1075);\n" + ) public static native double longBitsToDouble(long bits); /** diff -r 42bc1e89134d -r 6f8683517f1f rt/emul/mini/src/main/java/java/lang/Float.java --- a/rt/emul/mini/src/main/java/java/lang/Float.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/emul/mini/src/main/java/java/lang/Float.java Wed Feb 27 16:24:42 2013 +0100 @@ -822,13 +822,13 @@ "var s = ((bits >> 31) == 0) ? 1 : -1;\n" + "var e = ((bits >> 23) & 0xff);\n" + "if (e === 0xff) {\n" - + " if ((bits & 0x7fffff) === 0) {\n" - + " return (s > 0) ? Number.POSITIVE_INFINITY" - + " : Number.NEGATIVE_INFINITY;\n" - + " }\n" - + " return Number.NaN;\n" + + " if ((bits & 0x7fffff) === 0) {\n" + + " return (s > 0) ? Number.POSITIVE_INFINITY" + + " : Number.NEGATIVE_INFINITY;\n" + + " }\n" + + " return Number.NaN;\n" + "}\n" - + "var m = (e == 0) ?\n" + + "var m = (e === 0) ?\n" + " (bits & 0x7fffff) << 1 :\n" + " (bits & 0x7fffff) | 0x800000;\n" + "return s * m * Math.pow(2.0, e - 150);\n" diff -r 42bc1e89134d -r 6f8683517f1f rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Wed Feb 27 16:24:42 2013 +0100 @@ -28,8 +28,17 @@ return this.hi ? this.hi * (__m32+1) + this : this; }; Number.prototype.toLong = function() { - var hi = (this > __m32) ? (Math.floor(this / (__m32+1))) | 0 : 0; - return hi.next32(Math.floor(this % (__m32+1))); + var hi = (this / (__m32+1)) | 0; + var low = (this % (__m32+1)) | 0; + if (low < 0) { + low += __m32+1; + } + + if (this < 0) { + hi -= 1; + } + + return hi.next32(low); }; Number.prototype.toExactString = function() { @@ -481,7 +490,7 @@ v = x; } - if ((v === 0) && (v.high32() === 0)) { + if ((v == 0) && (v.high32() === 0)) { __handleDivByZero(); } @@ -522,7 +531,7 @@ v = x; } - if ((v === 0) && (v.high32() === 0)) { + if ((v == 0) && (v.high32() === 0)) { __handleDivByZero(); } diff -r 42bc1e89134d -r 6f8683517f1f rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Feb 27 16:24:42 2013 +0100 @@ -691,19 +691,19 @@ emit(out, "var @2 = @1;", smapper.popD(), smapper.pushF()); break; case opc_f2i: - emit(out, "var @2 = Math.floor(@1).toInt32();", + emit(out, "var @2 = @1.toInt32();", smapper.popF(), smapper.pushI()); break; case opc_f2l: - emit(out, "var @2 = Math.floor(@1).toLong();", + emit(out, "var @2 = @1.toLong();", smapper.popF(), smapper.pushL()); break; case opc_d2i: - emit(out, "var @2 = Math.floor(@1).toInt32();", + emit(out, "var @2 = @1.toInt32();", smapper.popD(), smapper.pushI()); break; case opc_d2l: - emit(out, "var @2 = Math.floor(@1).toLong();", + emit(out, "var @2 = @1.toLong();", smapper.popD(), smapper.pushL()); break; case opc_i2b: diff -r 42bc1e89134d -r 6f8683517f1f rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Wed Feb 27 16:24:42 2013 +0100 @@ -50,6 +50,14 @@ private static int neg(int x) { return (-x); } + + private static float fadd(float x, float y) { + return x + y; + } + + private static double dadd(double x, double y) { + return x + y; + } @Compare public int addOverflow() { return add(Integer.MAX_VALUE, 1); @@ -90,7 +98,7 @@ @Compare public int division() { return div(1, 2); } - + @Compare public int divisionReminder() { return mod(1, 2); } @@ -103,6 +111,14 @@ return mod(-7, 3); } + @Compare public int conversionFromFloat() { + return (int) fadd(-2, -0.6f); + } + + @Compare public int conversionFromDouble() { + return (int) dadd(-2, -0.6); + } + @Compare public boolean divByZeroThrowsArithmeticException() { try { div(1, 0); diff -r 42bc1e89134d -r 6f8683517f1f rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Wed Feb 27 11:24:58 2013 +0100 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Wed Feb 27 16:24:42 2013 +0100 @@ -26,55 +26,63 @@ * @author Jaroslav Tulach */ public class LongArithmeticTest { - + private static long add(long x, long y) { return (x + y); } - + private static long sub(long x, long y) { return (x - y); } - + private static long mul(long x, long y) { return (x * y); } - + private static long div(long x, long y) { return (x / y); } - + private static long mod(long x, long y) { return (x % y); } - + private static long neg(long x) { return (-x); } - + private static long shl(long x, int b) { return (x << b); } - + private static long shr(long x, int b) { return (x >> b); } - + private static long ushr(long x, int b) { return (x >>> b); } - + private static long and(long x, long y) { return (x & y); } - + private static long or(long x, long y) { return (x | y); } - + private static long xor(long x, long y) { return (x ^ y); } - + + private static float fadd(float x, float y) { + return x + y; + } + + private static double dadd(double x, double y) { + return x + y; + } + public static int compare(long x, long y, int zero) { final int xyResult = compareL(x, y, zero); final int yxResult = compareL(y, x, zero); @@ -106,15 +114,15 @@ return (trueCount == 1) ? result : -2; } - + @Compare public long conversion() { return Long.MAX_VALUE; } - + @Compare public long negate1() { return neg(0x00fa37d7763e0ca1l); } - + @Compare public long negate2() { return neg(0x80fa37d7763e0ca1l); } @@ -134,11 +142,11 @@ @Compare public long addMaxLongAndMaxLong() { return add(Long.MAX_VALUE, Long.MAX_VALUE); } - + @Compare public long subMinLongAndMinLong() { return sub(Long.MIN_VALUE, Long.MIN_VALUE); } - + @Compare public long subMinLongAndMaxLong() { return sub(Long.MIN_VALUE, Long.MAX_VALUE); } @@ -146,23 +154,23 @@ @Compare public long multiplyMaxLong() { return mul(Long.MAX_VALUE, 2l); } - + @Compare public long multiplyMaxLongAndMaxLong() { return mul(Long.MAX_VALUE, Long.MAX_VALUE); } - + @Compare public long multiplyMinLong() { return mul(Long.MIN_VALUE, 2l); } - + @Compare public long multiplyMinLongAndMinLong() { return mul(Long.MIN_VALUE, Long.MIN_VALUE); } - + @Compare public long multiplyPrecision() { return mul(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); } - + @Compare public long divideSmallPositiveNumbers() { return div(0xabcdef, 0x123); } @@ -251,6 +259,22 @@ return mod(0x7fff800000000000l, 0x800000000001l); } + @Compare public long conversionFromFloatPositive() { + return (long) fadd(2, 0.6f); + } + + @Compare public long conversionFromFloatNegative() { + return (long) fadd(-2, -0.6f); + } + + @Compare public long conversionFromDoublePositive() { + return (long) dadd(0x20ffff0000L, 0.6); + } + + @Compare public long conversionFromDoubleNegative() { + return (long) dadd(-0x20ffff0000L, -0.6); + } + @Compare public boolean divByZeroThrowsArithmeticException() { try { div(1, 0); @@ -272,63 +296,63 @@ @Compare public long shiftL1() { return shl(0x00fa37d7763e0ca1l, 5); } - + @Compare public long shiftL2() { return shl(0x00fa37d7763e0ca1l, 32); } - + @Compare public long shiftL3() { return shl(0x00fa37d7763e0ca1l, 45); } - + @Compare public long shiftR1() { return shr(0x00fa37d7763e0ca1l, 5); } - + @Compare public long shiftR2() { return shr(0x00fa37d7763e0ca1l, 32); } - + @Compare public long shiftR3() { return shr(0x00fa37d7763e0ca1l, 45); } - + @Compare public long uShiftR1() { return ushr(0x00fa37d7763e0ca1l, 5); } - + @Compare public long uShiftR2() { return ushr(0x00fa37d7763e0ca1l, 45); } - + @Compare public long uShiftR3() { return ushr(0xf0fa37d7763e0ca1l, 5); } - + @Compare public long uShiftR4() { return ushr(0xf0fa37d7763e0ca1l, 45); } - + @Compare public long and1() { return and(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); } - + @Compare public long or1() { return or(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); } - + @Compare public long xor1() { return xor(0x00fa37d7763e0ca1l, 0xa7b3432fff00123el); } - + @Compare public long xor2() { return xor(0x00fa37d7763e0ca1l, 0x00000000ff00123el); } - + @Compare public long xor3() { return xor(0x00000000763e0ca1l, 0x00000000ff00123el); } - + @Compare public int compareSameNumbers() { return compare(0x0000000000000000l, 0x0000000000000000l, 0); }