# HG changeset patch # User Martin Soch # Date 1359642369 -3600 # Node ID 189f695d0b02f3701288376d82c24e7b4e9b5506 # Parent 5134b1d78432589123327b1ef00f7c8be74f6c50 Added subtraction for Long + tests diff -r 5134b1d78432 -r 189f695d0b02 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 Thu Jan 31 14:45:11 2013 +0100 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Jan 31 15:26:09 2013 +0100 @@ -69,6 +69,17 @@ return hi.next32(low); }; +Number.prototype.sub64 = function(x) { + var low = this - x; + carry = 0; + if (low < 0) { + carry = 1; + low += (__m32+1); + } + var hi = (this.high32() - x.high32() - carry) | 0; + return hi.next32(low); +}; + Number.prototype.div64 = function(x) { var low = Math.floor(this.toFP() / x.toFP()); // TODO: not exact enough if (low > __m32) { diff -r 5134b1d78432 -r 189f695d0b02 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 31 14:45:11 2013 +0100 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Jan 31 15:26:09 2013 +0100 @@ -532,7 +532,7 @@ emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI()); break; case opc_lsub: - emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL()); + emit(out, "@1 = @1.sub64(@2);", smapper.getL(1), smapper.popL()); break; case opc_fsub: emit(out, "@1 -= @2;", smapper.getF(1), smapper.popF()); diff -r 5134b1d78432 -r 189f695d0b02 vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Jan 31 14:45:11 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Jan 31 15:26:09 2013 +0100 @@ -171,6 +171,36 @@ ); } + @Test public void longSubUnderflow() throws Exception { + final long res = Long.MIN_VALUE - 1l; + assertExec("Subtraction MIN-1", + Numbers.class, "subL__J_3B_3B", + Double.valueOf(res), + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, + new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 } + ); + } + + @Test public void longSubMinAndMin() throws Exception { + final long res = Long.MIN_VALUE - Long.MIN_VALUE; + assertExec("Subtraction MIN-MIN", + Numbers.class, "subL__J_3B_3B", + Double.valueOf(res), + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 } + ); + } + + @Test public void longSubMinAndMax() throws Exception { + final long res = Long.MIN_VALUE - Long.MAX_VALUE; + assertExec("Subtraction MIN-MAX", + Numbers.class, "subL__J_3B_3B", + Double.valueOf(res), + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff } + ); + } + @Test public void longShiftL1() throws Exception { final long res = 0x00fa37d7763e0ca1l << 5; assertExec("Long << 5", diff -r 5134b1d78432 -r 189f695d0b02 vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Jan 31 14:45:11 2013 +0100 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Jan 31 15:26:09 2013 +0100 @@ -80,8 +80,12 @@ return (disX.readLong() + disY.readLong()); } - public static long subL(long x, long y) { - return (x - y); + public static long subL(byte[] arrX, byte[] arrY) throws IOException { + ByteArrayInputStream isX = new ByteArrayInputStream(arrX); + DataInputStream disX = new DataInputStream(isX); + ByteArrayInputStream isY = new ByteArrayInputStream(arrY); + DataInputStream disY = new DataInputStream(isY); + return (disX.readLong() - disY.readLong()); } public static long mulL(long x, long y) {