| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of fixnum; | 5 part of fixnum; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * An immutable 64-bit signed integer, in the range [-2^63, 2^63 - 1]. | 8 * An immutable 64-bit signed integer, in the range [-2^63, 2^63 - 1]. |
| 9 * Arithmetic operations may overflow in order to maintain this range. | 9 * Arithmetic operations may overflow in order to maintain this range. |
| 10 */ | 10 */ |
| 11 class Int64 implements IntX { | 11 class Int64 implements IntX { |
| 12 | 12 |
| 13 // A 64-bit integer is represented internally as three non-negative | 13 // A 64-bit integer is represented internally as three non-negative |
| 14 // integers, storing the 22 low, 22 middle, and 20 high bits of the | 14 // integers, storing the 22 low, 22 middle, and 20 high bits of the |
| 15 // 64-bit value. _l (low) and _m (middle) are in the range | 15 // 64-bit value. _l (low) and _m (middle) are in the range |
| 16 // [0, 2^22 - 1] and _h (high) is in the range [0, 2^20 - 1]. | 16 // [0, 2^22 - 1] and _h (high) is in the range [0, 2^20 - 1]. |
| 17 // |
| 18 // The values being assigned to _l, _m and _h in initialization are masked to |
| 19 // force them into the above ranges. Sometimes we know that the value is a |
| 20 // small non-negative integer but the dart2js compiler can't infer that, so a |
| 21 // few of the masking operations are not needed for correctness but are |
| 22 // helpful for dart2js code quality. |
| 23 |
| 17 final int _l, _m, _h; | 24 final int _l, _m, _h; |
| 18 | 25 |
| 19 // Note: several functions require _BITS == 22 -- do not change this value. | 26 // Note: several functions require _BITS == 22 -- do not change this value. |
| 20 static const int _BITS = 22; | 27 static const int _BITS = 22; |
| 21 static const int _BITS01 = 44; // 2 * _BITS | 28 static const int _BITS01 = 44; // 2 * _BITS |
| 22 static const int _BITS2 = 20; // 64 - _BITS01 | 29 static const int _BITS2 = 20; // 64 - _BITS01 |
| 23 static const int _MASK = 4194303; // (1 << _BITS) - 1 | 30 static const int _MASK = 4194303; // (1 << _BITS) - 1 |
| 24 static const int _MASK2 = 1048575; // (1 << _BITS2) - 1 | 31 static const int _MASK2 = 1048575; // (1 << _BITS2) - 1 |
| 25 static const int _SIGN_BIT = 19; // _BITS2 - 1 | 32 static const int _SIGN_BIT = 19; // _BITS2 - 1 |
| 26 static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT | 33 static const int _SIGN_BIT_MASK = 524288; // 1 << _SIGN_BIT |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } else { | 141 } else { |
| 135 // Avoid using bitwise operations that coerce their input to 32 bits. | 142 // Avoid using bitwise operations that coerce their input to 32 bits. |
| 136 v2 = value ~/ 17592186044416; // 2^44 | 143 v2 = value ~/ 17592186044416; // 2^44 |
| 137 value -= v2 * 17592186044416; | 144 value -= v2 * 17592186044416; |
| 138 v1 = value ~/ 4194304; // 2^22 | 145 v1 = value ~/ 4194304; // 2^22 |
| 139 value -= v1 * 4194304; | 146 value -= v1 * 4194304; |
| 140 v0 = value; | 147 v0 = value; |
| 141 } | 148 } |
| 142 | 149 |
| 143 if (negative) { | 150 if (negative) { |
| 144 v0 = _MASK & ~v0; | 151 v0 = ~v0; |
| 145 v1 = _MASK & ~v1; | 152 v1 = ~v1; |
| 146 v2 = _MASK2 & ~v2; | 153 v2 = ~v2; |
| 147 } | 154 } |
| 148 return new Int64._bits(v0, v1, v2); | 155 return Int64._masked(v0, v1, v2); |
| 149 } | 156 } |
| 150 | 157 |
| 151 factory Int64.fromBytes(List<int> bytes) { | 158 factory Int64.fromBytes(List<int> bytes) { |
| 152 int top = bytes[7] & 0xff; | 159 int top = bytes[7] & 0xff; |
| 153 top <<= 8; | 160 top <<= 8; |
| 154 top |= bytes[6] & 0xff; | 161 top |= bytes[6] & 0xff; |
| 155 top <<= 8; | 162 top <<= 8; |
| 156 top |= bytes[5] & 0xff; | 163 top |= bytes[5] & 0xff; |
| 157 top <<= 8; | 164 top <<= 8; |
| 158 top |= bytes[4] & 0xff; | 165 top |= bytes[4] & 0xff; |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 // All zeros | 593 // All zeros |
| 587 return 64; | 594 return 64; |
| 588 } | 595 } |
| 589 | 596 |
| 590 Int64 toSigned(int width) { | 597 Int64 toSigned(int width) { |
| 591 if (width < 1 || width > 64) throw new ArgumentError(width); | 598 if (width < 1 || width > 64) throw new ArgumentError(width); |
| 592 if (width > _BITS01) { | 599 if (width > _BITS01) { |
| 593 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01)); | 600 return Int64._masked(_l, _m, _h.toSigned(width - _BITS01)); |
| 594 } else if (width > _BITS) { | 601 } else if (width > _BITS) { |
| 595 int m = _m.toSigned(width - _BITS); | 602 int m = _m.toSigned(width - _BITS); |
| 596 return m.isNegative ? Int64._masked(_l, m, _MASK2) : | 603 return m.isNegative |
| 597 new Int64._bits(_l, m, 0); | 604 ? Int64._masked(_l, m, _MASK2) |
| 605 : Int64._masked(_l, m, 0); // Masking for type inferrer. |
| 598 } else { | 606 } else { |
| 599 int l = _l.toSigned(width); | 607 int l = _l.toSigned(width); |
| 600 return l.isNegative ? Int64._masked(l, _MASK, _MASK2) : | 608 return l.isNegative |
| 601 new Int64._bits(l, 0, 0); | 609 ? Int64._masked(l, _MASK, _MASK2) |
| 610 : Int64._masked(l, 0, 0); // Masking for type inferrer. |
| 602 } | 611 } |
| 603 } | 612 } |
| 604 | 613 |
| 605 Int64 toUnsigned(int width) { | 614 Int64 toUnsigned(int width) { |
| 606 if (width < 0 || width > 64) throw new ArgumentError(width); | 615 if (width < 0 || width > 64) throw new ArgumentError(width); |
| 607 if (width > _BITS01) { | 616 if (width > _BITS01) { |
| 608 int h = _h.toUnsigned(width - _BITS01); | 617 int h = _h.toUnsigned(width - _BITS01); |
| 609 return Int64._masked(_l, _m, h); | 618 return Int64._masked(_l, _m, h); |
| 610 } else if (width > _BITS) { | 619 } else if (width > _BITS) { |
| 611 int m = _m.toUnsigned(width - _BITS); | 620 int m = _m.toUnsigned(width - _BITS); |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1017 } | 1026 } |
| 1018 | 1027 |
| 1019 // 0 <= R < B | 1028 // 0 <= R < B |
| 1020 assert(Int64.ZERO <= new Int64._bits(r0, r1, r2)); | 1029 assert(Int64.ZERO <= new Int64._bits(r0, r1, r2)); |
| 1021 assert(r2 < b2 || // Handles case where B = -(MIN_VALUE) | 1030 assert(r2 < b2 || // Handles case where B = -(MIN_VALUE) |
| 1022 new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2)); | 1031 new Int64._bits(r0, r1, r2) < new Int64._bits(b0, b1, b2)); |
| 1023 | 1032 |
| 1024 assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM); | 1033 assert(what == _RETURN_DIV || what == _RETURN_MOD || what == _RETURN_REM); |
| 1025 if (what == _RETURN_DIV) { | 1034 if (what == _RETURN_DIV) { |
| 1026 if (aNeg != bNeg) return _negate(q0, q1, q2); | 1035 if (aNeg != bNeg) return _negate(q0, q1, q2); |
| 1027 return new Int64._bits(q0, q1, q2); | 1036 return Int64._masked(q0, q1, q2); // Masking for type inferrer. |
| 1028 } | 1037 } |
| 1029 | 1038 |
| 1030 if (!aNeg) return new Int64._bits(r0, r1, r2); | 1039 if (!aNeg) { |
| 1040 return new Int64._bits(_MASK & r0, r1, r2); // Masking for type inferrer. |
| 1041 } |
| 1031 | 1042 |
| 1032 if (what == _RETURN_MOD) { | 1043 if (what == _RETURN_MOD) { |
| 1033 if (r0 == 0 && r1 == 0 && r2 == 0) { | 1044 if (r0 == 0 && r1 == 0 && r2 == 0) { |
| 1034 return ZERO; | 1045 return ZERO; |
| 1035 } else { | 1046 } else { |
| 1036 return _sub(b0, b1, b2, r0, r1, r2); | 1047 return _sub(b0, b1, b2, r0, r1, r2); |
| 1037 } | 1048 } |
| 1038 } else { | 1049 } else { |
| 1039 return _negate(r0, r1, r2); | 1050 return _negate(r0, r1, r2); |
| 1040 } | 1051 } |
| 1041 } | 1052 } |
| 1042 } | 1053 } |
| OLD | NEW |