Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Side by Side Diff: pkg/fixnum/lib/src/int64.dart

Issue 404453002: Int64 tweaks for type inference (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698