1.1 --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Jan 31 14:45:11 2013 +0100
1.2 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Jan 31 15:26:09 2013 +0100
1.3 @@ -69,6 +69,17 @@
1.4 return hi.next32(low);
1.5 };
1.6
1.7 +Number.prototype.sub64 = function(x) {
1.8 + var low = this - x;
1.9 + carry = 0;
1.10 + if (low < 0) {
1.11 + carry = 1;
1.12 + low += (__m32+1);
1.13 + }
1.14 + var hi = (this.high32() - x.high32() - carry) | 0;
1.15 + return hi.next32(low);
1.16 +};
1.17 +
1.18 Number.prototype.div64 = function(x) {
1.19 var low = Math.floor(this.toFP() / x.toFP()); // TODO: not exact enough
1.20 if (low > __m32) {
2.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 31 14:45:11 2013 +0100
2.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 31 15:26:09 2013 +0100
2.3 @@ -532,7 +532,7 @@
2.4 emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI());
2.5 break;
2.6 case opc_lsub:
2.7 - emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
2.8 + emit(out, "@1 = @1.sub64(@2);", smapper.getL(1), smapper.popL());
2.9 break;
2.10 case opc_fsub:
2.11 emit(out, "@1 -= @2;", smapper.getF(1), smapper.popF());
3.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Jan 31 14:45:11 2013 +0100
3.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Jan 31 15:26:09 2013 +0100
3.3 @@ -171,6 +171,36 @@
3.4 );
3.5 }
3.6
3.7 + @Test public void longSubUnderflow() throws Exception {
3.8 + final long res = Long.MIN_VALUE - 1l;
3.9 + assertExec("Subtraction MIN-1",
3.10 + Numbers.class, "subL__J_3B_3B",
3.11 + Double.valueOf(res),
3.12 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
3.13 + new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
3.14 + );
3.15 + }
3.16 +
3.17 + @Test public void longSubMinAndMin() throws Exception {
3.18 + final long res = Long.MIN_VALUE - Long.MIN_VALUE;
3.19 + assertExec("Subtraction MIN-MIN",
3.20 + Numbers.class, "subL__J_3B_3B",
3.21 + Double.valueOf(res),
3.22 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
3.23 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
3.24 + );
3.25 + }
3.26 +
3.27 + @Test public void longSubMinAndMax() throws Exception {
3.28 + final long res = Long.MIN_VALUE - Long.MAX_VALUE;
3.29 + assertExec("Subtraction MIN-MAX",
3.30 + Numbers.class, "subL__J_3B_3B",
3.31 + Double.valueOf(res),
3.32 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
3.33 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
3.34 + );
3.35 + }
3.36 +
3.37 @Test public void longShiftL1() throws Exception {
3.38 final long res = 0x00fa37d7763e0ca1l << 5;
3.39 assertExec("Long << 5",
4.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Jan 31 14:45:11 2013 +0100
4.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Jan 31 15:26:09 2013 +0100
4.3 @@ -80,8 +80,12 @@
4.4 return (disX.readLong() + disY.readLong());
4.5 }
4.6
4.7 - public static long subL(long x, long y) {
4.8 - return (x - y);
4.9 + public static long subL(byte[] arrX, byte[] arrY) throws IOException {
4.10 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
4.11 + DataInputStream disX = new DataInputStream(isX);
4.12 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
4.13 + DataInputStream disY = new DataInputStream(isY);
4.14 + return (disX.readLong() - disY.readLong());
4.15 }
4.16
4.17 public static long mulL(long x, long y) {