rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 27 Jan 2016 22:46:04 +0100
changeset 1873 9af63c578721
parent 1872 df5db062f180
permissions -rw-r--r--
Encapsulating access to lower 32-bits of a long number
Martin@438
     1
// empty line needed here
Martin@439
     2
jaroslav@912
     3
(function(numberPrototype) {
jaroslav@1857
     4
    function add32(x, y) {
jaroslav@1857
     5
        return (x + y) | 0;
jaroslav@912
     6
    };
jaroslav@1858
     7
    function mul32(x, y) {
jaroslav@1858
     8
        return (((x * (y >> 16)) << 16) + x * (y & 0xFFFF)) | 0;
jaroslav@912
     9
    };
jaroslav@912
    10
    var __m32 = 0xFFFFFFFF;
Martin@582
    11
jaroslav@912
    12
    numberPrototype.next32 = function(low) {
jaroslav@912
    13
        if (this === 0) {
jaroslav@912
    14
            return low;
jaroslav@912
    15
        }
jaroslav@912
    16
        var l = new Number(low);
jaroslav@912
    17
        l.hi = this | 0;
jaroslav@912
    18
        return l;
jaroslav@912
    19
    };
lubomir@778
    20
jaroslav@912
    21
    numberPrototype.high32 = function() {
jaroslav@1872
    22
        return high32(this);
jaroslav@1872
    23
    };
jaroslav@1873
    24
    function low32(x) {
jaroslav@1873
    25
        return x.lo ? x.lo : x;
jaroslav@1873
    26
    };
jaroslav@1872
    27
    function high32(x) {
jaroslav@1873
    28
        return x.hi ? x.hi : (Math.floor(low32(x) / (__m32 + 1))) | 0;
jaroslav@912
    29
    };
jaroslav@912
    30
    numberPrototype.toFP = function() {
jaroslav@1873
    31
        return this.hi ? this.hi * (__m32 + 1) + low32(this) : low32(this);
jaroslav@912
    32
    };
jaroslav@912
    33
    numberPrototype.toLong = function() {
jaroslav@1873
    34
        var hi = (low32(this) / (__m32 + 1)) | 0;
jaroslav@1873
    35
        var low = (low32(this) % (__m32 + 1)) | 0;
jaroslav@912
    36
        if (low < 0) {
jaroslav@912
    37
            low += __m32 + 1;
jaroslav@912
    38
        }
Martin@607
    39
jaroslav@1873
    40
        if (low32(this) < 0) {
jaroslav@912
    41
            hi -= 1;
Martin@698
    42
        }
Martin@607
    43
Martin@615
    44
        return hi.next32(low);
Martin@615
    45
    };
Martin@615
    46
jaroslav@912
    47
    numberPrototype.toExactString = function() {
jaroslav@912
    48
        if (this.hi) {
jaroslav@912
    49
            // check for Long.MIN_VALUE
jaroslav@1873
    50
            if ((this.hi == (0x80000000 | 0)) && (low32(this) == 0)) {
jaroslav@912
    51
                return '-9223372036854775808';
jaroslav@912
    52
            }
jaroslav@912
    53
            var res = 0;
jaroslav@912
    54
            var a = [6, 9, 2, 7, 6, 9, 4, 9, 2, 4];
jaroslav@912
    55
            var s = '';
jaroslav@912
    56
            var digit;
jaroslav@912
    57
            var neg = this.hi < 0;
jaroslav@912
    58
            if (neg) {
jaroslav@1870
    59
                var x = neg64(this);
jaroslav@912
    60
                var hi = x.hi;
jaroslav@1873
    61
                var low = low32(x);
jaroslav@912
    62
            } else {
jaroslav@912
    63
                var hi = this.hi;
jaroslav@1873
    64
                var low = low32(this);
jaroslav@912
    65
            }
jaroslav@912
    66
            for (var i = 0; i < a.length; i++) {
jaroslav@912
    67
                res += hi * a[i];
jaroslav@912
    68
                var low_digit = low % 10;
jaroslav@912
    69
                digit = (res % 10) + low_digit;
jaroslav@912
    70
jaroslav@912
    71
                low = Math.floor(low / 10);
jaroslav@912
    72
                res = Math.floor(res / 10);
jaroslav@912
    73
jaroslav@912
    74
                if (digit >= 10) {
jaroslav@912
    75
                    digit -= 10;
jaroslav@912
    76
                    res++;
jaroslav@912
    77
                }
jaroslav@912
    78
                s = String(digit).concat(s);
jaroslav@912
    79
            }
jaroslav@912
    80
            s = String(res).concat(s).replace(/^0+/, '');
jaroslav@912
    81
            return (neg ? '-' : '').concat(s);
jaroslav@912
    82
        }
jaroslav@1873
    83
        return String(low32(this));
jaroslav@912
    84
    };
jaroslav@912
    85
jaroslav@1867
    86
    function add64(x, y) {
jaroslav@1873
    87
        var low = low32(x) + low32(y);
jaroslav@912
    88
        carry = 0;
jaroslav@912
    89
        if (low > __m32) {
jaroslav@912
    90
            carry = 1;
jaroslav@912
    91
            low -= (__m32 + 1);
jaroslav@912
    92
        }
jaroslav@1872
    93
        var hi = (high32(x) + high32(y) + carry) | 0;
Martin@627
    94
        return hi.next32(low);
Martin@627
    95
    };
Martin@627
    96
jaroslav@1867
    97
    function sub64(x, y) {
jaroslav@1873
    98
        var low = low32(x) - low32(y);
jaroslav@912
    99
        carry = 0;
jaroslav@912
   100
        if (low < 0) {
jaroslav@912
   101
            carry = 1;
jaroslav@912
   102
            low += (__m32 + 1);
jaroslav@912
   103
        }
jaroslav@1872
   104
        var hi = (high32(x) - high32(y) - carry) | 0;
Martin@628
   105
        return hi.next32(low);
Martin@628
   106
    };
Martin@628
   107
jaroslav@1867
   108
    function mul64(x, y) {
jaroslav@1873
   109
        var low = mul32(low32(x), low32(y));
jaroslav@912
   110
        low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1867
   111
        // first count upper 32 bits of (x.low * x.low)
jaroslav@912
   112
        var hi_hi = 0;
jaroslav@912
   113
        var hi_low = 0;
jaroslav@912
   114
        var m = 1;
jaroslav@912
   115
        for (var i = 0; i < 32; i++) {
jaroslav@1873
   116
            if (low32(y) & m) {
jaroslav@1867
   117
                hi_hi += x >>> 16;
jaroslav@1867
   118
                hi_low += x & 0xFFFF
jaroslav@912
   119
            }
jaroslav@912
   120
            hi_low >>= 1;
jaroslav@912
   121
            hi_low += (hi_hi & 1) ? 0x8000 : 0;
jaroslav@912
   122
            hi_hi >>= 1;
jaroslav@912
   123
            m <<= 1;
jaroslav@912
   124
        }
jaroslav@912
   125
        var hi = (hi_hi << 16) + hi_low;
jaroslav@912
   126
jaroslav@1873
   127
        var m1 = mul32(high32(x), low32(y));
jaroslav@1873
   128
        var m2 = mul32(low32(x), high32(y));
jaroslav@1857
   129
        hi = add32(add32(hi, m1), m2);
jaroslav@912
   130
Martin@594
   131
        return hi.next32(low);
jaroslav@912
   132
    };
Martin@582
   133
jaroslav@1868
   134
    function and64(x, y) {
jaroslav@1873
   135
        var low = low32(x) & low32(y);
jaroslav@912
   136
        low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1868
   137
        if (x.hi && y.hi) {
jaroslav@1868
   138
            var hi = x.hi & y.hi;
jaroslav@912
   139
            return hi.next32(low);
jaroslav@912
   140
        }
jaroslav@912
   141
        ;
Martin@615
   142
        return low;
jaroslav@912
   143
    };
Martin@615
   144
jaroslav@1868
   145
    function or64(x, y) {
jaroslav@1873
   146
        var low = low32(x) | low32(y);
jaroslav@912
   147
        low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1868
   148
        if (x.hi || y.hi) {
jaroslav@1868
   149
            var hi = x.hi | y.hi;
jaroslav@912
   150
            return hi.next32(low);
jaroslav@912
   151
        }
Martin@629
   152
        return low;
jaroslav@912
   153
    };
Martin@629
   154
jaroslav@1868
   155
    function xor64(x, y) {
jaroslav@1873
   156
        var low = low32(x) ^ low32(y);
jaroslav@912
   157
        low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1868
   158
        if (x.hi || y.hi) {
jaroslav@1868
   159
            var hi = x.hi ^ y.hi;
jaroslav@912
   160
            return hi.next32(low);
jaroslav@912
   161
        }
jaroslav@912
   162
        ;
jaroslav@912
   163
        return low;
jaroslav@912
   164
    };
Martin@630
   165
jaroslav@1869
   166
    function shl64(thiz, x) {
Martin@1352
   167
        x &= 0x3f;
jaroslav@1872
   168
        if (x === 0) return thiz;
jaroslav@912
   169
        if (x >= 32) {
jaroslav@1873
   170
            var hi = low32(thiz) << (x - 32);
jaroslav@912
   171
            return hi.next32(0);
jaroslav@912
   172
        } else {
jaroslav@1872
   173
            var hi = high32(thiz) << x;
jaroslav@1873
   174
            var low_reminder = low32(thiz) >> (32 - x);
jaroslav@912
   175
            hi |= low_reminder;
jaroslav@1873
   176
            var low = low32(thiz) << x;
jaroslav@912
   177
            low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@912
   178
            return hi.next32(low);
jaroslav@912
   179
        }
jaroslav@912
   180
    };
lubomir@676
   181
jaroslav@1869
   182
    function shr64(thiz, x) {
Martin@1352
   183
        x &= 0x3f;
jaroslav@1872
   184
        if (x === 0) return thiz;
jaroslav@912
   185
        if (x >= 32) {
jaroslav@1872
   186
            var low = high32(thiz) >> (x - 32);
jaroslav@912
   187
            low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@912
   188
            return low;
jaroslav@912
   189
        } else {
jaroslav@1873
   190
            var low = low32(thiz) >>> x;
jaroslav@1872
   191
            var hi_reminder = high32(thiz) << (32 - x);
jaroslav@912
   192
            low |= hi_reminder;
jaroslav@912
   193
            low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1872
   194
            var hi = high32(thiz) >> x;
jaroslav@912
   195
            return hi.next32(low);
jaroslav@912
   196
        }
jaroslav@912
   197
    };
jaroslav@912
   198
jaroslav@1869
   199
    function ushr64(thiz, x) {
Martin@1352
   200
        x &= 0x3f;
jaroslav@1872
   201
        if (x === 0) return thiz;
jaroslav@912
   202
        if (x >= 32) {
jaroslav@1872
   203
            var low = high32(thiz) >>> (x - 32);
jaroslav@912
   204
            low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@912
   205
            return low;
jaroslav@912
   206
        } else {
jaroslav@1873
   207
            var low = low32(thiz) >>> x;
jaroslav@1872
   208
            var hi_reminder = high32(thiz) << (32 - x);
jaroslav@912
   209
            low |= hi_reminder;
jaroslav@912
   210
            low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@1872
   211
            var hi = high32(thiz) >>> x;
jaroslav@912
   212
            return hi.next32(low);
jaroslav@912
   213
        }
jaroslav@912
   214
    };
jaroslav@1800
   215
jaroslav@1871
   216
    function compare64(x, y) {
jaroslav@1872
   217
        if (high32(x) === high32(y)) {
jaroslav@1873
   218
            var lox = low32(x);
jaroslav@1873
   219
            var loy = low32(y);
jaroslav@1873
   220
            return (lox < loy) ? -1 : ((lox > loy) ? 1 : 0);
jaroslav@912
   221
        }
jaroslav@1872
   222
        return (high32(x) < high32(y)) ? -1 : 1;
jaroslav@912
   223
    };
jaroslav@912
   224
jaroslav@1870
   225
    function neg64(x) {
jaroslav@1872
   226
        var hi = high32(x);
jaroslav@1873
   227
        var low = low32(x);
jaroslav@912
   228
        if ((hi === 0) && (low < 0)) {
jaroslav@912
   229
            return -low;
jaroslav@912
   230
        }
jaroslav@912
   231
        hi = ~hi;
jaroslav@912
   232
        low = ~low;
jaroslav@912
   233
        low += (low < 0) ? (__m32 + 1) : 0;
jaroslav@912
   234
        var ret = hi.next32(low);
jaroslav@1867
   235
        return add64(ret, 1);
jaroslav@912
   236
    };
jaroslav@912
   237
    
lubomir@737
   238
    function __handleDivByZero() {
lubomir@737
   239
        var exception = new vm.java_lang_ArithmeticException;
lubomir@737
   240
        vm.java_lang_ArithmeticException(false).constructor
lubomir@737
   241
          .cons__VLjava_lang_String_2.call(exception, "/ by zero");
lubomir@737
   242
lubomir@737
   243
        throw exception;
lubomir@737
   244
    }
lubomir@737
   245
lubomir@676
   246
    function __Int64(hi32, lo32) {
lubomir@676
   247
        this.hi32 = hi32 | 0;
lubomir@676
   248
        this.lo32 = lo32 | 0;
lubomir@676
   249
lubomir@676
   250
        this.get32 = function(bitIndex) {
lubomir@676
   251
            var v0;
lubomir@676
   252
            var v1;
lubomir@676
   253
            bitIndex += 32;
lubomir@676
   254
            var selector = bitIndex >>> 5;
lubomir@676
   255
            switch (selector) {
lubomir@676
   256
                case 0:
lubomir@676
   257
                    v0 = 0;
lubomir@676
   258
                    v1 = this.lo32;
lubomir@676
   259
                    break;
lubomir@676
   260
                case 1:
lubomir@676
   261
                    v0 = this.lo32;
lubomir@676
   262
                    v1 = this.hi32;
lubomir@676
   263
                    break;
lubomir@676
   264
                case 2:
lubomir@676
   265
                    v0 = this.hi32;
lubomir@676
   266
                    v1 = 0;
lubomir@676
   267
                    break
lubomir@676
   268
                default:
lubomir@676
   269
                    return 0;
lubomir@676
   270
            }
lubomir@676
   271
lubomir@676
   272
            var shift = bitIndex & 31;
lubomir@676
   273
            if (shift === 0) {
lubomir@676
   274
                return v0;
lubomir@676
   275
            }
lubomir@676
   276
lubomir@676
   277
            return (v1 << (32 - shift)) | (v0 >>> shift);
lubomir@676
   278
        }
lubomir@676
   279
lubomir@676
   280
        this.get16 = function(bitIndex) {
lubomir@676
   281
            return this.get32(bitIndex) & 0xffff;
lubomir@676
   282
        }
lubomir@676
   283
lubomir@676
   284
        this.set16 = function(bitIndex, value) {
lubomir@676
   285
            bitIndex += 32;
lubomir@676
   286
            var shift = bitIndex & 15;
lubomir@676
   287
            var svalue = (value & 0xffff) << shift; 
lubomir@676
   288
            var smask = 0xffff << shift;
lubomir@676
   289
            var selector = bitIndex >>> 4;
lubomir@676
   290
            switch (selector) {
lubomir@676
   291
                case 0:
lubomir@676
   292
                    break;
lubomir@676
   293
                case 1:
lubomir@676
   294
                    this.lo32 = (this.lo32 & ~(smask >>> 16))
lubomir@676
   295
                                    | (svalue >>> 16);
lubomir@676
   296
                    break;
lubomir@676
   297
                case 2:
lubomir@676
   298
                    this.lo32 = (this.lo32 & ~smask) | svalue;
lubomir@676
   299
                    break;
lubomir@676
   300
                case 3:
lubomir@676
   301
                    this.lo32 = (this.lo32 & ~(smask << 16))
lubomir@676
   302
                                    | (svalue << 16);
lubomir@676
   303
                    this.hi32 = (this.hi32 & ~(smask >>> 16))
lubomir@676
   304
                                    | (svalue >>> 16);
lubomir@676
   305
                    break;
lubomir@676
   306
                case 4:
lubomir@676
   307
                    this.hi32 = (this.hi32 & ~smask) | svalue;
lubomir@676
   308
                    break;
lubomir@676
   309
                case 5:
lubomir@676
   310
                    this.hi32 = (this.hi32 & ~(smask << 16))
lubomir@676
   311
                                    | (svalue << 16);
lubomir@676
   312
                    break;
lubomir@676
   313
            }
lubomir@676
   314
        }
lubomir@676
   315
lubomir@676
   316
        this.getDigit = function(index, shift) {
lubomir@676
   317
            return this.get16((index << 4) - shift);
lubomir@676
   318
        }
lubomir@676
   319
lubomir@676
   320
        this.getTwoDigits = function(index, shift) {
lubomir@676
   321
            return this.get32(((index - 1) << 4) - shift);
lubomir@676
   322
        }
lubomir@676
   323
lubomir@676
   324
        this.setDigit = function(index, shift, value) {
lubomir@676
   325
            this.set16((index << 4) - shift, value);
lubomir@676
   326
        }
lubomir@676
   327
lubomir@676
   328
        this.countSignificantDigits = function() {
lubomir@676
   329
            var sd;
lubomir@676
   330
            var remaining;
lubomir@676
   331
lubomir@676
   332
            if (this.hi32 === 0) {
lubomir@676
   333
                if (this.lo32 === 0) {
lubomir@676
   334
                    return 0;
lubomir@676
   335
                }
lubomir@676
   336
lubomir@676
   337
                sd = 2;
lubomir@676
   338
                remaining = this.lo32;
lubomir@676
   339
            } else {
lubomir@676
   340
                sd = 4;
lubomir@676
   341
                remaining = this.hi32;
lubomir@676
   342
            }
lubomir@676
   343
lubomir@676
   344
            if (remaining < 0) {
lubomir@676
   345
                return sd;
lubomir@676
   346
            }
lubomir@676
   347
lubomir@676
   348
            return (remaining < 65536) ? sd - 1 : sd;
lubomir@676
   349
        }
lubomir@676
   350
        
lubomir@676
   351
        this.toNumber = function() {
lubomir@676
   352
            var lo32 = this.lo32;
lubomir@676
   353
            if (lo32 < 0) {
lubomir@676
   354
                lo32 += 0x100000000;
lubomir@676
   355
            }
lubomir@676
   356
lubomir@676
   357
            return this.hi32.next32(lo32);
lubomir@676
   358
        }
lubomir@676
   359
    }
lubomir@676
   360
lubomir@676
   361
    function __countLeadingZeroes16(number) {
lubomir@676
   362
        var nlz = 0;
lubomir@676
   363
lubomir@676
   364
        if (number < 256) {
lubomir@676
   365
            nlz += 8;
lubomir@676
   366
            number <<= 8;
lubomir@676
   367
        }
lubomir@676
   368
lubomir@676
   369
        if (number < 4096) {
lubomir@676
   370
            nlz += 4;
lubomir@676
   371
            number <<= 4;
lubomir@676
   372
        }
lubomir@676
   373
lubomir@676
   374
        if (number < 16384) {
lubomir@676
   375
            nlz += 2;
lubomir@676
   376
            number <<= 2;
lubomir@676
   377
        }
lubomir@676
   378
lubomir@676
   379
        return (number < 32768) ? nlz + 1 : nlz;
lubomir@676
   380
    }
lubomir@676
   381
    
lubomir@676
   382
    // q = u / v; r = u - q * v;
lubomir@676
   383
    // v != 0
lubomir@676
   384
    function __div64(q, r, u, v) {
lubomir@676
   385
        var m = u.countSignificantDigits();
lubomir@676
   386
        var n = v.countSignificantDigits();
lubomir@676
   387
lubomir@676
   388
        q.hi32 = q.lo32 = 0;
lubomir@676
   389
lubomir@676
   390
        if (n === 1) {
lubomir@676
   391
            // v has single digit
lubomir@676
   392
            var vd = v.getDigit(0, 0);
lubomir@676
   393
            var carry = 0;
lubomir@676
   394
            for (var i = m - 1; i >= 0; --i) {
lubomir@676
   395
                var ui = (carry << 16) | u.getDigit(i, 0);
lubomir@676
   396
                if (ui < 0) {
lubomir@676
   397
                    ui += 0x100000000;
lubomir@676
   398
                }
lubomir@676
   399
                var qi = (ui / vd) | 0;
lubomir@676
   400
                q.setDigit(i, 0, qi);
lubomir@676
   401
                carry = ui - qi * vd;
lubomir@676
   402
            }
lubomir@676
   403
lubomir@676
   404
            r.hi32 = 0;
lubomir@676
   405
            r.lo32 = carry;
lubomir@676
   406
            return;
lubomir@676
   407
        }
lubomir@676
   408
lubomir@676
   409
        r.hi32 = u.hi32;  
lubomir@676
   410
        r.lo32 = u.lo32;
lubomir@676
   411
lubomir@676
   412
        if (m < n) {
lubomir@676
   413
            return;
lubomir@676
   414
        }
lubomir@676
   415
lubomir@676
   416
        // Normalize
lubomir@676
   417
        var nrm = __countLeadingZeroes16(v.getDigit(n - 1, 0));
lubomir@676
   418
lubomir@676
   419
        var vd1 = v.getDigit(n - 1, nrm);                
lubomir@676
   420
        var vd0 = v.getDigit(n - 2, nrm);
lubomir@676
   421
        for (var j = m - n; j >= 0; --j) {
lubomir@676
   422
            // Calculate qj estimate
lubomir@676
   423
            var ud21 = r.getTwoDigits(j + n, nrm);
lubomir@676
   424
            var ud2 = ud21 >>> 16;
lubomir@676
   425
            if (ud21 < 0) {
lubomir@676
   426
                ud21 += 0x100000000;
lubomir@676
   427
            }
lubomir@676
   428
lubomir@676
   429
            var qest = (ud2 === vd1) ? 0xFFFF : ((ud21 / vd1) | 0);
lubomir@676
   430
            var rest = ud21 - qest * vd1;
lubomir@676
   431
lubomir@676
   432
            // 0 <= (qest - qj) <= 2
lubomir@676
   433
lubomir@676
   434
            // Refine qj estimate
lubomir@676
   435
            var ud0 = r.getDigit(j + n - 2, nrm);
lubomir@676
   436
            while ((qest * vd0) > ((rest * 0x10000) + ud0)) {
lubomir@676
   437
                --qest;
lubomir@676
   438
                rest += vd1;
lubomir@676
   439
            }
lubomir@676
   440
lubomir@676
   441
            // 0 <= (qest - qj) <= 1
lubomir@676
   442
            
lubomir@676
   443
            // Multiply and subtract
lubomir@676
   444
            var carry = 0;
lubomir@676
   445
            for (var i = 0; i < n; ++i) {
lubomir@676
   446
                var vi = qest * v.getDigit(i, nrm);
lubomir@676
   447
                var ui = r.getDigit(i + j, nrm) - carry - (vi & 0xffff);
lubomir@676
   448
                r.setDigit(i + j, nrm, ui);
lubomir@676
   449
                carry = (vi >>> 16) - (ui >> 16);
lubomir@676
   450
            }
lubomir@676
   451
            var uj = ud2 - carry;
lubomir@676
   452
lubomir@676
   453
            if (uj < 0) {
lubomir@676
   454
                // qest - qj = 1
lubomir@676
   455
lubomir@676
   456
                // Add back
lubomir@676
   457
                --qest;
lubomir@676
   458
                var carry = 0;
lubomir@676
   459
                for (var i = 0; i < n; ++i) {
lubomir@676
   460
                    var ui = r.getDigit(i + j, nrm) + v.getDigit(i, nrm)
lubomir@676
   461
                                 + carry;
lubomir@676
   462
                    r.setDigit(i + j, nrm, ui);
lubomir@676
   463
                    carry = ui >> 16;
lubomir@676
   464
                }
lubomir@676
   465
                uj += carry;
lubomir@676
   466
            }
lubomir@676
   467
lubomir@676
   468
            q.setDigit(j, 0, qest);
lubomir@676
   469
            r.setDigit(j + n, nrm, uj);
lubomir@676
   470
        }
lubomir@676
   471
    }
lubomir@737
   472
jaroslav@1867
   473
    function div64(x, y) {
lubomir@676
   474
        var negateResult = false;
lubomir@676
   475
        var u, v;
lubomir@737
   476
jaroslav@1872
   477
        if ((high32(x) & 0x80000000) !== 0) {
jaroslav@1870
   478
            u = neg64(x);
lubomir@676
   479
            negateResult = !negateResult;
lubomir@676
   480
        } else {
jaroslav@1867
   481
            u = x;
lubomir@676
   482
        }
lubomir@676
   483
jaroslav@1872
   484
        if ((high32(y) & 0x80000000) !== 0) {
jaroslav@1870
   485
            v = neg64(y);
lubomir@676
   486
            negateResult = !negateResult;
lubomir@676
   487
        } else {
jaroslav@1867
   488
            v = y;
lubomir@676
   489
        }
lubomir@676
   490
jaroslav@1873
   491
        if ((low32(v) === 0) && (high32(v) === 0)) {
lubomir@737
   492
            __handleDivByZero();
lubomir@676
   493
        }
lubomir@676
   494
jaroslav@1872
   495
        if (high32(u) === 0) {
jaroslav@1872
   496
            if (high32(v) === 0) {
jaroslav@1873
   497
                var result = (low32(u) / low32(v)) | 0;
jaroslav@1870
   498
                return negateResult ? neg64(result) : result;
lubomir@676
   499
            }
lubomir@676
   500
lubomir@676
   501
            return 0;
lubomir@676
   502
        }
lubomir@676
   503
jaroslav@1873
   504
        var u64 = new __Int64(high32(u), low32(u));
jaroslav@1873
   505
        var v64 = new __Int64(high32(v), low32(v));
lubomir@676
   506
        var q64 = new __Int64(0, 0);
lubomir@676
   507
        var r64 = new __Int64(0, 0);
lubomir@676
   508
lubomir@676
   509
        __div64(q64, r64, u64, v64);
lubomir@676
   510
lubomir@676
   511
        var result = q64.toNumber();
jaroslav@1870
   512
        return negateResult ? neg64(result) : result;
lubomir@676
   513
    }
lubomir@676
   514
jaroslav@1868
   515
    function mod64(x, y) {
lubomir@676
   516
        var negateResult = false;
lubomir@676
   517
        var u, v;
lubomir@676
   518
        
jaroslav@1872
   519
        if ((high32(x) & 0x80000000) !== 0) {
jaroslav@1870
   520
            u = neg64(x);
lubomir@676
   521
            negateResult = !negateResult;
lubomir@676
   522
        } else {
jaroslav@1868
   523
            u = x;
lubomir@676
   524
        }
lubomir@676
   525
jaroslav@1872
   526
        if ((high32(y) & 0x80000000) !== 0) {
jaroslav@1870
   527
            v = neg64(y);
lubomir@676
   528
        } else {
jaroslav@1868
   529
            v = y;
lubomir@676
   530
        }
lubomir@676
   531
jaroslav@1873
   532
        if ((low32(v) === 0) && (high32(v) === 0)) {
lubomir@737
   533
            __handleDivByZero();
lubomir@676
   534
        }
lubomir@676
   535
jaroslav@1872
   536
        if (high32(u) === 0) {
jaroslav@1873
   537
            var result = (high32(v) === 0) ? (low32(u) % low32(v)) : low32(u);
jaroslav@1870
   538
            return negateResult ? neg64(result) : result;
lubomir@676
   539
        }
lubomir@676
   540
jaroslav@1873
   541
        var u64 = new __Int64(high32(u), low32(u));
jaroslav@1873
   542
        var v64 = new __Int64(high32(v), low32(v));
lubomir@676
   543
        var q64 = new __Int64(0, 0);
lubomir@676
   544
        var r64 = new __Int64(0, 0);
lubomir@676
   545
lubomir@676
   546
        __div64(q64, r64, u64, v64);
lubomir@676
   547
lubomir@676
   548
        var result = r64.toNumber();
jaroslav@1870
   549
        return negateResult ? neg64(result) : result;
lubomir@676
   550
    }
jaroslav@1866
   551
jaroslav@1866
   552
    var b = numberPrototype['__bit64'] = {};
jaroslav@1867
   553
    b.add64 = add64;
jaroslav@1867
   554
    b.sub64 = sub64;
jaroslav@1867
   555
    b.mul64 = mul64;
jaroslav@1867
   556
    b.div64 = div64;
jaroslav@1868
   557
    b.mod64 = mod64;
jaroslav@1868
   558
    b.and64 = and64;
jaroslav@1868
   559
    b.or64 = or64;
jaroslav@1868
   560
    b.xor64 = xor64;
jaroslav@1870
   561
    b.neg64 = neg64;
jaroslav@1869
   562
    b.shl64 = shl64;
jaroslav@1869
   563
    b.shr64 = shr64;
jaroslav@1869
   564
    b.ushr64 = ushr64;
jaroslav@1871
   565
    b.compare64 = compare64;
lubomir@678
   566
})(Number.prototype);
jaroslav@832
   567
jaroslav@832
   568
vm.java_lang_Number(false);