rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
Some operations are faster when included in the generated code rather than dispatched to Number.prototype
1 // empty line needed here
3 (function(numberPrototype) {
7 numberPrototype.mul32 = function(x) {
8 return (((this * (x >> 16)) << 16) + this * (x & 0xFFFF)) | 0;
10 numberPrototype.div32 = function(x) {
15 return (this / x) | 0;
18 numberPrototype.mod32 = function(x) {
26 var __m32 = 0xFFFFFFFF;
28 numberPrototype.next32 = function(low) {
32 var l = new Number(low);
37 numberPrototype.high32 = function() {
38 return this.hi ? this.hi : (Math.floor(this / (__m32 + 1))) | 0;
40 numberPrototype.toFP = function() {
41 return this.hi ? this.hi * (__m32 + 1) + this : this;
43 numberPrototype.toLong = function() {
44 var hi = (this / (__m32 + 1)) | 0;
45 var low = (this % (__m32 + 1)) | 0;
54 return hi.next32(low);
57 numberPrototype.toExactString = function() {
59 // check for Long.MIN_VALUE
60 if ((this.hi == (0x80000000 | 0)) && (this == 0)) {
61 return '-9223372036854775808';
64 var a = [6, 9, 2, 7, 6, 9, 4, 9, 2, 4];
67 var neg = this.hi < 0;
76 for (var i = 0; i < a.length; i++) {
78 var low_digit = low % 10;
79 digit = (res % 10) + low_digit;
81 low = Math.floor(low / 10);
82 res = Math.floor(res / 10);
88 s = String(digit).concat(s);
90 s = String(res).concat(s).replace(/^0+/, '');
91 return (neg ? '-' : '').concat(s);
96 numberPrototype.add64 = function(x) {
103 var hi = (this.high32() + x.high32() + carry) | 0;
104 return hi.next32(low);
107 numberPrototype.sub64 = function(x) {
114 var hi = (this.high32() - x.high32() - carry) | 0;
115 return hi.next32(low);
118 numberPrototype.mul64 = function(x) {
119 var low = this.mul32(x);
120 low += (low < 0) ? (__m32 + 1) : 0;
121 // first count upper 32 bits of (this.low * x.low)
125 for (var i = 0; i < 32; i++) {
127 hi_hi += this >>> 16;
128 hi_low += this & 0xFFFF
131 hi_low += (hi_hi & 1) ? 0x8000 : 0;
135 var hi = (hi_hi << 16) + hi_low;
137 var m1 = this.high32().mul32(x);
138 var m2 = this.mul32(x.high32());
139 hi = add32(add32(hi, m1), m2);
141 return hi.next32(low);
144 numberPrototype.and64 = function(x) {
146 low += (low < 0) ? (__m32 + 1) : 0;
147 if (this.hi && x.hi) {
148 var hi = this.hi & x.hi;
149 return hi.next32(low);
155 numberPrototype.or64 = function(x) {
157 low += (low < 0) ? (__m32 + 1) : 0;
158 if (this.hi || x.hi) {
159 var hi = this.hi | x.hi;
160 return hi.next32(low);
166 numberPrototype.xor64 = function(x) {
168 low += (low < 0) ? (__m32 + 1) : 0;
169 if (this.hi || x.hi) {
170 var hi = this.hi ^ x.hi;
171 return hi.next32(low);
177 numberPrototype.shl64 = function(x) {
179 if (x == 0) return this;
181 var hi = this << (x - 32);
184 var hi = this.high32() << x;
185 var low_reminder = this >> (32 - x);
188 low += (low < 0) ? (__m32 + 1) : 0;
189 return hi.next32(low);
193 numberPrototype.shr64 = function(x) {
195 if (x == 0) return this;
197 var low = this.high32() >> (x - 32);
198 low += (low < 0) ? (__m32 + 1) : 0;
201 var low = this >>> x;
202 var hi_reminder = this.high32() << (32 - x);
204 low += (low < 0) ? (__m32 + 1) : 0;
205 var hi = this.high32() >> x;
206 return hi.next32(low);
210 numberPrototype.ushr64 = function(x) {
212 if (x == 0) return this;
214 var low = this.high32() >>> (x - 32);
215 low += (low < 0) ? (__m32 + 1) : 0;
218 var low = this >>> x;
219 var hi_reminder = this.high32() << (32 - x);
221 low += (low < 0) ? (__m32 + 1) : 0;
222 var hi = this.high32() >>> x;
223 return hi.next32(low);
227 numberPrototype.compare64 = function(x) {
228 if (this.high32() === x.high32()) {
229 return (this < x) ? -1 : ((this > x) ? 1 : 0);
231 return (this.high32() < x.high32()) ? -1 : 1;
234 numberPrototype.neg64 = function() {
235 var hi = this.high32();
237 if ((hi === 0) && (low < 0)) {
242 low += (low < 0) ? (__m32 + 1) : 0;
243 var ret = hi.next32(low);
247 function __handleDivByZero() {
248 var exception = new vm.java_lang_ArithmeticException;
249 vm.java_lang_ArithmeticException(false).constructor
250 .cons__VLjava_lang_String_2.call(exception, "/ by zero");
255 function __Int64(hi32, lo32) {
256 this.hi32 = hi32 | 0;
257 this.lo32 = lo32 | 0;
259 this.get32 = function(bitIndex) {
263 var selector = bitIndex >>> 5;
281 var shift = bitIndex & 31;
286 return (v1 << (32 - shift)) | (v0 >>> shift);
289 this.get16 = function(bitIndex) {
290 return this.get32(bitIndex) & 0xffff;
293 this.set16 = function(bitIndex, value) {
295 var shift = bitIndex & 15;
296 var svalue = (value & 0xffff) << shift;
297 var smask = 0xffff << shift;
298 var selector = bitIndex >>> 4;
303 this.lo32 = (this.lo32 & ~(smask >>> 16))
307 this.lo32 = (this.lo32 & ~smask) | svalue;
310 this.lo32 = (this.lo32 & ~(smask << 16))
312 this.hi32 = (this.hi32 & ~(smask >>> 16))
316 this.hi32 = (this.hi32 & ~smask) | svalue;
319 this.hi32 = (this.hi32 & ~(smask << 16))
325 this.getDigit = function(index, shift) {
326 return this.get16((index << 4) - shift);
329 this.getTwoDigits = function(index, shift) {
330 return this.get32(((index - 1) << 4) - shift);
333 this.setDigit = function(index, shift, value) {
334 this.set16((index << 4) - shift, value);
337 this.countSignificantDigits = function() {
341 if (this.hi32 === 0) {
342 if (this.lo32 === 0) {
347 remaining = this.lo32;
350 remaining = this.hi32;
357 return (remaining < 65536) ? sd - 1 : sd;
360 this.toNumber = function() {
361 var lo32 = this.lo32;
366 return this.hi32.next32(lo32);
370 function __countLeadingZeroes16(number) {
383 if (number < 16384) {
388 return (number < 32768) ? nlz + 1 : nlz;
391 // q = u / v; r = u - q * v;
393 function __div64(q, r, u, v) {
394 var m = u.countSignificantDigits();
395 var n = v.countSignificantDigits();
400 // v has single digit
401 var vd = v.getDigit(0, 0);
403 for (var i = m - 1; i >= 0; --i) {
404 var ui = (carry << 16) | u.getDigit(i, 0);
408 var qi = (ui / vd) | 0;
409 q.setDigit(i, 0, qi);
410 carry = ui - qi * vd;
426 var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
428 var vd1 = v.getDigit(n - 1, nrm);
429 var vd0 = v.getDigit(n - 2, nrm);
430 for (var j = m - n; j >= 0; --j) {
431 // Calculate qj estimate
432 var ud21 = r.getTwoDigits(j + n, nrm);
433 var ud2 = ud21 >>> 16;
438 var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
439 var rest = ud21 - qest * vd1;
441 // 0 <= (qest - qj) <= 2
443 // Refine qj estimate
444 var ud0 = r.getDigit(j + n - 2, nrm);
445 while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
450 // 0 <= (qest - qj) <= 1
452 // Multiply and subtract
454 for (var i = 0; i < n; ++i) {
455 var vi = qest * v.getDigit(i, nrm);
456 var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
457 r.setDigit(i + j, nrm, ui);
458 carry = (vi >>> 16) - (ui >> 16);
460 var uj = ud2 - carry;
468 for (var i = 0; i < n; ++i) {
469 var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
471 r.setDigit(i + j, nrm, ui);
477 q.setDigit(j, 0, qest);
478 r.setDigit(j + n, nrm, uj);
482 numberPrototype.div64 = function(x) {
483 var negateResult = false;
486 if ((this.high32() & 0x80000000) != 0) {
488 negateResult = !negateResult;
493 if ((x.high32() & 0x80000000) != 0) {
495 negateResult = !negateResult;
500 if ((v == 0) && (v.high32() === 0)) {
504 if (u.high32() === 0) {
505 if (v.high32() === 0) {
506 var result = (u / v) | 0;
507 return negateResult ? result.neg64() : result;
513 var u64 = new __Int64(u.high32(), u);
514 var v64 = new __Int64(v.high32(), v);
515 var q64 = new __Int64(0, 0);
516 var r64 = new __Int64(0, 0);
518 __div64(q64, r64, u64, v64);
520 var result = q64.toNumber();
521 return negateResult ? result.neg64() : result;
524 numberPrototype.mod64 = function(x) {
525 var negateResult = false;
528 if ((this.high32() & 0x80000000) != 0) {
530 negateResult = !negateResult;
535 if ((x.high32() & 0x80000000) != 0) {
541 if ((v == 0) && (v.high32() === 0)) {
545 if (u.high32() === 0) {
546 var result = (v.high32() === 0) ? (u % v) : u;
547 return negateResult ? result.neg64() : result;
550 var u64 = new __Int64(u.high32(), u);
551 var v64 = new __Int64(v.high32(), v);
552 var q64 = new __Int64(0, 0);
553 var r64 = new __Int64(0, 0);
555 __div64(q64, r64, u64, v64);
557 var result = r64.toNumber();
558 return negateResult ? result.neg64() : result;
560 })(Number.prototype);
562 vm.java_lang_Number(false);