# HG changeset patch # User Jaroslav Tulach # Date 1361787492 -3600 # Node ID 39712168230d3ef1425b172b6da2b17284ee8475 # Parent c6878807b0d47eae0301efde41bf60f55c8caa6f# Parent cc0e6767259b352bba903b921f1e7519e1602bb7 Merge of Lubo's fix to David's problem: Infinity and div by zero diff -r c6878807b0d4 -r 39712168230d emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/JFXIssuesTest.java --- a/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/JFXIssuesTest.java Sat Feb 16 11:02:15 2013 +0100 +++ b/emul/compact/src/test/java/org/apidesign/bck2brwsr/compact/tck/JFXIssuesTest.java Mon Feb 25 11:18:12 2013 +0100 @@ -39,7 +39,15 @@ @Compare public boolean isClassAssignable() { return Application.class.isAssignableFrom(MyApplication.class); } - + + @Compare public boolean isNaN() { + return Double.isNaN(Double.NaN); + } + + @Compare public boolean isInfinite() { + return Float.isInfinite(Float.NEGATIVE_INFINITY); + } + @Factory public static Object[] create() { return VMTest.create(JFXIssuesTest.class); } diff -r c6878807b0d4 -r 39712168230d emul/mini/src/main/java/java/lang/Double.java --- a/emul/mini/src/main/java/java/lang/Double.java Sat Feb 16 11:02:15 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/Double.java Mon Feb 25 11:18:12 2013 +0100 @@ -191,7 +191,7 @@ * @return a string representation of the argument. */ @JavaScriptBody(args="d", body="var r = d.toString();" - + "if (r.indexOf('.') === -1) r = r + '.0';" + + "if (isFinite(d) && (r.indexOf('.') === -1)) r = r + '.0';" + "return r;") public static String toString(double d) { throw new UnsupportedOperationException(); diff -r c6878807b0d4 -r 39712168230d emul/mini/src/main/java/java/lang/Float.java --- a/emul/mini/src/main/java/java/lang/Float.java Sat Feb 16 11:02:15 2013 +0100 +++ b/emul/mini/src/main/java/java/lang/Float.java Mon Feb 25 11:18:12 2013 +0100 @@ -819,11 +819,15 @@ */ @JavaScriptBody(args = "bits", body = - "if (bits === 0x7f800000) return Number.POSITIVE_INFINITY;\n" - + "if (bits === 0xff800000) return Number.NEGATIVE_INFINITY;\n" - + "if (bits >= 0x7f800001 && bits <= 0xffffffff) return Number.NaN;\n" - + "var s = ((bits >> 31) == 0) ? 1 : -1;\n" + "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" + + "}\n" + "var m = (e == 0) ?\n" + " (bits & 0x7fffff) << 1 :\n" + " (bits & 0x7fffff) | 0x800000;\n" diff -r c6878807b0d4 -r 39712168230d emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Sat Feb 16 11:02:15 2013 +0100 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Mon Feb 25 11:18:12 2013 +0100 @@ -212,6 +212,14 @@ }; (function(numberPrototype) { + function __handleDivByZero() { + var exception = new vm.java_lang_ArithmeticException; + vm.java_lang_ArithmeticException(false).constructor + .cons__VLjava_lang_String_2.call(exception, "/ by zero"); + + throw exception; + } + function __Int64(hi32, lo32) { this.hi32 = hi32 | 0; this.lo32 = lo32 | 0; @@ -438,11 +446,27 @@ r.setDigit(j + n, nrm, uj); } } - + + numberPrototype.div32 = function(x) { + if (x === 0) { + __handleDivByZero(); + } + + return (this / x) | 0; + } + + numberPrototype.mod32 = function(x) { + if (x === 0) { + __handleDivByZero(); + } + + return (this % x); + } + numberPrototype.div64 = function(x) { var negateResult = false; var u, v; - + if ((this.high32() & 0x80000000) != 0) { u = this.neg64(); negateResult = !negateResult; @@ -458,7 +482,7 @@ } if ((v === 0) && (v.high32() === 0)) { - // TODO: throw + __handleDivByZero(); } if (u.high32() === 0) { @@ -499,7 +523,7 @@ } if ((v === 0) && (v.high32() === 0)) { - // TODO: throw + __handleDivByZero(); } if (u.high32() === 0) { diff -r c6878807b0d4 -r 39712168230d vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sat Feb 16 11:02:15 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Feb 25 11:18:12 2013 +0100 @@ -555,7 +555,7 @@ emit(out, "@1 *= @2;", smapper.getD(1), smapper.popD()); break; case opc_idiv: - emit(out, "@1 = Math.floor(@1 / @2);", + emit(out, "@1 = @1.div32(@2);", smapper.getI(1), smapper.popI()); break; case opc_ldiv: @@ -569,7 +569,8 @@ emit(out, "@1 /= @2;", smapper.getD(1), smapper.popD()); break; case opc_irem: - emit(out, "@1 %= @2;", smapper.getI(1), smapper.popI()); + emit(out, "@1 = @1.mod32(@2);", + smapper.getI(1), smapper.popI()); break; case opc_lrem: emit(out, "@1 = @1.mod64(@2);", diff -r c6878807b0d4 -r 39712168230d vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Sat Feb 16 11:02:15 2013 +0100 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Mon Feb 25 11:18:12 2013 +0100 @@ -94,7 +94,33 @@ @Compare public int divisionReminder() { return mod(1, 2); } - + + @Compare public int negativeDivision() { + return div(-7, 3); + } + + @Compare public int negativeDivisionReminder() { + return mod(-7, 3); + } + + @Compare public boolean divByZeroThrowsArithmeticException() { + try { + div(1, 0); + return false; + } catch (final ArithmeticException e) { + return true; + } + } + + @Compare public boolean modByZeroThrowsArithmeticException() { + try { + mod(1, 0); + return false; + } catch (final ArithmeticException e) { + return true; + } + } + @Compare public int negate() { return neg(123456); } diff -r c6878807b0d4 -r 39712168230d vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Sat Feb 16 11:02:15 2013 +0100 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Mon Feb 25 11:18:12 2013 +0100 @@ -250,7 +250,25 @@ @Compare public long moduloWithCorrection() { return mod(0x7fff800000000000l, 0x800000000001l); } - + + @Compare public boolean divByZeroThrowsArithmeticException() { + try { + div(1, 0); + return false; + } catch (final ArithmeticException e) { + return true; + } + } + + @Compare public boolean modByZeroThrowsArithmeticException() { + try { + mod(1, 0); + return false; + } catch (final ArithmeticException e) { + return true; + } + } + @Compare public long shiftL1() { return shl(0x00fa37d7763e0ca1l, 5); }