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

Side by Side Diff: runtime/lib/integers.dart

Issue 247083002: Avoid comparing smi to mint in smi.toString(). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add comments. Created 6 years, 8 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 // TODO(srdjan): fix limitations. 5 // TODO(srdjan): fix limitations.
6 // - shift amount must be a Smi. 6 // - shift amount must be a Smi.
7 class _IntegerImplementation { 7 class _IntegerImplementation {
8 factory _IntegerImplementation._uninstantiable() { 8 factory _IntegerImplementation._uninstantiable() {
9 throw new UnsupportedError( 9 throw new UnsupportedError(
10 "_IntegerImplementation can only be allocated by the VM"); 10 "_IntegerImplementation can only be allocated by the VM");
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31, 287 0x36, 0x38, 0x36, 0x39, 0x37, 0x30, 0x37, 0x31,
288 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35, 288 0x37, 0x32, 0x37, 0x33, 0x37, 0x34, 0x37, 0x35,
289 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39, 289 0x37, 0x36, 0x37, 0x37, 0x37, 0x38, 0x37, 0x39,
290 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33, 290 0x38, 0x30, 0x38, 0x31, 0x38, 0x32, 0x38, 0x33,
291 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37, 291 0x38, 0x34, 0x38, 0x35, 0x38, 0x36, 0x38, 0x37,
292 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31, 292 0x38, 0x38, 0x38, 0x39, 0x39, 0x30, 0x39, 0x31,
293 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35, 293 0x39, 0x32, 0x39, 0x33, 0x39, 0x34, 0x39, 0x35,
294 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39 294 0x39, 0x36, 0x39, 0x37, 0x39, 0x38, 0x39, 0x39
295 ]; 295 ];
296 296
297 // Powers of 10 above 1000000 are indistinguishable. 297 // Powers of 10 above 1000000 are indistinguishable by eye.
298 static const int _POW_10_7 = 10000000; 298 static const int _POW_10_7 = 10000000;
299 static const int _POW_10_8 = 100000000; 299 static const int _POW_10_8 = 100000000;
300 static const int _POW_10_9 = 1000000000; 300 static const int _POW_10_9 = 1000000000;
301 static const int _POW_10_10 = 10000000000;
302 301
303 // Find the number of decimal digits in a positive smi. 302 // Find the number of decimal digits in a positive smi.
303 // Never called with numbers < 100. These are handled before calling.
304 static int _positiveBase10Length(var smi) { 304 static int _positiveBase10Length(var smi) {
305 // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit. 305 // A positive smi has length <= 19 if 63-bit, <=10 if 31-bit.
306 // Avoid comparing a 31-bit smi to a non-smi. 306 // Avoid comparing a 31-bit smi to a non-smi.
307 if (smi < 1000) return 3; 307 if (smi < 1000) return 3;
308 if (smi < 10000) return 4; 308 if (smi < 10000) return 4;
309 if (smi < _POW_10_7) { 309 if (smi < _POW_10_7) {
310 if (smi < 100000) return 5; 310 if (smi < 100000) return 5;
311 if (smi < 1000000) return 6; 311 if (smi < 1000000) return 6;
312 return 7; 312 return 7;
313 } 313 }
314 if (smi < _POW_10_10) { 314 if (smi < _POW_10_8) return 8;
315 if (smi < _POW_10_8) return 8; 315 if (smi < _POW_10_9) return 9;
316 if (smi < _POW_10_9) return 9; 316 smi = smi ~/ _POW_10_9;
317 return 10; 317 // Handle numbers < 100 before calling recursively.
318 } 318 if (smi < 10) return 10;
319 smi = smi ~/ _POW_10_10; 319 if (smi < 100) return 11;
320 if (smi < 10) return 11; 320 return 9 + _positiveBase10Length(smi);
321 if (smi < 100) return 12;
322 return 10 + _positiveBase10Length(smi);
323 } 321 }
324 322
325 String toString() { 323 String toString() {
326 if (this < 0) return _negativeToString(this); 324 if (this < 0) return _negativeToString(this);
327 // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++" 325 // Inspired by Andrei Alexandrescu: "Three Optimization Tips for C++"
328 // Avoid expensive remainder operation by doing it on more than 326 // Avoid expensive remainder operation by doing it on more than
329 // one digit at a time. 327 // one digit at a time.
330 const int DIGIT_ZERO = 0x30; 328 const int DIGIT_ZERO = 0x30;
331 if (this < 10) { 329 if (this < 10) {
332 return _OneByteString._allocate(1).._setAt(0, DIGIT_ZERO + this); 330 return _OneByteString._allocate(1).._setAt(0, DIGIT_ZERO + this);
(...skipping 23 matching lines...) Expand all
356 } else { 354 } else {
357 // No remainder for this case. 355 // No remainder for this case.
358 int digitIndex = smi * 2; 356 int digitIndex = smi * 2;
359 result._setAt(index, _digitTable[digitIndex + 1]); 357 result._setAt(index, _digitTable[digitIndex + 1]);
360 result._setAt(index - 1, _digitTable[digitIndex]); 358 result._setAt(index - 1, _digitTable[digitIndex]);
361 } 359 }
362 return result; 360 return result;
363 } 361 }
364 362
365 // Find the number of decimal digits in a negative smi. 363 // Find the number of decimal digits in a negative smi.
364 // Never called with numbers > -100. These are handled before calling.
366 static int _negativeBase10Length(var negSmi) { 365 static int _negativeBase10Length(var negSmi) {
367 // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit. 366 // A negative smi has length <= 19 if 63-bit, <=10 if 31-bit.
368 // Avoid comparing a 31-bit smi to a non-smi. 367 // Avoid comparing a 31-bit smi to a non-smi.
369 if (negSmi > -1000) return 3; 368 if (negSmi > -1000) return 3;
370 if (negSmi > -10000) return 4; 369 if (negSmi > -10000) return 4;
371 if (negSmi > -_POW_10_7) { 370 if (negSmi > -_POW_10_7) {
372 if (negSmi > -100000) return 5; 371 if (negSmi > -100000) return 5;
373 if (negSmi > -1000000) return 6; 372 if (negSmi > -1000000) return 6;
374 return 7; 373 return 7;
375 } 374 }
376 if (negSmi > -_POW_10_10) { 375 if (negSmi > -_POW_10_8) return 8;
377 if (negSmi > -_POW_10_8) return 8; 376 if (negSmi > -_POW_10_9) return 9;
378 if (negSmi > -_POW_10_9) return 9; 377 negSmi = negSmi ~/ _POW_10_9;
379 return 10; 378 // Handle numbers > -100 before calling recursively.
380 } 379 if (negSmi > -10) return 10;
381 negSmi = negSmi ~/ _POW_10_10; 380 if (negSmi > -100) return 11;
382 if (negSmi > -10) return 11; 381 return 9 + _negativeBase10Length(negSmi);
383 if (negSmi > -100) return 12;
384 return 10 + _negativeBase10Length(negSmi);
385 } 382 }
386 383
387 // Convert a negative smi to a string. 384 // Convert a negative smi to a string.
388 // Doesn't negate the smi to avoid negating the most negative smi, which 385 // Doesn't negate the smi to avoid negating the most negative smi, which
389 // would become a non-smi. 386 // would become a non-smi.
390 static String _negativeToString(int negSmi) { 387 static String _negativeToString(int negSmi) {
391 // Character code for '-' 388 // Character code for '-'
392 const int MINUS_SIGN = 0x2d; 389 const int MINUS_SIGN = 0x2d;
393 // Character code for '0'. 390 // Character code for '0'.
394 const int DIGIT_ZERO = 0x30; 391 const int DIGIT_ZERO = 0x30;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } else { 468 } else {
472 return 0; 469 return 0;
473 } 470 }
474 } 471 }
475 int _shlFromInt(int other) native "Bigint_shlFromInt"; 472 int _shlFromInt(int other) native "Bigint_shlFromInt";
476 473
477 int pow(int exponent) { 474 int pow(int exponent) {
478 throw "Bigint.pow not implemented"; 475 throw "Bigint.pow not implemented";
479 } 476 }
480 } 477 }
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