1.1 --- a/emul/mini/src/main/java/java/lang/Character.java Thu Feb 07 12:58:12 2013 +0100
1.2 +++ b/emul/mini/src/main/java/java/lang/Character.java Thu Feb 07 13:07:22 2013 +0100
1.3 @@ -2193,6 +2193,10 @@
1.4 * @see Character#isDigit(int)
1.5 * @since 1.5
1.6 */
1.7 + @JavaScriptBody(args = { "codePoint", "radix" }, body=
1.8 + "var x = parseInt(String.fromCharCode(codePoint), radix);\n"
1.9 + + "return isNaN(x) ? -1 : x;"
1.10 + )
1.11 public static int digit(int codePoint, int radix) {
1.12 throw new UnsupportedOperationException();
1.13 }
2.1 --- a/emul/mini/src/main/java/java/lang/Long.java Thu Feb 07 12:58:12 2013 +0100
2.2 +++ b/emul/mini/src/main/java/java/lang/Long.java Thu Feb 07 13:07:22 2013 +0100
2.3 @@ -262,7 +262,7 @@
2.4 * @param i a {@code long} to be converted.
2.5 * @return a string representation of the argument in base 10.
2.6 */
2.7 - @JavaScriptBody(args = "i", body = "return i.toString();")
2.8 + @JavaScriptBody(args = "i", body = "return i.toExactString();")
2.9 public static String toString(long i) {
2.10 if (i == Long.MIN_VALUE)
2.11 return "-9223372036854775808";
3.1 --- a/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Thu Feb 07 12:58:12 2013 +0100
3.2 +++ b/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Thu Feb 07 13:07:22 2013 +0100
3.3 @@ -54,7 +54,7 @@
3.4 )
3.5 public static native byte[] expandArray(byte[] arr, int expectedSize);
3.6
3.7 - @JavaScriptBody(args = {}, body = "new Date().getMilliseconds();")
3.8 + @JavaScriptBody(args = {}, body = "return new Date().getMilliseconds();")
3.9 public static native long currentTimeMillis();
3.10
3.11 public static long nanoTime() {
4.1 --- a/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Feb 07 12:58:12 2013 +0100
4.2 +++ b/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Feb 07 13:07:22 2013 +0100
4.3 @@ -6,4 +6,509 @@
4.4 };
4.5
4.6 Number.prototype.toInt8 = function() { return (this << 24) >> 24; };
4.7 -Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
4.8 \ No newline at end of file
4.9 +Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
4.10 +
4.11 +var __m32 = 0xFFFFFFFF;
4.12 +
4.13 +Number.prototype.next32 = function(low) {
4.14 + if (this === 0) {
4.15 + return low;
4.16 + }
4.17 + var l = new Number(low);
4.18 + l.hi = this | 0;
4.19 + return l;
4.20 +};
4.21 +
4.22 +Number.prototype.high32 = function() {
4.23 + return this.hi ? this.hi : (Math.floor(this / (__m32+1))) | 0;
4.24 +};
4.25 +Number.prototype.toInt32 = function() { return this | 0; };
4.26 +Number.prototype.toFP = function() {
4.27 + return this.hi ? this.hi * (__m32+1) + this : this;
4.28 +};
4.29 +Number.prototype.toLong = function() {
4.30 + var hi = (this > __m32) ? (Math.floor(this / (__m32+1))) | 0 : 0;
4.31 + return hi.next32(Math.floor(this % (__m32+1)));
4.32 +};
4.33 +
4.34 +Number.prototype.toExactString = function() {
4.35 + if (this.hi) {
4.36 + var res = 0;
4.37 + var a = [ 6,9,2,7,6,9,4,9,2,4 ];
4.38 + var s = '';
4.39 + var digit;
4.40 + var neg = this.hi < 0;
4.41 + if (neg) {
4.42 + var x = this.neg64();
4.43 + var hi = x.hi;
4.44 + var low = x;
4.45 + } else {
4.46 + var hi = this.hi;
4.47 + var low = this;
4.48 + }
4.49 + for (var i = 0; i < a.length; i++) {
4.50 + res += hi * a[i];
4.51 + var low_digit = low % 10;
4.52 + digit = (res % 10) + low_digit;
4.53 +
4.54 + low = Math.floor(low / 10);
4.55 + res = Math.floor(res / 10);
4.56 +
4.57 + if (digit >= 10) {
4.58 + digit -= 10;
4.59 + res++;
4.60 + }
4.61 + s = String(digit).concat(s);
4.62 + }
4.63 + return (neg ? '-' : '').concat(res).concat(s);
4.64 + }
4.65 + return String(this);
4.66 +};
4.67 +
4.68 +Number.prototype.add64 = function(x) {
4.69 + var low = this + x;
4.70 + carry = 0;
4.71 + if (low > __m32) {
4.72 + carry = 1;
4.73 + low -= (__m32+1);
4.74 + }
4.75 + var hi = (this.high32() + x.high32() + carry) | 0;
4.76 + return hi.next32(low);
4.77 +};
4.78 +
4.79 +Number.prototype.sub64 = function(x) {
4.80 + var low = this - x;
4.81 + carry = 0;
4.82 + if (low < 0) {
4.83 + carry = 1;
4.84 + low += (__m32+1);
4.85 + }
4.86 + var hi = (this.high32() - x.high32() - carry) | 0;
4.87 + return hi.next32(low);
4.88 +};
4.89 +
4.90 +Number.prototype.mul64 = function(x) {
4.91 + var low = this.mul32(x);
4.92 + low += (low < 0) ? (__m32+1) : 0;
4.93 + // first count upper 32 bits of (this.low * x.low)
4.94 + var hi_hi = 0;
4.95 + var hi_low = 0;
4.96 + var m = 1;
4.97 + for (var i = 0; i < 32; i++) {
4.98 + if (x & m) {
4.99 + hi_hi += this >>> 16;
4.100 + hi_low += this & 0xFFFF
4.101 + }
4.102 + hi_low >>= 1;
4.103 + hi_low += (hi_hi & 1) ? 0x8000 : 0;
4.104 + hi_hi >>= 1;
4.105 + m <<= 1;
4.106 + }
4.107 + var hi = (hi_hi << 16) + hi_low;
4.108 +
4.109 + var m1 = this.high32().mul32(x);
4.110 + var m2 = this.mul32(x.high32());
4.111 + hi = hi.add32(m1).add32(m2);
4.112 +
4.113 + return hi.next32(low);
4.114 +};
4.115 +
4.116 +Number.prototype.and64 = function(x) {
4.117 + var low = this & x;
4.118 + low += (low < 0) ? (__m32+1) : 0;
4.119 + if (this.hi && x.hi) {
4.120 + var hi = this.hi & x.hi;
4.121 + return hi.next32(low);
4.122 + };
4.123 + return low;
4.124 +};
4.125 +
4.126 +Number.prototype.or64 = function(x) {
4.127 + var low = this | x;
4.128 + low += (low < 0) ? (__m32+1) : 0;
4.129 + if (this.hi || x.hi) {
4.130 + var hi = this.hi | x.hi;
4.131 + return hi.next32(low);
4.132 + };
4.133 + return low;
4.134 +};
4.135 +
4.136 +Number.prototype.xor64 = function(x) {
4.137 + var low = this ^ x;
4.138 + low += (low < 0) ? (__m32+1) : 0;
4.139 + if (this.hi || x.hi) {
4.140 + var hi = this.hi ^ x.hi;
4.141 + return hi.next32(low);
4.142 + };
4.143 + return low;
4.144 +};
4.145 +
4.146 +Number.prototype.shl64 = function(x) {
4.147 + if (x >= 32) {
4.148 + var hi = this << (x - 32);
4.149 + return hi.next32(0);
4.150 + } else {
4.151 + var hi = this.high32() << x;
4.152 + var low_reminder = this >> (32 - x);
4.153 + hi |= low_reminder;
4.154 + var low = this << x;
4.155 + low += (low < 0) ? (__m32+1) : 0;
4.156 + return hi.next32(low);
4.157 + }
4.158 +};
4.159 +
4.160 +Number.prototype.shr64 = function(x) {
4.161 + if (x >= 32) {
4.162 + var low = this.high32() >> (x - 32);
4.163 + low += (low < 0) ? (__m32+1) : 0;
4.164 + return low;
4.165 + } else {
4.166 + var low = this >> x;
4.167 + var hi_reminder = this.high32() << (32 - x);
4.168 + low |= hi_reminder;
4.169 + low += (low < 0) ? (__m32+1) : 0;
4.170 + var hi = this.high32() >> x;
4.171 + return hi.next32(low);
4.172 + }
4.173 +};
4.174 +
4.175 +Number.prototype.ushr64 = function(x) {
4.176 + if (x >= 32) {
4.177 + var low = this.high32() >>> (x - 32);
4.178 + low += (low < 0) ? (__m32+1) : 0;
4.179 + return low;
4.180 + } else {
4.181 + var low = this >>> x;
4.182 + var hi_reminder = this.high32() << (32 - x);
4.183 + low |= hi_reminder;
4.184 + low += (low < 0) ? (__m32+1) : 0;
4.185 + var hi = this.high32() >>> x;
4.186 + return hi.next32(low);
4.187 + }
4.188 +};
4.189 +
4.190 +Number.prototype.compare64 = function(x) {
4.191 + if (this.high32() === x.high32()) {
4.192 + return (this < x) ? -1 : ((this > x) ? 1 : 0);
4.193 + }
4.194 + return (this.high32() < x.high32()) ? -1 : 1;
4.195 +};
4.196 +
4.197 +Number.prototype.neg64 = function() {
4.198 + var hi = this.high32();
4.199 + var low = this;
4.200 + if ((hi === 0) && (low < 0)) { return -low; }
4.201 + hi = ~hi;
4.202 + low = ~low;
4.203 + low += (low < 0) ? (__m32+1) : 0;
4.204 + var ret = hi.next32(low);
4.205 + return ret.add64(1);
4.206 +};
4.207 +
4.208 +(function(numberPrototype) {
4.209 + function __Int64(hi32, lo32) {
4.210 + this.hi32 = hi32 | 0;
4.211 + this.lo32 = lo32 | 0;
4.212 +
4.213 + this.get32 = function(bitIndex) {
4.214 + var v0;
4.215 + var v1;
4.216 + bitIndex += 32;
4.217 + var selector = bitIndex >>> 5;
4.218 + switch (selector) {
4.219 + case 0:
4.220 + v0 = 0;
4.221 + v1 = this.lo32;
4.222 + break;
4.223 + case 1:
4.224 + v0 = this.lo32;
4.225 + v1 = this.hi32;
4.226 + break;
4.227 + case 2:
4.228 + v0 = this.hi32;
4.229 + v1 = 0;
4.230 + break
4.231 + default:
4.232 + return 0;
4.233 + }
4.234 +
4.235 + var shift = bitIndex & 31;
4.236 + if (shift === 0) {
4.237 + return v0;
4.238 + }
4.239 +
4.240 + return (v1 << (32 - shift)) | (v0 >>> shift);
4.241 + }
4.242 +
4.243 + this.get16 = function(bitIndex) {
4.244 + return this.get32(bitIndex) & 0xffff;
4.245 + }
4.246 +
4.247 + this.set16 = function(bitIndex, value) {
4.248 + bitIndex += 32;
4.249 + var shift = bitIndex & 15;
4.250 + var svalue = (value & 0xffff) << shift;
4.251 + var smask = 0xffff << shift;
4.252 + var selector = bitIndex >>> 4;
4.253 + switch (selector) {
4.254 + case 0:
4.255 + break;
4.256 + case 1:
4.257 + this.lo32 = (this.lo32 & ~(smask >>> 16))
4.258 + | (svalue >>> 16);
4.259 + break;
4.260 + case 2:
4.261 + this.lo32 = (this.lo32 & ~smask) | svalue;
4.262 + break;
4.263 + case 3:
4.264 + this.lo32 = (this.lo32 & ~(smask << 16))
4.265 + | (svalue << 16);
4.266 + this.hi32 = (this.hi32 & ~(smask >>> 16))
4.267 + | (svalue >>> 16);
4.268 + break;
4.269 + case 4:
4.270 + this.hi32 = (this.hi32 & ~smask) | svalue;
4.271 + break;
4.272 + case 5:
4.273 + this.hi32 = (this.hi32 & ~(smask << 16))
4.274 + | (svalue << 16);
4.275 + break;
4.276 + }
4.277 + }
4.278 +
4.279 + this.getDigit = function(index, shift) {
4.280 + return this.get16((index << 4) - shift);
4.281 + }
4.282 +
4.283 + this.getTwoDigits = function(index, shift) {
4.284 + return this.get32(((index - 1) << 4) - shift);
4.285 + }
4.286 +
4.287 + this.setDigit = function(index, shift, value) {
4.288 + this.set16((index << 4) - shift, value);
4.289 + }
4.290 +
4.291 + this.countSignificantDigits = function() {
4.292 + var sd;
4.293 + var remaining;
4.294 +
4.295 + if (this.hi32 === 0) {
4.296 + if (this.lo32 === 0) {
4.297 + return 0;
4.298 + }
4.299 +
4.300 + sd = 2;
4.301 + remaining = this.lo32;
4.302 + } else {
4.303 + sd = 4;
4.304 + remaining = this.hi32;
4.305 + }
4.306 +
4.307 + if (remaining < 0) {
4.308 + return sd;
4.309 + }
4.310 +
4.311 + return (remaining < 65536) ? sd - 1 : sd;
4.312 + }
4.313 +
4.314 + this.toNumber = function() {
4.315 + var lo32 = this.lo32;
4.316 + if (lo32 < 0) {
4.317 + lo32 += 0x100000000;
4.318 + }
4.319 +
4.320 + return this.hi32.next32(lo32);
4.321 + }
4.322 + }
4.323 +
4.324 + function __countLeadingZeroes16(number) {
4.325 + var nlz = 0;
4.326 +
4.327 + if (number < 256) {
4.328 + nlz += 8;
4.329 + number <<= 8;
4.330 + }
4.331 +
4.332 + if (number < 4096) {
4.333 + nlz += 4;
4.334 + number <<= 4;
4.335 + }
4.336 +
4.337 + if (number < 16384) {
4.338 + nlz += 2;
4.339 + number <<= 2;
4.340 + }
4.341 +
4.342 + return (number < 32768) ? nlz + 1 : nlz;
4.343 + }
4.344 +
4.345 + // q = u / v; r = u - q * v;
4.346 + // v != 0
4.347 + function __div64(q, r, u, v) {
4.348 + var m = u.countSignificantDigits();
4.349 + var n = v.countSignificantDigits();
4.350 +
4.351 + q.hi32 = q.lo32 = 0;
4.352 +
4.353 + if (n === 1) {
4.354 + // v has single digit
4.355 + var vd = v.getDigit(0, 0);
4.356 + var carry = 0;
4.357 + for (var i = m - 1; i >= 0; --i) {
4.358 + var ui = (carry << 16) | u.getDigit(i, 0);
4.359 + if (ui < 0) {
4.360 + ui += 0x100000000;
4.361 + }
4.362 + var qi = (ui / vd) | 0;
4.363 + q.setDigit(i, 0, qi);
4.364 + carry = ui - qi * vd;
4.365 + }
4.366 +
4.367 + r.hi32 = 0;
4.368 + r.lo32 = carry;
4.369 + return;
4.370 + }
4.371 +
4.372 + r.hi32 = u.hi32;
4.373 + r.lo32 = u.lo32;
4.374 +
4.375 + if (m < n) {
4.376 + return;
4.377 + }
4.378 +
4.379 + // Normalize
4.380 + var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
4.381 +
4.382 + var vd1 = v.getDigit(n - 1, nrm);
4.383 + var vd0 = v.getDigit(n - 2, nrm);
4.384 + for (var j = m - n; j >= 0; --j) {
4.385 + // Calculate qj estimate
4.386 + var ud21 = r.getTwoDigits(j + n, nrm);
4.387 + var ud2 = ud21 >>> 16;
4.388 + if (ud21 < 0) {
4.389 + ud21 += 0x100000000;
4.390 + }
4.391 +
4.392 + var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
4.393 + var rest = ud21 - qest * vd1;
4.394 +
4.395 + // 0 <= (qest - qj) <= 2
4.396 +
4.397 + // Refine qj estimate
4.398 + var ud0 = r.getDigit(j + n - 2, nrm);
4.399 + while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
4.400 + --qest;
4.401 + rest += vd1;
4.402 + }
4.403 +
4.404 + // 0 <= (qest - qj) <= 1
4.405 +
4.406 + // Multiply and subtract
4.407 + var carry = 0;
4.408 + for (var i = 0; i < n; ++i) {
4.409 + var vi = qest * v.getDigit(i, nrm);
4.410 + var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
4.411 + r.setDigit(i + j, nrm, ui);
4.412 + carry = (vi >>> 16) - (ui >> 16);
4.413 + }
4.414 + var uj = ud2 - carry;
4.415 +
4.416 + if (uj < 0) {
4.417 + // qest - qj = 1
4.418 +
4.419 + // Add back
4.420 + --qest;
4.421 + var carry = 0;
4.422 + for (var i = 0; i < n; ++i) {
4.423 + var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
4.424 + + carry;
4.425 + r.setDigit(i + j, nrm, ui);
4.426 + carry = ui >> 16;
4.427 + }
4.428 + uj += carry;
4.429 + }
4.430 +
4.431 + q.setDigit(j, 0, qest);
4.432 + r.setDigit(j + n, nrm, uj);
4.433 + }
4.434 + }
4.435 +
4.436 + numberPrototype.div64 = function(x) {
4.437 + var negateResult = false;
4.438 + var u, v;
4.439 +
4.440 + if ((this.high32() & 0x80000000) != 0) {
4.441 + u = this.neg64();
4.442 + negateResult = !negateResult;
4.443 + } else {
4.444 + u = this;
4.445 + }
4.446 +
4.447 + if ((x.high32() & 0x80000000) != 0) {
4.448 + v = x.neg64();
4.449 + negateResult = !negateResult;
4.450 + } else {
4.451 + v = x;
4.452 + }
4.453 +
4.454 + if ((v === 0) && (v.high32() === 0)) {
4.455 + // TODO: throw
4.456 + }
4.457 +
4.458 + if (u.high32() === 0) {
4.459 + if (v.high32() === 0) {
4.460 + var result = (u / v) | 0;
4.461 + return negateResult ? result.neg64() : result;
4.462 + }
4.463 +
4.464 + return 0;
4.465 + }
4.466 +
4.467 + var u64 = new __Int64(u.high32(), u);
4.468 + var v64 = new __Int64(v.high32(), v);
4.469 + var q64 = new __Int64(0, 0);
4.470 + var r64 = new __Int64(0, 0);
4.471 +
4.472 + __div64(q64, r64, u64, v64);
4.473 +
4.474 + var result = q64.toNumber();
4.475 + return negateResult ? result.neg64() : result;
4.476 + }
4.477 +
4.478 + numberPrototype.mod64 = function(x) {
4.479 + var negateResult = false;
4.480 + var u, v;
4.481 +
4.482 + if ((this.high32() & 0x80000000) != 0) {
4.483 + u = this.neg64();
4.484 + negateResult = !negateResult;
4.485 + } else {
4.486 + u = this;
4.487 + }
4.488 +
4.489 + if ((x.high32() & 0x80000000) != 0) {
4.490 + v = x.neg64();
4.491 + } else {
4.492 + v = x;
4.493 + }
4.494 +
4.495 + if ((v === 0) && (v.high32() === 0)) {
4.496 + // TODO: throw
4.497 + }
4.498 +
4.499 + if (u.high32() === 0) {
4.500 + var result = (v.high32() === 0) ? (u % v) : u;
4.501 + return negateResult ? result.neg64() : result;
4.502 + }
4.503 +
4.504 + var u64 = new __Int64(u.high32(), u);
4.505 + var v64 = new __Int64(v.high32(), v);
4.506 + var q64 = new __Int64(0, 0);
4.507 + var r64 = new __Int64(0, 0);
4.508 +
4.509 + __div64(q64, r64, u64, v64);
4.510 +
4.511 + var result = r64.toNumber();
4.512 + return negateResult ? result.neg64() : result;
4.513 + }
4.514 +})(Number.prototype);
5.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Feb 07 12:58:12 2013 +0100
5.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Feb 07 13:07:22 2013 +0100
5.3 @@ -521,7 +521,7 @@
5.4 emit(out, "@1 = @1.add32(@2);", smapper.getI(1), smapper.popI());
5.5 break;
5.6 case opc_ladd:
5.7 - emit(out, "@1 += @2;", smapper.getL(1), smapper.popL());
5.8 + emit(out, "@1 = @1.add64(@2);", smapper.getL(1), smapper.popL());
5.9 break;
5.10 case opc_fadd:
5.11 emit(out, "@1 += @2;", smapper.getF(1), smapper.popF());
5.12 @@ -533,7 +533,7 @@
5.13 emit(out, "@1 = @1.sub32(@2);", smapper.getI(1), smapper.popI());
5.14 break;
5.15 case opc_lsub:
5.16 - emit(out, "@1 -= @2;", smapper.getL(1), smapper.popL());
5.17 + emit(out, "@1 = @1.sub64(@2);", smapper.getL(1), smapper.popL());
5.18 break;
5.19 case opc_fsub:
5.20 emit(out, "@1 -= @2;", smapper.getF(1), smapper.popF());
5.21 @@ -545,7 +545,7 @@
5.22 emit(out, "@1 = @1.mul32(@2);", smapper.getI(1), smapper.popI());
5.23 break;
5.24 case opc_lmul:
5.25 - emit(out, "@1 *= @2;", smapper.getL(1), smapper.popL());
5.26 + emit(out, "@1 = @1.mul64(@2);", smapper.getL(1), smapper.popL());
5.27 break;
5.28 case opc_fmul:
5.29 emit(out, "@1 *= @2;", smapper.getF(1), smapper.popF());
5.30 @@ -558,7 +558,7 @@
5.31 smapper.getI(1), smapper.popI());
5.32 break;
5.33 case opc_ldiv:
5.34 - emit(out, "@1 = Math.floor(@1 / @2);",
5.35 + emit(out, "@1 = @1.div64(@2);",
5.36 smapper.getL(1), smapper.popL());
5.37 break;
5.38 case opc_fdiv:
5.39 @@ -571,7 +571,8 @@
5.40 emit(out, "@1 %= @2;", smapper.getI(1), smapper.popI());
5.41 break;
5.42 case opc_lrem:
5.43 - emit(out, "@1 %= @2;", smapper.getL(1), smapper.popL());
5.44 + emit(out, "@1 = @1.mod64(@2);",
5.45 + smapper.getL(1), smapper.popL());
5.46 break;
5.47 case opc_frem:
5.48 emit(out, "@1 %= @2;", smapper.getF(1), smapper.popF());
5.49 @@ -583,25 +584,25 @@
5.50 emit(out, "@1 &= @2;", smapper.getI(1), smapper.popI());
5.51 break;
5.52 case opc_land:
5.53 - emit(out, "@1 &= @2;", smapper.getL(1), smapper.popL());
5.54 + emit(out, "@1 = @1.and64(@2);", smapper.getL(1), smapper.popL());
5.55 break;
5.56 case opc_ior:
5.57 emit(out, "@1 |= @2;", smapper.getI(1), smapper.popI());
5.58 break;
5.59 case opc_lor:
5.60 - emit(out, "@1 |= @2;", smapper.getL(1), smapper.popL());
5.61 + emit(out, "@1 = @1.or64(@2);", smapper.getL(1), smapper.popL());
5.62 break;
5.63 case opc_ixor:
5.64 emit(out, "@1 ^= @2;", smapper.getI(1), smapper.popI());
5.65 break;
5.66 case opc_lxor:
5.67 - emit(out, "@1 ^= @2;", smapper.getL(1), smapper.popL());
5.68 + emit(out, "@1 = @1.xor64(@2);", smapper.getL(1), smapper.popL());
5.69 break;
5.70 case opc_ineg:
5.71 emit(out, "@1 = -@1;", smapper.getI(0));
5.72 break;
5.73 case opc_lneg:
5.74 - emit(out, "@1 = -@1;", smapper.getL(0));
5.75 + emit(out, "@1 = @1.neg64();", smapper.getL(0));
5.76 break;
5.77 case opc_fneg:
5.78 emit(out, "@1 = -@1;", smapper.getF(0));
5.79 @@ -613,19 +614,19 @@
5.80 emit(out, "@1 <<= @2;", smapper.getI(1), smapper.popI());
5.81 break;
5.82 case opc_lshl:
5.83 - emit(out, "@1 <<= @2;", smapper.getL(1), smapper.popI());
5.84 + emit(out, "@1 = @1.shl64(@2);", smapper.getL(1), smapper.popI());
5.85 break;
5.86 case opc_ishr:
5.87 emit(out, "@1 >>= @2;", smapper.getI(1), smapper.popI());
5.88 break;
5.89 case opc_lshr:
5.90 - emit(out, "@1 >>= @2;", smapper.getL(1), smapper.popI());
5.91 + emit(out, "@1 = @1.shr64(@2);", smapper.getL(1), smapper.popI());
5.92 break;
5.93 case opc_iushr:
5.94 emit(out, "@1 >>>= @2;", smapper.getI(1), smapper.popI());
5.95 break;
5.96 case opc_lushr:
5.97 - emit(out, "@1 >>>= @2;", smapper.getL(1), smapper.popI());
5.98 + emit(out, "@1 = @1.ushr64(@2);", smapper.getL(1), smapper.popI());
5.99 break;
5.100 case opc_iinc: {
5.101 ++i;
5.102 @@ -672,14 +673,14 @@
5.103 emit(out, "var @2 = @1;", smapper.popI(), smapper.pushD());
5.104 break;
5.105 case opc_l2i:
5.106 - emit(out, "var @2 = @1;", smapper.popL(), smapper.pushI());
5.107 + emit(out, "var @2 = @1.toInt32();", smapper.popL(), smapper.pushI());
5.108 break;
5.109 // max int check?
5.110 case opc_l2f:
5.111 - emit(out, "var @2 = @1;", smapper.popL(), smapper.pushF());
5.112 + emit(out, "var @2 = @1.toFP();", smapper.popL(), smapper.pushF());
5.113 break;
5.114 case opc_l2d:
5.115 - emit(out, "var @2 = @1;", smapper.popL(), smapper.pushD());
5.116 + emit(out, "var @2 = @1.toFP();", smapper.popL(), smapper.pushD());
5.117 break;
5.118 case opc_f2d:
5.119 emit(out, "var @2 = @1;", smapper.popF(), smapper.pushD());
5.120 @@ -692,7 +693,7 @@
5.121 smapper.popF(), smapper.pushI());
5.122 break;
5.123 case opc_f2l:
5.124 - emit(out, "var @2 = Math.floor(@1);",
5.125 + emit(out, "var @2 = Math.floor(@1).toLong();",
5.126 smapper.popF(), smapper.pushL());
5.127 break;
5.128 case opc_d2i:
5.129 @@ -700,7 +701,7 @@
5.130 smapper.popD(), smapper.pushI());
5.131 break;
5.132 case opc_d2l:
5.133 - emit(out, "var @2 = Math.floor(@1);",
5.134 + emit(out, "var @2 = Math.floor(@1).toLong();",
5.135 smapper.popD(), smapper.pushL());
5.136 break;
5.137 case opc_i2b:
5.138 @@ -770,11 +771,19 @@
5.139 i += 2;
5.140 String v = encodeConstant(indx);
5.141 int type = VarType.fromConstantType(jc.getTag(indx));
5.142 - emit(out, "var @1 = @2;", smapper.pushT(type), v);
5.143 + if (type == VarType.LONG) {
5.144 + final Long lv = new Long(v);
5.145 + final int low = (int)(lv.longValue() & 0xFFFFFFFF);
5.146 + final int hi = (int)(lv.longValue() >> 32);
5.147 + emit(out, "var @1 = 0x@3.next32(0x@2);", smapper.pushL(),
5.148 + Integer.toHexString(low), Integer.toHexString(hi));
5.149 + } else {
5.150 + emit(out, "var @1 = @2;", smapper.pushT(type), v);
5.151 + }
5.152 break;
5.153 }
5.154 case opc_lcmp:
5.155 - emit(out, "var @3 = (@2 == @1) ? 0 : ((@2 < @1) ? -1 : 1);",
5.156 + emit(out, "var @3 = @2.compare64(@1);",
5.157 smapper.popL(), smapper.popL(), smapper.pushI());
5.158 break;
5.159 case opc_fcmpl:
6.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Feb 07 12:58:12 2013 +0100
6.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/NumberTest.java Thu Feb 07 13:07:22 2013 +0100
6.3 @@ -144,6 +144,552 @@
6.4 );
6.5 }
6.6
6.7 + @Test public void longConversion() throws Exception {
6.8 + assertExec("Long from cPool",
6.9 + Numbers.class, "conversionL__J",
6.10 + Double.valueOf(Long.MAX_VALUE)
6.11 + );
6.12 + }
6.13 +
6.14 + @Test public void longNegate1() throws Exception {
6.15 + final long res = -0x00fa37d7763e0ca1l;
6.16 + assertExec("Long negate",
6.17 + Numbers.class, "negL__J_3B",
6.18 + Double.valueOf(res),
6.19 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
6.20 + );
6.21 + }
6.22 +
6.23 + @Test public void longNegate2() throws Exception {
6.24 + final long res = -0x80fa37d7763e0ca1l;
6.25 + assertExec("Long negate",
6.26 + Numbers.class, "negL__J_3B",
6.27 + Double.valueOf(res),
6.28 + new byte[] { (byte)0x80, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 }
6.29 + );
6.30 + }
6.31 +
6.32 + @Test public void longNegate3() throws Exception {
6.33 + final long res = -0xfffffffffffffeddl;
6.34 + assertExec("Long negate",
6.35 + Numbers.class, "negL__J_3B",
6.36 + Double.valueOf(res),
6.37 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
6.38 + );
6.39 + }
6.40 +
6.41 + @Test public void longAddOverflow() throws Exception {
6.42 + final long res = Long.MAX_VALUE + 1l;
6.43 + assertExec("Addition 1+MAX",
6.44 + Numbers.class, "addL__J_3B_3B",
6.45 + Double.valueOf(res),
6.46 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.47 + new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
6.48 + );
6.49 + }
6.50 +
6.51 + @Test public void longAddMaxAndMax() throws Exception {
6.52 + final long res = Long.MAX_VALUE + Long.MAX_VALUE;
6.53 + assertExec("Addition MAX+MAX",
6.54 + Numbers.class, "addL__J_3B_3B",
6.55 + Double.valueOf(res),
6.56 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.57 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
6.58 + );
6.59 + }
6.60 +
6.61 + @Test public void longSubUnderflow() throws Exception {
6.62 + final long res = Long.MIN_VALUE - 1l;
6.63 + assertExec("Subtraction MIN-1",
6.64 + Numbers.class, "subL__J_3B_3B",
6.65 + Double.valueOf(res),
6.66 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.67 + new byte[] { (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)0, (byte)1 }
6.68 + );
6.69 + }
6.70 +
6.71 + @Test public void longSubMinAndMin() throws Exception {
6.72 + final long res = Long.MIN_VALUE - Long.MIN_VALUE;
6.73 + assertExec("Subtraction MIN-MIN",
6.74 + Numbers.class, "subL__J_3B_3B",
6.75 + Double.valueOf(res),
6.76 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.77 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
6.78 + );
6.79 + }
6.80 +
6.81 + @Test public void longSubMinAndMax() throws Exception {
6.82 + final long res = Long.MIN_VALUE - Long.MAX_VALUE;
6.83 + assertExec("Subtraction MIN-MAX",
6.84 + Numbers.class, "subL__J_3B_3B",
6.85 + Double.valueOf(res),
6.86 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.87 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
6.88 + );
6.89 + }
6.90 +
6.91 + @Test public void longMultiplyMax() throws Exception {
6.92 + final long res = Long.MAX_VALUE * 2l;
6.93 + assertExec("Multiplication MAX*2",
6.94 + Numbers.class, "mulL__J_3B_3B",
6.95 + Double.valueOf(res),
6.96 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.97 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
6.98 + );
6.99 + }
6.100 +
6.101 + @Test public void longMultiplyMaxAndMax() throws Exception {
6.102 + final long res = Long.MAX_VALUE * Long.MAX_VALUE;
6.103 + assertExec("Multiplication MAX*MAX",
6.104 + Numbers.class, "mulL__J_3B_3B",
6.105 + Double.valueOf(res),
6.106 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.107 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }
6.108 + );
6.109 + }
6.110 +
6.111 + @Test public void longMultiplyMin() throws Exception {
6.112 + final long res = Long.MIN_VALUE * 2l;
6.113 + assertExec("Multiplication MIN*2",
6.114 + Numbers.class, "mulL__J_3B_3B",
6.115 + Double.valueOf(res),
6.116 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.117 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02 }
6.118 + );
6.119 + }
6.120 +
6.121 + @Test public void longMultiplyMinAndMin() throws Exception {
6.122 + final long res = Long.MIN_VALUE * Long.MIN_VALUE;
6.123 + assertExec("Multiplication MIN*2",
6.124 + Numbers.class, "mulL__J_3B_3B",
6.125 + Double.valueOf(res),
6.126 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.127 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }
6.128 + );
6.129 + }
6.130 +
6.131 + @Test public void longMultiplyPrecision() throws Exception {
6.132 + final long res = 0x00fa37d7763e0ca1l * 0xa7b3432fff00123el;
6.133 + assertExec("Multiplication",
6.134 + Numbers.class, "mulL__J_3B_3B",
6.135 + Double.valueOf(res),
6.136 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.137 + new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.138 + );
6.139 + }
6.140 +
6.141 + @Test public void longDivideSmallPositiveNumbers() throws Exception {
6.142 + final long res = 0xabcdef / 0x123;
6.143 + assertExec("Division Small Positive Numbers",
6.144 + Numbers.class, "divL__J_3B_3B",
6.145 + Double.valueOf(res),
6.146 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
6.147 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
6.148 + );
6.149 + }
6.150 +
6.151 + @Test public void longDivideSmallNegativeNumbers() throws Exception {
6.152 + final long res = -0xabcdef / -0x123;
6.153 + assertExec("Division Small Negative Numbers",
6.154 + Numbers.class, "divL__J_3B_3B",
6.155 + Double.valueOf(res),
6.156 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
6.157 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
6.158 + );
6.159 + }
6.160 +
6.161 + @Test public void longDivideSmallMixedNumbers() throws Exception {
6.162 + final long res = 0xabcdef / -0x123;
6.163 + assertExec("Division Small Mixed Numbers",
6.164 + Numbers.class, "divL__J_3B_3B",
6.165 + Double.valueOf(res),
6.166 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
6.167 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
6.168 + );
6.169 + }
6.170 +
6.171 + @Test public void longDividePositiveNumbersOneDigitDenom()
6.172 + throws Exception {
6.173 + final long res = 0xabcdef0102ffffL / 0x654;
6.174 + assertExec("Division Positive Numbers One Digit Denom",
6.175 + Numbers.class, "divL__J_3B_3B",
6.176 + Double.valueOf(res),
6.177 + new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
6.178 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
6.179 + );
6.180 + }
6.181 +
6.182 + @Test public void longDivideNegativeNumbersOneDigitDenom()
6.183 + throws Exception {
6.184 + final long res = -0xabcdef0102ffffL / -0x654;
6.185 + assertExec("Division Negative Numbers One Digit Denom",
6.186 + Numbers.class, "divL__J_3B_3B",
6.187 + Double.valueOf(res),
6.188 + new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
6.189 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
6.190 + );
6.191 + }
6.192 +
6.193 + @Test public void longDivideMixedNumbersOneDigitDenom()
6.194 + throws Exception {
6.195 + final long res = -0xabcdef0102ffffL / 0x654;
6.196 + assertExec("Division Mixed Numbers One Digit Denom",
6.197 + Numbers.class, "divL__J_3B_3B",
6.198 + Double.valueOf(res),
6.199 + new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
6.200 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
6.201 + );
6.202 + }
6.203 +
6.204 + @Test public void longDividePositiveNumbersMultiDigitDenom()
6.205 + throws Exception {
6.206 + final long res = 0x7ffefc003322aabbL / 0x89ab1000L;
6.207 + assertExec("Division Positive Numbers Multi Digit Denom",
6.208 + Numbers.class, "divL__J_3B_3B",
6.209 + Double.valueOf(res),
6.210 + new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
6.211 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
6.212 + );
6.213 + }
6.214 +
6.215 + @Test public void longDivideNegativeNumbersMultiDigitDenom()
6.216 + throws Exception {
6.217 + final long res = -0x7ffefc003322aabbL / -0x123489ab1001L;
6.218 + assertExec("Division Negative Numbers Multi Digit Denom",
6.219 + Numbers.class, "divL__J_3B_3B",
6.220 + Double.valueOf(res),
6.221 + new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
6.222 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
6.223 + );
6.224 + }
6.225 +
6.226 + @Test public void longDivideMixedNumbersMultiDigitDenom()
6.227 + throws Exception {
6.228 + final long res = 0x7ffefc003322aabbL / -0x38f49b0b7574e36L;
6.229 + assertExec("Division Mixed Numbers Multi Digit Denom",
6.230 + Numbers.class, "divL__J_3B_3B",
6.231 + Double.valueOf(res),
6.232 + new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
6.233 + new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
6.234 + );
6.235 + }
6.236 +
6.237 + @Test public void longDivideWithOverflow() throws Exception {
6.238 + final long res = 0x8000fffe0000L / 0x8000ffffL;
6.239 + assertExec("Division With Overflow",
6.240 + Numbers.class, "divL__J_3B_3B",
6.241 + Double.valueOf(res),
6.242 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
6.243 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
6.244 + );
6.245 + }
6.246 +
6.247 + @Test public void longDivideWithCorrection() throws Exception {
6.248 + final long res = 0x7fff800000000000L / 0x800000000001L;
6.249 + assertExec("Division With Correction",
6.250 + Numbers.class, "divL__J_3B_3B",
6.251 + Double.valueOf(res),
6.252 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.253 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
6.254 + );
6.255 + }
6.256 +
6.257 + @Test public void longModuloSmallPositiveNumbers() throws Exception {
6.258 + final long res = 0xabcdef % 0x123;
6.259 + assertExec("Modulo Small Positive Numbers",
6.260 + Numbers.class, "modL__J_3B_3B",
6.261 + Double.valueOf(res),
6.262 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
6.263 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x23 }
6.264 + );
6.265 + }
6.266 +
6.267 + @Test public void longModuloSmallNegativeNumbers() throws Exception {
6.268 + final long res = -0xabcdef % -0x123;
6.269 + assertExec("Modulo Small Negative Numbers",
6.270 + Numbers.class, "modL__J_3B_3B",
6.271 + Double.valueOf(res),
6.272 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x11 },
6.273 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
6.274 + );
6.275 + }
6.276 +
6.277 + @Test public void longModuloSmallMixedNumbers() throws Exception {
6.278 + final long res = 0xabcdef % -0x123;
6.279 + assertExec("Modulo Small Mixed Numbers",
6.280 + Numbers.class, "modL__J_3B_3B",
6.281 + Double.valueOf(res),
6.282 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef },
6.283 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xfe, (byte)0xdd }
6.284 + );
6.285 + }
6.286 +
6.287 + @Test public void longModuloPositiveNumbersOneDigitDenom()
6.288 + throws Exception {
6.289 + final long res = 0xabcdef0102ffffL % 0x654;
6.290 + assertExec("Modulo Positive Numbers One Digit Denom",
6.291 + Numbers.class, "modL__J_3B_3B",
6.292 + Double.valueOf(res),
6.293 + new byte[] { (byte)0x00, (byte)0xab, (byte)0xcd, (byte)0xef, (byte)0x01, (byte)0x02, (byte)0xff, (byte)0xff },
6.294 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
6.295 + );
6.296 + }
6.297 +
6.298 + @Test public void longModuloNegativeNumbersOneDigitDenom()
6.299 + throws Exception {
6.300 + final long res = -0xabcdef0102ffffL % -0x654;
6.301 + assertExec("Modulo Negative Numbers One Digit Denom",
6.302 + Numbers.class, "modL__J_3B_3B",
6.303 + Double.valueOf(res),
6.304 + new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
6.305 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xf9, (byte)0xac }
6.306 + );
6.307 + }
6.308 +
6.309 + @Test public void longModuloMixedNumbersOneDigitDenom()
6.310 + throws Exception {
6.311 + final long res = -0xabcdef0102ffffL % 0x654;
6.312 + assertExec("Modulo Mixed Numbers One Digit Denom",
6.313 + Numbers.class, "modL__J_3B_3B",
6.314 + Double.valueOf(res),
6.315 + new byte[] { (byte)0xff, (byte)0x54, (byte)0x32, (byte)0x10, (byte)0xfe, (byte)0xfd, (byte)0x00, (byte)0x01 },
6.316 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x54 }
6.317 + );
6.318 + }
6.319 +
6.320 + @Test public void longModuloPositiveNumbersMultiDigitDenom()
6.321 + throws Exception {
6.322 + final long res = 0x7ffefc003322aabbL % 0x89ab1000L;
6.323 + assertExec("Modulo Positive Numbers Multi Digit Denom",
6.324 + Numbers.class, "modL__J_3B_3B",
6.325 + Double.valueOf(res),
6.326 + new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
6.327 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x89, (byte)0xab, (byte)0x10, (byte)0x00 }
6.328 + );
6.329 + }
6.330 +
6.331 + @Test public void longModuloNegativeNumbersMultiDigitDenom()
6.332 + throws Exception {
6.333 + final long res = -0x7ffefc003322aabbL % -0x123489ab1001L;
6.334 + assertExec("Modulo Negative Numbers Multi Digit Denom",
6.335 + Numbers.class, "modL__J_3B_3B",
6.336 + Double.valueOf(res),
6.337 + new byte[] { (byte)0x80, (byte)0x01, (byte)0x03, (byte)0xff, (byte)0xcc, (byte)0xdd, (byte)0x55, (byte)0x45 },
6.338 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xed, (byte)0xcb, (byte)0x76, (byte)0x54, (byte)0xef, (byte)0xff }
6.339 + );
6.340 + }
6.341 +
6.342 + @Test public void longModuloMixedNumbersMultiDigitDenom()
6.343 + throws Exception {
6.344 + final long res = 0x7ffefc003322aabbL % -0x38f49b0b7574e36L;
6.345 + assertExec("Modulo Mixed Numbers Multi Digit Denom",
6.346 + Numbers.class, "modL__J_3B_3B",
6.347 + Double.valueOf(res),
6.348 + new byte[] { (byte)0x7f, (byte)0xfe, (byte)0xfc, (byte)0x00, (byte)0x33, (byte)0x22, (byte)0xaa, (byte)0xbb },
6.349 + new byte[] { (byte)0xfc, (byte)0x70, (byte)0xb6, (byte)0x4f, (byte)0x48, (byte)0xa8, (byte)0xb1, (byte)0xca }
6.350 + );
6.351 + }
6.352 +
6.353 + @Test public void longModuloWithOverflow() throws Exception {
6.354 + final long res = 0x8000fffe0000L % 0x8000ffffL;
6.355 + assertExec("Modulo With Overflow",
6.356 + Numbers.class, "modL__J_3B_3B",
6.357 + Double.valueOf(res),
6.358 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 },
6.359 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0xff, (byte)0xff }
6.360 + );
6.361 + }
6.362 +
6.363 + @Test public void longModuloWithCorrection() throws Exception {
6.364 + final long res = 0x7fff800000000000L % 0x800000000001L;
6.365 + assertExec("Modulo With Correction",
6.366 + Numbers.class, "modL__J_3B_3B",
6.367 + Double.valueOf(res),
6.368 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.369 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 }
6.370 + );
6.371 + }
6.372 +
6.373 + @Test public void longShiftL1() throws Exception {
6.374 + final long res = 0x00fa37d7763e0ca1l << 5;
6.375 + assertExec("Long << 5",
6.376 + Numbers.class, "shlL__J_3BI",
6.377 + Double.valueOf(res),
6.378 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.379 + 5);
6.380 + }
6.381 +
6.382 + @Test public void longShiftL2() throws Exception {
6.383 + final long res = 0x00fa37d7763e0ca1l << 32;
6.384 + assertExec("Long << 32",
6.385 + Numbers.class, "shlL__J_3BI",
6.386 + Double.valueOf(res),
6.387 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.388 + 32);
6.389 + }
6.390 +
6.391 + @Test public void longShiftL3() throws Exception {
6.392 + final long res = 0x00fa37d7763e0ca1l << 45;
6.393 + assertExec("Long << 45",
6.394 + Numbers.class, "shlL__J_3BI",
6.395 + Double.valueOf(res),
6.396 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.397 + 45);
6.398 + }
6.399 +
6.400 + @Test public void longShiftR1() throws Exception {
6.401 + final long res = 0x00fa37d7763e0ca1l >> 5;
6.402 + assertExec("Long >> 5",
6.403 + Numbers.class, "shrL__J_3BI",
6.404 + Double.valueOf(res),
6.405 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.406 + 5);
6.407 + }
6.408 +
6.409 + @Test public void longShiftR2() throws Exception {
6.410 + final long res = 0x00fa37d7763e0ca1l >> 32;
6.411 + assertExec("Long >> 32",
6.412 + Numbers.class, "shrL__J_3BI",
6.413 + Double.valueOf(res),
6.414 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.415 + 32);
6.416 + }
6.417 +
6.418 + @Test public void longShiftR3() throws Exception {
6.419 + final long res = 0x00fa37d7763e0ca1l >> 45;
6.420 + assertExec("Long >> 45",
6.421 + Numbers.class, "shrL__J_3BI",
6.422 + Double.valueOf(res),
6.423 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.424 + 45);
6.425 + }
6.426 +
6.427 + @Test public void longUShiftR1() throws Exception {
6.428 + final long res = 0x00fa37d7763e0ca1l >>> 5;
6.429 + assertExec("Long >>> 5",
6.430 + Numbers.class, "ushrL__J_3BI",
6.431 + Double.valueOf(res),
6.432 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.433 + 5);
6.434 + }
6.435 +
6.436 + @Test public void longUShiftR2() throws Exception {
6.437 + final long res = 0x00fa37d7763e0ca1l >>> 45;
6.438 + assertExec("Long >>> 45",
6.439 + Numbers.class, "ushrL__J_3BI",
6.440 + Double.valueOf(res),
6.441 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.442 + 45);
6.443 + }
6.444 +
6.445 + @Test public void longUShiftR3() throws Exception {
6.446 + final long res = 0xf0fa37d7763e0ca1l >>> 5;
6.447 + assertExec("Long >>> 5",
6.448 + Numbers.class, "ushrL__J_3BI",
6.449 + Double.valueOf(res),
6.450 + new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.451 + 5);
6.452 + }
6.453 +
6.454 + @Test public void longUShiftR4() throws Exception {
6.455 + final long res = 0xf0fa37d7763e0ca1l >>> 45;
6.456 + assertExec("Long >>> 45",
6.457 + Numbers.class, "ushrL__J_3BI",
6.458 + Double.valueOf(res),
6.459 + new byte[] { (byte)0xf0, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.460 + 45);
6.461 + }
6.462 +
6.463 + @Test public void longAnd() throws Exception {
6.464 + final long res = 0x00fa37d7763e0ca1l & 0xa7b3432fff00123el;
6.465 + assertExec("LOng binary AND",
6.466 + Numbers.class, "andL__J_3B_3B",
6.467 + Double.valueOf(res),
6.468 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.469 + new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.470 + );
6.471 + }
6.472 +
6.473 + @Test public void longOr() throws Exception {
6.474 + final long res = 0x00fa37d7763e0ca1l | 0xa7b3432fff00123el;
6.475 + assertExec("Long binary OR",
6.476 + Numbers.class, "orL__J_3B_3B",
6.477 + Double.valueOf(res),
6.478 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.479 + new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.480 + );
6.481 + }
6.482 +
6.483 + @Test public void longXor1() throws Exception {
6.484 + final long res = 0x00fa37d7763e0ca1l ^ 0xa7b3432fff00123el;
6.485 + assertExec("Long binary XOR",
6.486 + Numbers.class, "xorL__J_3B_3B",
6.487 + Double.valueOf(res),
6.488 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.489 + new byte[] { (byte)0xa7, (byte)0xb3, (byte)0x43, (byte)0x2f, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.490 + );
6.491 + }
6.492 +
6.493 + @Test public void longXor2() throws Exception {
6.494 + final long res = 0x00fa37d7763e0ca1l ^ 0x00000000ff00123el;
6.495 + assertExec("Long binary XOR",
6.496 + Numbers.class, "xorL__J_3B_3B",
6.497 + Double.valueOf(res),
6.498 + new byte[] { (byte)0x00, (byte)0xfa, (byte)0x37, (byte)0xd7, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.499 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.500 + );
6.501 + }
6.502 +
6.503 + @Test public void longXor3() throws Exception {
6.504 + final long res = 0x00000000763e0ca1l ^ 0x00000000ff00123el;
6.505 + assertExec("Long binary XOR",
6.506 + Numbers.class, "xorL__J_3B_3B",
6.507 + Double.valueOf(res),
6.508 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x76, (byte)0x3e, (byte)0x0c, (byte)0xa1 },
6.509 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0x00, (byte)0x12, (byte)0x3e }
6.510 + );
6.511 + }
6.512 +
6.513 + @Test public void longCompareSameNumbers() throws Exception {
6.514 + assertExec("Long compare same numbers",
6.515 + Numbers.class, "compareL__I_3B_3BI",
6.516 + 0.0,
6.517 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.518 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.519 + 0
6.520 + );
6.521 + }
6.522 +
6.523 + @Test public void longComparePositiveNumbers() throws Exception {
6.524 + assertExec("Long compare positive numbers",
6.525 + Numbers.class, "compareL__I_3B_3BI",
6.526 + -1.0,
6.527 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x20, (byte)0x00, (byte)0x00 },
6.528 + new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00 },
6.529 + 0
6.530 + );
6.531 + }
6.532 +
6.533 + @Test public void longCompareNegativeNumbers() throws Exception {
6.534 + assertExec("Long compare negative numbers",
6.535 + Numbers.class, "compareL__I_3B_3BI",
6.536 + 1.0,
6.537 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.538 + new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.539 + 0
6.540 + );
6.541 + }
6.542 +
6.543 + @Test public void longCompareMixedNumbers() throws Exception {
6.544 + assertExec("Long compare mixed numbers",
6.545 + Numbers.class, "compareL__I_3B_3BI",
6.546 + -1.0,
6.547 + new byte[] { (byte)0x80, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 },
6.548 + new byte[] { (byte)0x7f, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff },
6.549 + 0
6.550 + );
6.551 + }
6.552 +
6.553 private static CharSequence codeSeq;
6.554 private static Invocable code;
6.555
6.556 @@ -157,31 +703,20 @@
6.557 }
6.558
6.559 private static void assertExec(
6.560 - String msg, Class<?> clazz, String method, Object expRes, Object... args) throws Exception {
6.561 -
6.562 - Object ret = null;
6.563 - try {
6.564 - ret = code.invokeFunction("bck2brwsr");
6.565 - ret = code.invokeMethod(ret, "loadClass", clazz.getName());
6.566 - ret = code.invokeMethod(ret, method, args);
6.567 - } catch (ScriptException ex) {
6.568 - fail("Execution failed in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
6.569 - } catch (NoSuchMethodException ex) {
6.570 - fail("Cannot find method in\n" + StaticMethodTest.dumpJS(codeSeq), ex);
6.571 - }
6.572 - if (ret == null && expRes == null) {
6.573 - return;
6.574 - }
6.575 - if (expRes.equals(ret)) {
6.576 + String msg, Class<?> clazz, String method, Object expRes, Object... args) throws Exception
6.577 + {
6.578 + Object ret = TestUtils.execCode(code, codeSeq, msg, clazz, method, expRes, args);
6.579 + if (ret == null) {
6.580 return;
6.581 }
6.582 if (expRes instanceof Double && ret instanceof Double) {
6.583 double expD = ((Double)expRes).doubleValue();
6.584 double retD = ((Double)ret).doubleValue();
6.585 - assertEquals(retD, expD, 0.000004, msg + " was " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq));
6.586 + assertEquals(retD, expD, 0.000004, msg + " "
6.587 + + StaticMethodTest.dumpJS(codeSeq));
6.588 return;
6.589 }
6.590 - assertEquals(ret, expRes, msg + "was: " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq));
6.591 + assertEquals(ret, expRes, msg + " " + StaticMethodTest.dumpJS(codeSeq));
6.592 }
6.593
6.594 }
7.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Feb 07 12:58:12 2013 +0100
7.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Numbers.java Thu Feb 07 13:07:22 2013 +0100
7.3 @@ -67,4 +67,136 @@
7.4 static String floatToString() {
7.5 return new Float(7.0).toString().toString();
7.6 }
7.7 +
7.8 + public static long conversionL() {
7.9 + return Long.MAX_VALUE;
7.10 + }
7.11 +
7.12 + public static long negL(byte[] arrValue) throws IOException {
7.13 + ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
7.14 + DataInputStream disValue = new DataInputStream(isValue);
7.15 + return (-disValue.readLong());
7.16 + }
7.17 +
7.18 + public static long addL(byte[] arrX, byte[] arrY) throws IOException {
7.19 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.20 + DataInputStream disX = new DataInputStream(isX);
7.21 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.22 + DataInputStream disY = new DataInputStream(isY);
7.23 + return (disX.readLong() + disY.readLong());
7.24 + }
7.25 +
7.26 + public static long subL(byte[] arrX, byte[] arrY) throws IOException {
7.27 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.28 + DataInputStream disX = new DataInputStream(isX);
7.29 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.30 + DataInputStream disY = new DataInputStream(isY);
7.31 + return (disX.readLong() - disY.readLong());
7.32 + }
7.33 +
7.34 + public static long mulL(byte[] arrX, byte[] arrY) throws IOException {
7.35 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.36 + DataInputStream disX = new DataInputStream(isX);
7.37 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.38 + DataInputStream disY = new DataInputStream(isY);
7.39 + return (disX.readLong() * disY.readLong());
7.40 + }
7.41 +
7.42 + public static long divL(byte[] arrX, byte[] arrY) throws IOException {
7.43 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.44 + DataInputStream disX = new DataInputStream(isX);
7.45 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.46 + DataInputStream disY = new DataInputStream(isY);
7.47 + return (disX.readLong() / disY.readLong());
7.48 + }
7.49 +
7.50 + public static long modL(byte[] arrX, byte[] arrY) throws IOException {
7.51 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.52 + DataInputStream disX = new DataInputStream(isX);
7.53 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.54 + DataInputStream disY = new DataInputStream(isY);
7.55 + return (disX.readLong() % disY.readLong());
7.56 + }
7.57 +
7.58 + public static long shlL(byte[] arrValue, int nBits) throws IOException {
7.59 + ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
7.60 + DataInputStream disValue = new DataInputStream(isValue);
7.61 + return (disValue.readLong() << nBits);
7.62 + }
7.63 +
7.64 + public static long shrL(byte[] arrValue, int nBits) throws IOException {
7.65 + ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
7.66 + DataInputStream disValue = new DataInputStream(isValue);
7.67 + return (disValue.readLong() >> nBits);
7.68 + }
7.69 +
7.70 + public static long ushrL(byte[] arrValue, int nBits) throws IOException {
7.71 + ByteArrayInputStream isValue = new ByteArrayInputStream(arrValue);
7.72 + DataInputStream disValue = new DataInputStream(isValue);
7.73 + return (disValue.readLong() >>> nBits);
7.74 + }
7.75 +
7.76 + public static long andL(byte[] arrX, byte[] arrY) throws IOException {
7.77 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.78 + DataInputStream disX = new DataInputStream(isX);
7.79 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.80 + DataInputStream disY = new DataInputStream(isY);
7.81 + return (disX.readLong() & disY.readLong());
7.82 + }
7.83 +
7.84 + public static long orL(byte[] arrX, byte[] arrY) throws IOException {
7.85 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.86 + DataInputStream disX = new DataInputStream(isX);
7.87 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.88 + DataInputStream disY = new DataInputStream(isY);
7.89 + return (disX.readLong() | disY.readLong());
7.90 + }
7.91 +
7.92 + public static long xorL(byte[] arrX, byte[] arrY) throws IOException {
7.93 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.94 + DataInputStream disX = new DataInputStream(isX);
7.95 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.96 + DataInputStream disY = new DataInputStream(isY);
7.97 + return (disX.readLong() ^ disY.readLong());
7.98 + }
7.99 +
7.100 + public static int compareL(byte[] arrX, byte[] arrY,
7.101 + int zero) throws IOException {
7.102 + ByteArrayInputStream isX = new ByteArrayInputStream(arrX);
7.103 + DataInputStream disX = new DataInputStream(isX);
7.104 + ByteArrayInputStream isY = new ByteArrayInputStream(arrY);
7.105 + DataInputStream disY = new DataInputStream(isY);
7.106 + final long x = disX.readLong();
7.107 + final long y = disY.readLong();
7.108 +
7.109 + final int xyResult = compareL(x, y, zero);
7.110 + final int yxResult = compareL(y, x, zero);
7.111 +
7.112 + return ((xyResult + yxResult) == 0) ? xyResult : -2;
7.113 + }
7.114 +
7.115 + private static int compareL(long x, long y, int zero) {
7.116 + int result = -2;
7.117 + int trueCount = 0;
7.118 +
7.119 + x += zero;
7.120 + if (x == y) {
7.121 + result = 0;
7.122 + ++trueCount;
7.123 + }
7.124 +
7.125 + x += zero;
7.126 + if (x < y) {
7.127 + result = -1;
7.128 + ++trueCount;
7.129 + }
7.130 +
7.131 + x += zero;
7.132 + if (x > y) {
7.133 + result = 1;
7.134 + ++trueCount;
7.135 + }
7.136 +
7.137 + return (trueCount == 1) ? result : -2;
7.138 + }
7.139 }
8.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Thu Feb 07 12:58:12 2013 +0100
8.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Thu Feb 07 13:07:22 2013 +0100
8.3 @@ -353,17 +353,8 @@
8.4 String msg, Class clazz, String method,
8.5 Object expRes, Object... args
8.6 ) throws Exception {
8.7 - Object ret = null;
8.8 - try {
8.9 - ret = toRun.invokeFunction("bck2brwsr");
8.10 - ret = toRun.invokeMethod(ret, "loadClass", clazz.getName());
8.11 - ret = toRun.invokeMethod(ret, method, args);
8.12 - } catch (ScriptException ex) {
8.13 - fail("Execution failed in\n" + dumpJS(theCode), ex);
8.14 - } catch (NoSuchMethodException ex) {
8.15 - fail("Cannot find method in\n" + dumpJS(theCode), ex);
8.16 - }
8.17 - if (ret == null && expRes == null) {
8.18 + Object ret = TestUtils.execCode(toRun, theCode, msg, clazz, method, expRes, args);
8.19 + if (ret == null) {
8.20 return;
8.21 }
8.22 if (expRes != null && expRes.equals(ret)) {
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/TestUtils.java Thu Feb 07 13:07:22 2013 +0100
9.3 @@ -0,0 +1,60 @@
9.4 +/**
9.5 + * Back 2 Browser Bytecode Translator
9.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.7 + *
9.8 + * This program is free software: you can redistribute it and/or modify
9.9 + * it under the terms of the GNU General Public License as published by
9.10 + * the Free Software Foundation, version 2 of the License.
9.11 + *
9.12 + * This program is distributed in the hope that it will be useful,
9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.15 + * GNU General Public License for more details.
9.16 + *
9.17 + * You should have received a copy of the GNU General Public License
9.18 + * along with this program. Look for COPYING file in the top folder.
9.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
9.20 + */
9.21 +package org.apidesign.vm4brwsr;
9.22 +
9.23 +import javax.script.Invocable;
9.24 +import javax.script.ScriptException;
9.25 +import static org.testng.Assert.*;
9.26 +
9.27 +class TestUtils {
9.28 +
9.29 + static Object execCode(Invocable code, CharSequence codeSeq,
9.30 + String msg, Class<?> clazz, String method, Object expRes, Object... args)
9.31 + throws Exception
9.32 + {
9.33 + Object ret = null;
9.34 + try {
9.35 + ret = code.invokeFunction("bck2brwsr");
9.36 + ret = code.invokeMethod(ret, "loadClass", clazz.getName());
9.37 + ret = code.invokeMethod(ret, method, args);
9.38 + } catch (ScriptException ex) {
9.39 + fail("Execution failed in " + StaticMethodTest.dumpJS(codeSeq), ex);
9.40 + } catch (NoSuchMethodException ex) {
9.41 + fail("Cannot find method in " + StaticMethodTest.dumpJS(codeSeq), ex);
9.42 + }
9.43 + if (ret == null && expRes == null) {
9.44 + return null;
9.45 + }
9.46 + if (expRes.equals(ret)) {
9.47 + return null;
9.48 + }
9.49 + if (expRes instanceof Number) {
9.50 + // in case of Long it is necessary convert it to number
9.51 + // since the Long is represented by two numbers in JavaScript
9.52 + try {
9.53 + ret = code.invokeMethod(ret, "toFP");
9.54 + ret = code.invokeFunction("Number", ret);
9.55 + } catch (ScriptException ex) {
9.56 + fail("Conversion to number failed in " + StaticMethodTest.dumpJS(codeSeq), ex);
9.57 + } catch (NoSuchMethodException ex) {
9.58 + fail("Cannot find global Number(x) function in " + StaticMethodTest.dumpJS(codeSeq), ex);
9.59 + }
9.60 + }
9.61 + return ret;
9.62 + }
9.63 +}
10.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Thu Feb 07 12:58:12 2013 +0100
10.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Thu Feb 07 13:07:22 2013 +0100
10.3 @@ -51,7 +51,7 @@
10.4
10.5 ScriptEngine[] arr = { null };
10.6 code = StaticMethodTest.compileClass(sb, arr,
10.7 - "org/apidesign/vm4brwsr/VM"
10.8 + new String[]{"org/apidesign/vm4brwsr/VM", "org/apidesign/vm4brwsr/StaticMethod"}
10.9 );
10.10 arr[0].getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
10.11 codeSeq = sb;
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/LongArithmeticTest.java Thu Feb 07 13:07:22 2013 +0100
11.3 @@ -0,0 +1,104 @@
11.4 +/**
11.5 + * Back 2 Browser Bytecode Translator
11.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
11.7 + *
11.8 + * This program is free software: you can redistribute it and/or modify
11.9 + * it under the terms of the GNU General Public License as published by
11.10 + * the Free Software Foundation, version 2 of the License.
11.11 + *
11.12 + * This program is distributed in the hope that it will be useful,
11.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.15 + * GNU General Public License for more details.
11.16 + *
11.17 + * You should have received a copy of the GNU General Public License
11.18 + * along with this program. Look for COPYING file in the top folder.
11.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
11.20 + */
11.21 +package org.apidesign.bck2brwsr.tck;
11.22 +
11.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
11.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
11.25 +import org.testng.annotations.Factory;
11.26 +
11.27 +/**
11.28 + *
11.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
11.30 + */
11.31 +public class LongArithmeticTest {
11.32 +
11.33 + private static long add(long x, long y) {
11.34 + return (x + y);
11.35 + }
11.36 +
11.37 + private static long sub(long x, long y) {
11.38 + return (x - y);
11.39 + }
11.40 +
11.41 + private static long mul(long x, long y) {
11.42 + return (x * y);
11.43 + }
11.44 +
11.45 + private static long div(long x, long y) {
11.46 + return (x / y);
11.47 + }
11.48 +
11.49 + private static long mod(long x, long y) {
11.50 + return (x % y);
11.51 + }
11.52 +
11.53 + @Compare public long conversion() {
11.54 + return Long.MAX_VALUE;
11.55 + }
11.56 +
11.57 + /*
11.58 + @Compare public long addOverflow() {
11.59 + return add(Long.MAX_VALUE, 1l);
11.60 + }
11.61 +
11.62 + @Compare public long subUnderflow() {
11.63 + return sub(Long.MIN_VALUE, 1l);
11.64 + }
11.65 +
11.66 + @Compare public long addMaxLongAndMaxLong() {
11.67 + return add(Long.MAX_VALUE, Long.MAX_VALUE);
11.68 + }
11.69 +
11.70 + @Compare public long subMinLongAndMinLong() {
11.71 + return sub(Long.MIN_VALUE, Long.MIN_VALUE);
11.72 + }
11.73 +
11.74 + @Compare public long multiplyMaxLong() {
11.75 + return mul(Long.MAX_VALUE, 2l);
11.76 + }
11.77 +
11.78 + @Compare public long multiplyMaxLongAndMaxLong() {
11.79 + return mul(Long.MAX_VALUE, Long.MAX_VALUE);
11.80 + }
11.81 +
11.82 + @Compare public long multiplyMinLong() {
11.83 + return mul(Long.MIN_VALUE, 2l);
11.84 + }
11.85 +
11.86 + @Compare public long multiplyMinLongAndMinLong() {
11.87 + return mul(Long.MIN_VALUE, Long.MIN_VALUE);
11.88 + }
11.89 +
11.90 + @Compare public long multiplyPrecision() {
11.91 + return mul(17638l, 1103l);
11.92 + }
11.93 +
11.94 + @Compare public long division() {
11.95 + return div(1l, 2l);
11.96 + }
11.97 +
11.98 + @Compare public long divisionReminder() {
11.99 + return mod(1l, 2l);
11.100 + }
11.101 + */
11.102 +
11.103 + @Factory
11.104 + public static Object[] create() {
11.105 + return VMTest.create(LongArithmeticTest.class);
11.106 + }
11.107 +}