rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,544 @@
1.4 +// empty line needed here
1.5 +Number.prototype.add32 = function(x) { return (this + x) | 0; };
1.6 +Number.prototype.sub32 = function(x) { return (this - x) | 0; };
1.7 +Number.prototype.mul32 = function(x) {
1.8 + return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
1.9 +};
1.10 +Number.prototype.neg32 = function() { return (-this) | 0; };
1.11 +
1.12 +Number.prototype.toInt8 = function() { return (this << 24) >> 24; };
1.13 +Number.prototype.toInt16 = function() { return (this << 16) >> 16; };
1.14 +
1.15 +var __m32 = 0xFFFFFFFF;
1.16 +
1.17 +Number.prototype.next32 = function(low) {
1.18 + if (this === 0) {
1.19 + return low;
1.20 + }
1.21 + var l = new Number(low);
1.22 + l.hi = this | 0;
1.23 + return l;
1.24 +};
1.25 +
1.26 +Number.prototype.high32 = function() {
1.27 + return this.hi ? this.hi : (Math.floor(this / (__m32+1))) | 0;
1.28 +};
1.29 +Number.prototype.toInt32 = function() { return this | 0; };
1.30 +Number.prototype.toFP = function() {
1.31 + return this.hi ? this.hi * (__m32+1) + this : this;
1.32 +};
1.33 +Number.prototype.toLong = function() {
1.34 + var hi = (this > __m32) ? (Math.floor(this / (__m32+1))) | 0 : 0;
1.35 + return hi.next32(Math.floor(this % (__m32+1)));
1.36 +};
1.37 +
1.38 +Number.prototype.toExactString = function() {
1.39 + if (this.hi) {
1.40 + // check for Long.MIN_VALUE
1.41 + if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
1.42 + return '-9223372036854775808';
1.43 + }
1.44 + var res = 0;
1.45 + var a = [ 6,9,2,7,6,9,4,9,2,4 ];
1.46 + var s = '';
1.47 + var digit;
1.48 + var neg = this.hi < 0;
1.49 + if (neg) {
1.50 + var x = this.neg64();
1.51 + var hi = x.hi;
1.52 + var low = x;
1.53 + } else {
1.54 + var hi = this.hi;
1.55 + var low = this;
1.56 + }
1.57 + for (var i = 0; i < a.length; i++) {
1.58 + res += hi * a[i];
1.59 + var low_digit = low % 10;
1.60 + digit = (res % 10) + low_digit;
1.61 +
1.62 + low = Math.floor(low / 10);
1.63 + res = Math.floor(res / 10);
1.64 +
1.65 + if (digit >= 10) {
1.66 + digit -= 10;
1.67 + res++;
1.68 + }
1.69 + s = String(digit).concat(s);
1.70 + }
1.71 + s = String(res).concat(s).replace(/^0+/, '');
1.72 + return (neg ? '-' : '').concat(s);
1.73 + }
1.74 + return String(this);
1.75 +};
1.76 +
1.77 +Number.prototype.add64 = function(x) {
1.78 + var low = this + x;
1.79 + carry = 0;
1.80 + if (low > __m32) {
1.81 + carry = 1;
1.82 + low -= (__m32+1);
1.83 + }
1.84 + var hi = (this.high32() + x.high32() + carry) | 0;
1.85 + return hi.next32(low);
1.86 +};
1.87 +
1.88 +Number.prototype.sub64 = function(x) {
1.89 + var low = this - x;
1.90 + carry = 0;
1.91 + if (low < 0) {
1.92 + carry = 1;
1.93 + low += (__m32+1);
1.94 + }
1.95 + var hi = (this.high32() - x.high32() - carry) | 0;
1.96 + return hi.next32(low);
1.97 +};
1.98 +
1.99 +Number.prototype.mul64 = function(x) {
1.100 + var low = this.mul32(x);
1.101 + low += (low < 0) ? (__m32+1) : 0;
1.102 + // first count upper 32 bits of (this.low * x.low)
1.103 + var hi_hi = 0;
1.104 + var hi_low = 0;
1.105 + var m = 1;
1.106 + for (var i = 0; i < 32; i++) {
1.107 + if (x & m) {
1.108 + hi_hi += this >>> 16;
1.109 + hi_low += this & 0xFFFF
1.110 + }
1.111 + hi_low >>= 1;
1.112 + hi_low += (hi_hi & 1) ? 0x8000 : 0;
1.113 + hi_hi >>= 1;
1.114 + m <<= 1;
1.115 + }
1.116 + var hi = (hi_hi << 16) + hi_low;
1.117 +
1.118 + var m1 = this.high32().mul32(x);
1.119 + var m2 = this.mul32(x.high32());
1.120 + hi = hi.add32(m1).add32(m2);
1.121 +
1.122 + return hi.next32(low);
1.123 +};
1.124 +
1.125 +Number.prototype.and64 = function(x) {
1.126 + var low = this & x;
1.127 + low += (low < 0) ? (__m32+1) : 0;
1.128 + if (this.hi && x.hi) {
1.129 + var hi = this.hi & x.hi;
1.130 + return hi.next32(low);
1.131 + };
1.132 + return low;
1.133 +};
1.134 +
1.135 +Number.prototype.or64 = function(x) {
1.136 + var low = this | x;
1.137 + low += (low < 0) ? (__m32+1) : 0;
1.138 + if (this.hi || x.hi) {
1.139 + var hi = this.hi | x.hi;
1.140 + return hi.next32(low);
1.141 + };
1.142 + return low;
1.143 +};
1.144 +
1.145 +Number.prototype.xor64 = function(x) {
1.146 + var low = this ^ x;
1.147 + low += (low < 0) ? (__m32+1) : 0;
1.148 + if (this.hi || x.hi) {
1.149 + var hi = this.hi ^ x.hi;
1.150 + return hi.next32(low);
1.151 + };
1.152 + return low;
1.153 +};
1.154 +
1.155 +Number.prototype.shl64 = function(x) {
1.156 + if (x >= 32) {
1.157 + var hi = this << (x - 32);
1.158 + return hi.next32(0);
1.159 + } else {
1.160 + var hi = this.high32() << x;
1.161 + var low_reminder = this >> (32 - x);
1.162 + hi |= low_reminder;
1.163 + var low = this << x;
1.164 + low += (low < 0) ? (__m32+1) : 0;
1.165 + return hi.next32(low);
1.166 + }
1.167 +};
1.168 +
1.169 +Number.prototype.shr64 = function(x) {
1.170 + if (x >= 32) {
1.171 + var low = this.high32() >> (x - 32);
1.172 + low += (low < 0) ? (__m32+1) : 0;
1.173 + return low;
1.174 + } else {
1.175 + var low = this >> x;
1.176 + var hi_reminder = this.high32() << (32 - x);
1.177 + low |= hi_reminder;
1.178 + low += (low < 0) ? (__m32+1) : 0;
1.179 + var hi = this.high32() >> x;
1.180 + return hi.next32(low);
1.181 + }
1.182 +};
1.183 +
1.184 +Number.prototype.ushr64 = function(x) {
1.185 + if (x >= 32) {
1.186 + var low = this.high32() >>> (x - 32);
1.187 + low += (low < 0) ? (__m32+1) : 0;
1.188 + return low;
1.189 + } else {
1.190 + var low = this >>> x;
1.191 + var hi_reminder = this.high32() << (32 - x);
1.192 + low |= hi_reminder;
1.193 + low += (low < 0) ? (__m32+1) : 0;
1.194 + var hi = this.high32() >>> x;
1.195 + return hi.next32(low);
1.196 + }
1.197 +};
1.198 +
1.199 +Number.prototype.compare64 = function(x) {
1.200 + if (this.high32() === x.high32()) {
1.201 + return (this < x) ? -1 : ((this > x) ? 1 : 0);
1.202 + }
1.203 + return (this.high32() < x.high32()) ? -1 : 1;
1.204 +};
1.205 +
1.206 +Number.prototype.neg64 = function() {
1.207 + var hi = this.high32();
1.208 + var low = this;
1.209 + if ((hi === 0) && (low < 0)) { return -low; }
1.210 + hi = ~hi;
1.211 + low = ~low;
1.212 + low += (low < 0) ? (__m32+1) : 0;
1.213 + var ret = hi.next32(low);
1.214 + return ret.add64(1);
1.215 +};
1.216 +
1.217 +(function(numberPrototype) {
1.218 + function __handleDivByZero() {
1.219 + var exception = new vm.java_lang_ArithmeticException;
1.220 + vm.java_lang_ArithmeticException(false).constructor
1.221 + .cons__VLjava_lang_String_2.call(exception, "/ by zero");
1.222 +
1.223 + throw exception;
1.224 + }
1.225 +
1.226 + function __Int64(hi32, lo32) {
1.227 + this.hi32 = hi32 | 0;
1.228 + this.lo32 = lo32 | 0;
1.229 +
1.230 + this.get32 = function(bitIndex) {
1.231 + var v0;
1.232 + var v1;
1.233 + bitIndex += 32;
1.234 + var selector = bitIndex >>> 5;
1.235 + switch (selector) {
1.236 + case 0:
1.237 + v0 = 0;
1.238 + v1 = this.lo32;
1.239 + break;
1.240 + case 1:
1.241 + v0 = this.lo32;
1.242 + v1 = this.hi32;
1.243 + break;
1.244 + case 2:
1.245 + v0 = this.hi32;
1.246 + v1 = 0;
1.247 + break
1.248 + default:
1.249 + return 0;
1.250 + }
1.251 +
1.252 + var shift = bitIndex & 31;
1.253 + if (shift === 0) {
1.254 + return v0;
1.255 + }
1.256 +
1.257 + return (v1 << (32 - shift)) | (v0 >>> shift);
1.258 + }
1.259 +
1.260 + this.get16 = function(bitIndex) {
1.261 + return this.get32(bitIndex) & 0xffff;
1.262 + }
1.263 +
1.264 + this.set16 = function(bitIndex, value) {
1.265 + bitIndex += 32;
1.266 + var shift = bitIndex & 15;
1.267 + var svalue = (value & 0xffff) << shift;
1.268 + var smask = 0xffff << shift;
1.269 + var selector = bitIndex >>> 4;
1.270 + switch (selector) {
1.271 + case 0:
1.272 + break;
1.273 + case 1:
1.274 + this.lo32 = (this.lo32 & ~(smask >>> 16))
1.275 + | (svalue >>> 16);
1.276 + break;
1.277 + case 2:
1.278 + this.lo32 = (this.lo32 & ~smask) | svalue;
1.279 + break;
1.280 + case 3:
1.281 + this.lo32 = (this.lo32 & ~(smask << 16))
1.282 + | (svalue << 16);
1.283 + this.hi32 = (this.hi32 & ~(smask >>> 16))
1.284 + | (svalue >>> 16);
1.285 + break;
1.286 + case 4:
1.287 + this.hi32 = (this.hi32 & ~smask) | svalue;
1.288 + break;
1.289 + case 5:
1.290 + this.hi32 = (this.hi32 & ~(smask << 16))
1.291 + | (svalue << 16);
1.292 + break;
1.293 + }
1.294 + }
1.295 +
1.296 + this.getDigit = function(index, shift) {
1.297 + return this.get16((index << 4) - shift);
1.298 + }
1.299 +
1.300 + this.getTwoDigits = function(index, shift) {
1.301 + return this.get32(((index - 1) << 4) - shift);
1.302 + }
1.303 +
1.304 + this.setDigit = function(index, shift, value) {
1.305 + this.set16((index << 4) - shift, value);
1.306 + }
1.307 +
1.308 + this.countSignificantDigits = function() {
1.309 + var sd;
1.310 + var remaining;
1.311 +
1.312 + if (this.hi32 === 0) {
1.313 + if (this.lo32 === 0) {
1.314 + return 0;
1.315 + }
1.316 +
1.317 + sd = 2;
1.318 + remaining = this.lo32;
1.319 + } else {
1.320 + sd = 4;
1.321 + remaining = this.hi32;
1.322 + }
1.323 +
1.324 + if (remaining < 0) {
1.325 + return sd;
1.326 + }
1.327 +
1.328 + return (remaining < 65536) ? sd - 1 : sd;
1.329 + }
1.330 +
1.331 + this.toNumber = function() {
1.332 + var lo32 = this.lo32;
1.333 + if (lo32 < 0) {
1.334 + lo32 += 0x100000000;
1.335 + }
1.336 +
1.337 + return this.hi32.next32(lo32);
1.338 + }
1.339 + }
1.340 +
1.341 + function __countLeadingZeroes16(number) {
1.342 + var nlz = 0;
1.343 +
1.344 + if (number < 256) {
1.345 + nlz += 8;
1.346 + number <<= 8;
1.347 + }
1.348 +
1.349 + if (number < 4096) {
1.350 + nlz += 4;
1.351 + number <<= 4;
1.352 + }
1.353 +
1.354 + if (number < 16384) {
1.355 + nlz += 2;
1.356 + number <<= 2;
1.357 + }
1.358 +
1.359 + return (number < 32768) ? nlz + 1 : nlz;
1.360 + }
1.361 +
1.362 + // q = u / v; r = u - q * v;
1.363 + // v != 0
1.364 + function __div64(q, r, u, v) {
1.365 + var m = u.countSignificantDigits();
1.366 + var n = v.countSignificantDigits();
1.367 +
1.368 + q.hi32 = q.lo32 = 0;
1.369 +
1.370 + if (n === 1) {
1.371 + // v has single digit
1.372 + var vd = v.getDigit(0, 0);
1.373 + var carry = 0;
1.374 + for (var i = m - 1; i >= 0; --i) {
1.375 + var ui = (carry << 16) | u.getDigit(i, 0);
1.376 + if (ui < 0) {
1.377 + ui += 0x100000000;
1.378 + }
1.379 + var qi = (ui / vd) | 0;
1.380 + q.setDigit(i, 0, qi);
1.381 + carry = ui - qi * vd;
1.382 + }
1.383 +
1.384 + r.hi32 = 0;
1.385 + r.lo32 = carry;
1.386 + return;
1.387 + }
1.388 +
1.389 + r.hi32 = u.hi32;
1.390 + r.lo32 = u.lo32;
1.391 +
1.392 + if (m < n) {
1.393 + return;
1.394 + }
1.395 +
1.396 + // Normalize
1.397 + var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
1.398 +
1.399 + var vd1 = v.getDigit(n - 1, nrm);
1.400 + var vd0 = v.getDigit(n - 2, nrm);
1.401 + for (var j = m - n; j >= 0; --j) {
1.402 + // Calculate qj estimate
1.403 + var ud21 = r.getTwoDigits(j + n, nrm);
1.404 + var ud2 = ud21 >>> 16;
1.405 + if (ud21 < 0) {
1.406 + ud21 += 0x100000000;
1.407 + }
1.408 +
1.409 + var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
1.410 + var rest = ud21 - qest * vd1;
1.411 +
1.412 + // 0 <= (qest - qj) <= 2
1.413 +
1.414 + // Refine qj estimate
1.415 + var ud0 = r.getDigit(j + n - 2, nrm);
1.416 + while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
1.417 + --qest;
1.418 + rest += vd1;
1.419 + }
1.420 +
1.421 + // 0 <= (qest - qj) <= 1
1.422 +
1.423 + // Multiply and subtract
1.424 + var carry = 0;
1.425 + for (var i = 0; i < n; ++i) {
1.426 + var vi = qest * v.getDigit(i, nrm);
1.427 + var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
1.428 + r.setDigit(i + j, nrm, ui);
1.429 + carry = (vi >>> 16) - (ui >> 16);
1.430 + }
1.431 + var uj = ud2 - carry;
1.432 +
1.433 + if (uj < 0) {
1.434 + // qest - qj = 1
1.435 +
1.436 + // Add back
1.437 + --qest;
1.438 + var carry = 0;
1.439 + for (var i = 0; i < n; ++i) {
1.440 + var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
1.441 + + carry;
1.442 + r.setDigit(i + j, nrm, ui);
1.443 + carry = ui >> 16;
1.444 + }
1.445 + uj += carry;
1.446 + }
1.447 +
1.448 + q.setDigit(j, 0, qest);
1.449 + r.setDigit(j + n, nrm, uj);
1.450 + }
1.451 + }
1.452 +
1.453 + numberPrototype.div32 = function(x) {
1.454 + if (x === 0) {
1.455 + __handleDivByZero();
1.456 + }
1.457 +
1.458 + return (this / x) | 0;
1.459 + }
1.460 +
1.461 + numberPrototype.mod32 = function(x) {
1.462 + if (x === 0) {
1.463 + __handleDivByZero();
1.464 + }
1.465 +
1.466 + return (this % x);
1.467 + }
1.468 +
1.469 + numberPrototype.div64 = function(x) {
1.470 + var negateResult = false;
1.471 + var u, v;
1.472 +
1.473 + if ((this.high32() & 0x80000000) != 0) {
1.474 + u = this.neg64();
1.475 + negateResult = !negateResult;
1.476 + } else {
1.477 + u = this;
1.478 + }
1.479 +
1.480 + if ((x.high32() & 0x80000000) != 0) {
1.481 + v = x.neg64();
1.482 + negateResult = !negateResult;
1.483 + } else {
1.484 + v = x;
1.485 + }
1.486 +
1.487 + if ((v === 0) && (v.high32() === 0)) {
1.488 + __handleDivByZero();
1.489 + }
1.490 +
1.491 + if (u.high32() === 0) {
1.492 + if (v.high32() === 0) {
1.493 + var result = (u / v) | 0;
1.494 + return negateResult ? result.neg64() : result;
1.495 + }
1.496 +
1.497 + return 0;
1.498 + }
1.499 +
1.500 + var u64 = new __Int64(u.high32(), u);
1.501 + var v64 = new __Int64(v.high32(), v);
1.502 + var q64 = new __Int64(0, 0);
1.503 + var r64 = new __Int64(0, 0);
1.504 +
1.505 + __div64(q64, r64, u64, v64);
1.506 +
1.507 + var result = q64.toNumber();
1.508 + return negateResult ? result.neg64() : result;
1.509 + }
1.510 +
1.511 + numberPrototype.mod64 = function(x) {
1.512 + var negateResult = false;
1.513 + var u, v;
1.514 +
1.515 + if ((this.high32() & 0x80000000) != 0) {
1.516 + u = this.neg64();
1.517 + negateResult = !negateResult;
1.518 + } else {
1.519 + u = this;
1.520 + }
1.521 +
1.522 + if ((x.high32() & 0x80000000) != 0) {
1.523 + v = x.neg64();
1.524 + } else {
1.525 + v = x;
1.526 + }
1.527 +
1.528 + if ((v === 0) && (v.high32() === 0)) {
1.529 + __handleDivByZero();
1.530 + }
1.531 +
1.532 + if (u.high32() === 0) {
1.533 + var result = (v.high32() === 0) ? (u % v) : u;
1.534 + return negateResult ? result.neg64() : result;
1.535 + }
1.536 +
1.537 + var u64 = new __Int64(u.high32(), u);
1.538 + var v64 = new __Int64(v.high32(), v);
1.539 + var q64 = new __Int64(0, 0);
1.540 + var r64 = new __Int64(0, 0);
1.541 +
1.542 + __div64(q64, r64, u64, v64);
1.543 +
1.544 + var result = r64.toNumber();
1.545 + return negateResult ? result.neg64() : result;
1.546 + }
1.547 +})(Number.prototype);