1.1 --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Fri Feb 15 11:40:01 2013 +0100
1.2 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Fri Feb 15 16:06:12 2013 +0100
1.3 @@ -212,6 +212,14 @@
1.4 };
1.5
1.6 (function(numberPrototype) {
1.7 + function __handleDivByZero() {
1.8 + var exception = new vm.java_lang_ArithmeticException;
1.9 + vm.java_lang_ArithmeticException(false).constructor
1.10 + .cons__VLjava_lang_String_2.call(exception, "/ by zero");
1.11 +
1.12 + throw exception;
1.13 + }
1.14 +
1.15 function __Int64(hi32, lo32) {
1.16 this.hi32 = hi32 | 0;
1.17 this.lo32 = lo32 | 0;
1.18 @@ -438,11 +446,27 @@
1.19 r.setDigit(j + n, nrm, uj);
1.20 }
1.21 }
1.22 -
1.23 +
1.24 + numberPrototype.div32 = function(x) {
1.25 + if (x === 0) {
1.26 + __handleDivByZero();
1.27 + }
1.28 +
1.29 + return (this / x) | 0;
1.30 + }
1.31 +
1.32 + numberPrototype.mod32 = function(x) {
1.33 + if (x === 0) {
1.34 + __handleDivByZero();
1.35 + }
1.36 +
1.37 + return (this % x);
1.38 + }
1.39 +
1.40 numberPrototype.div64 = function(x) {
1.41 var negateResult = false;
1.42 var u, v;
1.43 -
1.44 +
1.45 if ((this.high32() & 0x80000000) != 0) {
1.46 u = this.neg64();
1.47 negateResult = !negateResult;
1.48 @@ -458,7 +482,7 @@
1.49 }
1.50
1.51 if ((v === 0) && (v.high32() === 0)) {
1.52 - // TODO: throw
1.53 + __handleDivByZero();
1.54 }
1.55
1.56 if (u.high32() === 0) {
1.57 @@ -499,7 +523,7 @@
1.58 }
1.59
1.60 if ((v === 0) && (v.high32() === 0)) {
1.61 - // TODO: throw
1.62 + __handleDivByZero();
1.63 }
1.64
1.65 if (u.high32() === 0) {
2.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Feb 15 11:40:01 2013 +0100
2.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Feb 15 16:06:12 2013 +0100
2.3 @@ -553,7 +553,7 @@
2.4 emit(out, "@1 *= @2;", smapper.getD(1), smapper.popD());
2.5 break;
2.6 case opc_idiv:
2.7 - emit(out, "@1 = Math.floor(@1 / @2);",
2.8 + emit(out, "@1 = @1.div32(@2);",
2.9 smapper.getI(1), smapper.popI());
2.10 break;
2.11 case opc_ldiv:
2.12 @@ -567,7 +567,8 @@
2.13 emit(out, "@1 /= @2;", smapper.getD(1), smapper.popD());
2.14 break;
2.15 case opc_irem:
2.16 - emit(out, "@1 %= @2;", smapper.getI(1), smapper.popI());
2.17 + emit(out, "@1 = @1.mod32(@2);",
2.18 + smapper.getI(1), smapper.popI());
2.19 break;
2.20 case opc_lrem:
2.21 emit(out, "@1 = @1.mod64(@2);",
3.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Fri Feb 15 11:40:01 2013 +0100
3.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java Fri Feb 15 16:06:12 2013 +0100
3.3 @@ -94,7 +94,33 @@
3.4 @Compare public int divisionReminder() {
3.5 return mod(1, 2);
3.6 }
3.7 -
3.8 +
3.9 + @Compare public int negativeDivision() {
3.10 + return div(-7, 3);
3.11 + }
3.12 +
3.13 + @Compare public int negativeDivisionReminder() {
3.14 + return mod(-7, 3);
3.15 + }
3.16 +
3.17 + @Compare public boolean divByZeroThrowsArithmeticException() {
3.18 + try {
3.19 + div(1, 0);
3.20 + return false;
3.21 + } catch (final ArithmeticException e) {
3.22 + return true;
3.23 + }
3.24 + }
3.25 +
3.26 + @Compare public boolean modByZeroThrowsArithmeticException() {
3.27 + try {
3.28 + mod(1, 0);
3.29 + return false;
3.30 + } catch (final ArithmeticException e) {
3.31 + return true;
3.32 + }
3.33 + }
3.34 +
3.35 @Compare public int negate() {
3.36 return neg(123456);
3.37 }
4.1 --- a/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Fri Feb 15 11:40:01 2013 +0100
4.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Fri Feb 15 16:06:12 2013 +0100
4.3 @@ -250,7 +250,25 @@
4.4 @Compare public long moduloWithCorrection() {
4.5 return mod(0x7fff800000000000l, 0x800000000001l);
4.6 }
4.7 -
4.8 +
4.9 + @Compare public boolean divByZeroThrowsArithmeticException() {
4.10 + try {
4.11 + div(1, 0);
4.12 + return false;
4.13 + } catch (final ArithmeticException e) {
4.14 + return true;
4.15 + }
4.16 + }
4.17 +
4.18 + @Compare public boolean modByZeroThrowsArithmeticException() {
4.19 + try {
4.20 + mod(1, 0);
4.21 + return false;
4.22 + } catch (final ArithmeticException e) {
4.23 + return true;
4.24 + }
4.25 + }
4.26 +
4.27 @Compare public long shiftL1() {
4.28 return shl(0x00fa37d7763e0ca1l, 5);
4.29 }