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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/js_helper.dart

Issue 2994203002: Optimize DDC private library files. (Closed)
Patch Set: Address comments Created 3 years, 4 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart._js_helper; 5 library dart._js_helper;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'dart:_debugger' show stackTraceMapper; 9 import 'dart:_debugger' show stackTraceMapper;
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 return JS('int', '#', hash); 66 return JS('int', '#', hash);
67 } 67 }
68 68
69 @NoInline() 69 @NoInline()
70 static int _parseIntError(String source, int handleError(String source)) { 70 static int _parseIntError(String source, int handleError(String source)) {
71 if (handleError == null) throw new FormatException(source); 71 if (handleError == null) throw new FormatException(source);
72 return handleError(source); 72 return handleError(source);
73 } 73 }
74 74
75 static int parseInt( 75 static int parseInt(
76 String source, int radix, int handleError(String source)) { 76 @nullCheck String source, int _radix, int handleError(String source)) {
77 checkString(source);
78 var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i'); 77 var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
79 var/*=JSArray<String>*/ match = 78 var/*=JSArray<String>*/ match =
80 JS('JSExtendableArray|Null', '#.exec(#)', re, source); 79 JS('JSExtendableArray|Null', '#.exec(#)', re, source);
81 int digitsIndex = 1; 80 int digitsIndex = 1;
82 int hexIndex = 2; 81 int hexIndex = 2;
83 int decimalIndex = 3; 82 int decimalIndex = 3;
84 int nonDecimalHexIndex = 4; 83 int nonDecimalHexIndex = 4;
85 if (match == null) { 84 if (match == null) {
86 // TODO(sra): It might be that the match failed due to unrecognized U+0085 85 // TODO(sra): It might be that the match failed due to unrecognized U+0085
87 // spaces. We could replace them with U+0020 spaces and try matching 86 // spaces. We could replace them with U+0020 spaces and try matching
88 // again. 87 // again.
89 return _parseIntError(source, handleError); 88 return _parseIntError(source, handleError);
90 } 89 }
91 String decimalMatch = match[decimalIndex]; 90 String decimalMatch = match[decimalIndex];
92 if (radix == null) { 91 if (_radix == null) {
93 if (decimalMatch != null) { 92 if (decimalMatch != null) {
94 // Cannot fail because we know that the digits are all decimal. 93 // Cannot fail because we know that the digits are all decimal.
95 return JS('int', r'parseInt(#, 10)', source); 94 return JS('int', r'parseInt(#, 10)', source);
96 } 95 }
97 if (match[hexIndex] != null) { 96 if (match[hexIndex] != null) {
98 // Cannot fail because we know that the digits are all hex. 97 // Cannot fail because we know that the digits are all hex.
99 return JS('int', r'parseInt(#, 16)', source); 98 return JS('int', r'parseInt(#, 16)', source);
100 } 99 }
101 return _parseIntError(source, handleError); 100 return _parseIntError(source, handleError);
102 } 101 }
103 102 @notNull var radix = _radix;
104 if (radix is! int) {
105 throw new ArgumentError.value(radix, 'radix', 'is not an integer');
106 }
107 if (radix < 2 || radix > 36) { 103 if (radix < 2 || radix > 36) {
108 throw new RangeError.range(radix, 2, 36, 'radix'); 104 throw new RangeError.range(radix, 2, 36, 'radix');
109 } 105 }
110 if (radix == 10 && decimalMatch != null) { 106 if (radix == 10 && decimalMatch != null) {
111 // Cannot fail because we know that the digits are all decimal. 107 // Cannot fail because we know that the digits are all decimal.
112 return JS('int', r'parseInt(#, 10)', source); 108 return JS('int', r'parseInt(#, 10)', source);
113 } 109 }
114 // If radix >= 10 and we have only decimal digits the string is safe. 110 // If radix >= 10 and we have only decimal digits the string is safe.
115 // Otherwise we need to check the digits. 111 // Otherwise we need to check the digits.
116 if (radix < 10 || decimalMatch == null) { 112 if (radix < 10 || decimalMatch == null) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 144
149 @NoInline() 145 @NoInline()
150 static double _parseDoubleError( 146 static double _parseDoubleError(
151 String source, double handleError(String source)) { 147 String source, double handleError(String source)) {
152 if (handleError == null) { 148 if (handleError == null) {
153 throw new FormatException('Invalid double', source); 149 throw new FormatException('Invalid double', source);
154 } 150 }
155 return handleError(source); 151 return handleError(source);
156 } 152 }
157 153
158 static double parseDouble(String source, double handleError(String source)) { 154 static double parseDouble(@nullCheck String source, double handleError(String source)) {
159 checkString(source);
160 // Notice that JS parseFloat accepts garbage at the end of the string. 155 // Notice that JS parseFloat accepts garbage at the end of the string.
161 // Accept only: 156 // Accept only:
162 // - [+/-]NaN 157 // - [+/-]NaN
163 // - [+/-]Infinity 158 // - [+/-]Infinity
164 // - a Dart double literal 159 // - a Dart double literal
165 // We do allow leading or trailing whitespace. 160 // We do allow leading or trailing whitespace.
166 if (!JS( 161 if (!JS(
167 'bool', 162 'bool',
168 r'/^\s*[+-]?(?:Infinity|NaN|' 163 r'/^\s*[+-]?(?:Infinity|NaN|'
169 r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)', 164 r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 // In a browser return self.location.href. 220 // In a browser return self.location.href.
226 if (JS('bool', '!!self.location')) { 221 if (JS('bool', '!!self.location')) {
227 return JS('String', 'self.location.href'); 222 return JS('String', 'self.location.href');
228 } 223 }
229 224
230 return null; 225 return null;
231 } 226 }
232 227
233 // This is to avoid stack overflows due to very large argument arrays in 228 // This is to avoid stack overflows due to very large argument arrays in
234 // apply(). It fixes http://dartbug.com/6919 229 // apply(). It fixes http://dartbug.com/6919
235 static String _fromCharCodeApply(List<int> array) { 230 @notNull static String _fromCharCodeApply(List<int> array) {
236 const kMaxApply = 500; 231 const kMaxApply = 500;
237 int end = array.length; 232 @nullCheck int end = array.length;
238 if (end <= kMaxApply) { 233 if (end <= kMaxApply) {
239 return JS('String', r'String.fromCharCode.apply(null, #)', array); 234 return JS('String', r'String.fromCharCode.apply(null, #)', array);
240 } 235 }
241 String result = ''; 236 String result = '';
242 for (int i = 0; i < end; i += kMaxApply) { 237 for (int i = 0; i < end; i += kMaxApply) {
243 int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; 238 int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
244 result = JS( 239 result = JS(
245 'String', 240 'String',
246 r'# + String.fromCharCode.apply(null, #.slice(#, #))', 241 r'# + String.fromCharCode.apply(null, #.slice(#, #))',
247 result, 242 result,
248 array, 243 array,
249 i, 244 i,
250 chunkEnd); 245 chunkEnd);
251 } 246 }
252 return result; 247 return result;
253 } 248 }
254 249
255 static String stringFromCodePoints(/*=JSArray<int>*/ codePoints) { 250 @notNull static String stringFromCodePoints(JSArray<int> codePoints) {
256 List<int> a = <int>[]; 251 List<int> a = <int>[];
257 for (var i in codePoints) { 252 for (@nullCheck var i in codePoints) {
258 if (i is! int) throw argumentErrorValue(i);
259 if (i <= 0xffff) { 253 if (i <= 0xffff) {
260 a.add(i); 254 a.add(i);
261 } else if (i <= 0x10ffff) { 255 } else if (i <= 0x10ffff) {
262 a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff))); 256 a.add(0xd800 + ((((i - 0x10000) >> 10) & 0x3ff)));
263 a.add(0xdc00 + (i & 0x3ff)); 257 a.add(0xdc00 + (i & 0x3ff));
264 } else { 258 } else {
265 throw argumentErrorValue(i); 259 throw argumentErrorValue(i);
266 } 260 }
267 } 261 }
268 return _fromCharCodeApply(a); 262 return _fromCharCodeApply(a);
269 } 263 }
270 264
271 static String stringFromCharCodes(/*=JSArray<int>*/ charCodes) { 265 @notNull static String stringFromCharCodes(JSArray<int> charCodes) {
272 for (var i in charCodes) { 266 for (@nullCheck var i in charCodes) {
273 if (i is! int) throw argumentErrorValue(i);
274 if (i < 0) throw argumentErrorValue(i); 267 if (i < 0) throw argumentErrorValue(i);
275 if (i > 0xffff) return stringFromCodePoints(charCodes); 268 if (i > 0xffff) return stringFromCodePoints(charCodes);
276 } 269 }
277 return _fromCharCodeApply(charCodes); 270 return _fromCharCodeApply(charCodes);
278 } 271 }
279 272
280 // [start] and [end] are validated. 273 // [start] and [end] are validated.
281 static String stringFromNativeUint8List( 274 @notNull static String stringFromNativeUint8List(
282 NativeUint8List charCodes, int start, int end) { 275 NativeUint8List charCodes, @nullCheck int start, @nullCheck int end) {
283 const kMaxApply = 500; 276 const kMaxApply = 500;
284 if (end <= kMaxApply && start == 0 && end == charCodes.length) { 277 if (end <= kMaxApply && start == 0 && end == charCodes.length) {
285 return JS('String', r'String.fromCharCode.apply(null, #)', charCodes); 278 return JS('String', r'String.fromCharCode.apply(null, #)', charCodes);
286 } 279 }
287 String result = ''; 280 String result = '';
288 for (int i = start; i < end; i += kMaxApply) { 281 for (int i = start; i < end; i += kMaxApply) {
289 int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end; 282 int chunkEnd = (i + kMaxApply < end) ? i + kMaxApply : end;
290 result = JS( 283 result = JS(
291 'String', 284 'String',
292 r'# + String.fromCharCode.apply(null, #.subarray(#, #))', 285 r'# + String.fromCharCode.apply(null, #.subarray(#, #))',
293 result, 286 result,
294 charCodes, 287 charCodes,
295 i, 288 i,
296 chunkEnd); 289 chunkEnd);
297 } 290 }
298 return result; 291 return result;
299 } 292 }
300 293
301 static String stringFromCharCode(int charCode) { 294 @notNull static String stringFromCharCode(@nullCheck int charCode) {
302 if (0 <= charCode) { 295 if (0 <= charCode) {
303 if (charCode <= 0xffff) { 296 if (charCode <= 0xffff) {
304 return JS('String', 'String.fromCharCode(#)', charCode); 297 return JS('String', 'String.fromCharCode(#)', charCode);
305 } 298 }
306 if (charCode <= 0x10ffff) { 299 if (charCode <= 0x10ffff) {
307 var bits = charCode - 0x10000; 300 var bits = charCode - 0x10000;
308 var low = 0xDC00 | (bits & 0x3ff); 301 var low = 0xDC00 | (bits & 0x3ff);
309 var high = 0xD800 | (bits >> 10); 302 var high = 0xD800 | (bits >> 10);
310 return JS('String', 'String.fromCharCode(#, #)', high, low); 303 return JS('String', 'String.fromCharCode(#, #)', high, low);
311 } 304 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d); 347 match = JS('JSArray|Null', r'/(?:GMT|UTC)[+-]\d{4}/.exec(#.toString())', d);
355 if (match != null) return match[0]; 348 if (match != null) return match[0];
356 return ""; 349 return "";
357 } 350 }
358 351
359 static int getTimeZoneOffsetInMinutes(DateTime receiver) { 352 static int getTimeZoneOffsetInMinutes(DateTime receiver) {
360 // Note that JS and Dart disagree on the sign of the offset. 353 // Note that JS and Dart disagree on the sign of the offset.
361 return -JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver)); 354 return -JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
362 } 355 }
363 356
364 static num valueFromDecomposedDate(int years, int month, int day, int hours, 357 static num valueFromDecomposedDate(@nullCheck int years, @nullCheck int month,
365 int minutes, int seconds, int milliseconds, bool isUtc) { 358 @nullCheck int day, @nullCheck int hours,
359 @nullCheck int minutes, @nullCheck int seconds, @nullCheck int millisecond s,
360 @nullCheck bool isUtc) {
366 final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000; 361 final int MAX_MILLISECONDS_SINCE_EPOCH = 8640000000000000;
367 checkInt(years);
368 checkInt(month);
369 checkInt(day);
370 checkInt(hours);
371 checkInt(minutes);
372 checkInt(seconds);
373 checkInt(milliseconds);
374 checkBool(isUtc);
375 var jsMonth = month - 1; 362 var jsMonth = month - 1;
376 num value; 363 num value;
377 if (isUtc) { 364 if (isUtc) {
378 value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day, 365 value = JS('num', r'Date.UTC(#, #, #, #, #, #, #)', years, jsMonth, day,
379 hours, minutes, seconds, milliseconds); 366 hours, minutes, seconds, milliseconds);
380 } else { 367 } else {
381 value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years, 368 value = JS('num', r'new Date(#, #, #, #, #, #, #).valueOf()', years,
382 jsMonth, day, hours, minutes, seconds, milliseconds); 369 jsMonth, day, hours, minutes, seconds, milliseconds);
383 } 370 }
384 if (value.isNaN || 371 if (value.isNaN ||
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 473
487 static StackTrace extractStackTrace(Error error) => 474 static StackTrace extractStackTrace(Error error) =>
488 getTraceFromException(error); 475 getTraceFromException(error);
489 } 476 }
490 477
491 /** 478 /**
492 * Diagnoses an indexing error. Returns the ArgumentError or RangeError that 479 * Diagnoses an indexing error. Returns the ArgumentError or RangeError that
493 * describes the problem. 480 * describes the problem.
494 */ 481 */
495 @NoInline() 482 @NoInline()
496 Error diagnoseIndexError(indexable, index) { 483 Error diagnoseIndexError(indexable, int index) {
497 if (index is! int) return new ArgumentError.value(index, 'index');
498 int length = indexable.length; 484 int length = indexable.length;
499 // The following returns the same error that would be thrown by calling 485 // The following returns the same error that would be thrown by calling
500 // [RangeError.checkValidIndex] with no optional parameters provided. 486 // [RangeError.checkValidIndex] with no optional parameters provided.
501 if (index < 0 || index >= length) { 487 if (index < 0 || index >= length) {
502 return new RangeError.index(index, indexable, 'index', null, length); 488 return new RangeError.index(index, indexable, 'index', null, length);
503 } 489 }
504 // The above should always match, but if it does not, use the following. 490 // The above should always match, but if it does not, use the following.
505 return new RangeError.value(index, 'index'); 491 return new RangeError.value(index, 'index');
506 } 492 }
507 493
508 /** 494 /**
509 * Diagnoses a range error. Returns the ArgumentError or RangeError that 495 * Diagnoses a range error. Returns the ArgumentError or RangeError that
510 * describes the problem. 496 * describes the problem.
511 */ 497 */
512 @NoInline() 498 @NoInline()
513 Error diagnoseRangeError(start, end, length) { 499 Error diagnoseRangeError(int start, int end, int length) {
514 if (start is! int) { 500 if (start == null) {
515 return new ArgumentError.value(start, 'start'); 501 return new ArgumentError.value(start, 'start');
516 } 502 }
517 if (start < 0 || start > length) { 503 if (start < 0 || start > length) {
518 return new RangeError.range(start, 0, length, 'start'); 504 return new RangeError.range(start, 0, length, 'start');
519 } 505 }
520 if (end != null) { 506 if (end != null) {
521 if (end is! int) {
522 return new ArgumentError.value(end, 'end');
523 }
524 if (end < start || end > length) { 507 if (end < start || end > length) {
525 return new RangeError.range(end, start, length, 'end'); 508 return new RangeError.range(end, start, length, 'end');
526 } 509 }
527 } 510 }
528 // The above should always match, but if it does not, use the following. 511 // The above should always match, but if it does not, use the following.
529 return new ArgumentError.value(end, "end"); 512 return new ArgumentError.value(end, "end");
530 } 513 }
531 514
532 stringLastIndexOfUnchecked(receiver, element, start) => 515 @notNull int stringLastIndexOfUnchecked(receiver, element, start) =>
533 JS('int', r'#.lastIndexOf(#, #)', receiver, element, start); 516 JS('int', r'#.lastIndexOf(#, #)', receiver, element, start);
534 517
535 /// 'factory' for constructing ArgumentError.value to keep the call sites small. 518 /// 'factory' for constructing ArgumentError.value to keep the call sites small.
536 @NoInline() 519 @NoInline()
537 ArgumentError argumentErrorValue(object) { 520 ArgumentError argumentErrorValue(object) {
538 return new ArgumentError.value(object); 521 return new ArgumentError.value(object);
539 } 522 }
540 523
541 checkNull(object) { 524 void throwArgumentErrorValue(value) {
542 if (object == null) throw argumentErrorValue(object); 525 throw argumentErrorValue(value);
543 return object;
544 }
545
546 checkNum(value) {
547 if (value is! num) throw argumentErrorValue(value);
548 return value;
549 } 526 }
550 527
551 checkInt(value) { 528 checkInt(value) {
552 if (value is! int) throw argumentErrorValue(value); 529 if (value is! int) throw argumentErrorValue(value);
553 return value; 530 return value;
554 } 531 }
555 532
556 checkBool(value) {
557 if (value is! bool) throw argumentErrorValue(value);
558 return value;
559 }
560
561 checkString(value) {
562 if (value is! String) throw argumentErrorValue(value);
563 return value;
564 }
565
566 throwRuntimeError(message) { 533 throwRuntimeError(message) {
567 throw new RuntimeError(message); 534 throw new RuntimeError(message);
568 } 535 }
569 536
570 throwAbstractClassInstantiationError(className) { 537 throwAbstractClassInstantiationError(className) {
571 throw new AbstractClassInstantiationError(className); 538 throw new AbstractClassInstantiationError(className);
572 } 539 }
573 540
574 @NoInline() 541 @NoInline()
575 throwConcurrentModificationError(collection) { 542 throwConcurrentModificationError(collection) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 if (dart.polyfill(object)) { 881 if (dart.polyfill(object)) {
915 dart.applyAllExtensions(object); 882 dart.applyAllExtensions(object);
916 } 883 }
917 } catch (e) { 884 } catch (e) {
918 // This may fail due to cross-origin errors. In that case, we shouldn't 885 // This may fail due to cross-origin errors. In that case, we shouldn't
919 // need to polyfill as we can't get objects from that frame. 886 // need to polyfill as we can't get objects from that frame.
920 887
921 // TODO(vsm): Detect this more robustly - ideally before we try to polyfill. 888 // TODO(vsm): Detect this more robustly - ideally before we try to polyfill.
922 } 889 }
923 } 890 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698