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

Side by Side Diff: frog/corejs.dart

Issue 9129023: adds array bounds checking (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merged Created 8 years, 11 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 | frog/frog_options.dart » ('j') | 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 /** 5 /**
6 * Generates JS helpers for dart:core. This used to be in a file "core.js". 6 * Generates JS helpers for dart:core. This used to be in a file "core.js".
7 * Having them in Dart code means we can easily control which are generated. 7 * Having them in Dart code means we can easily control which are generated.
8 */ 8 */
9 // TODO(jmesserly): one idea to make this cleaner: put these as private "native" 9 // TODO(jmesserly): one idea to make this cleaner: put these as private "native"
10 // methods somewhere in a library that we import. This would be rather elegant 10 // methods somewhere in a library that we import. This would be rather elegant
11 // because they'd get the right name collision behavior, conversions, 11 // because they'd get the right name collision behavior, conversions,
12 // include-if-used, etc for free. Not sure if it's worth doing that. 12 // include-if-used, etc for free. Not sure if it's worth doing that.
13 class CoreJs { 13 class CoreJs {
14 // These values track if the helper is actually used. If it is we generate it. 14 // These values track if the helper is actually used. If it is we generate it.
15 bool useThrow = false; 15 bool useThrow = false;
16 bool useAssert = false;
17 bool useNotNullBool = false; 16 bool useNotNullBool = false;
18 bool useIndex = false; 17 bool useIndex = false;
19 bool useSetIndex = false; 18 bool useSetIndex = false;
20 19
21 bool useWrap0 = false; 20 bool useWrap0 = false;
22 bool useWrap1 = false; 21 bool useWrap1 = false;
23 bool useIsolates = false; 22 bool useIsolates = false;
24 23
25 // These helpers had to switch to a new pattern, because they can be generated 24 // These helpers had to switch to a new pattern, because they can be generated
26 // after everything else. 25 // after everything else.
27 bool _generatedTypeNameOf = false; 26 bool _generatedTypeNameOf = false;
28 bool _generatedDynamicProto = false; 27 bool _generatedDynamicProto = false;
29 bool _generatedInherits = false; 28 bool _generatedInherits = false;
30 29
30
31 Map<String, String> _usedOperators; 31 Map<String, String> _usedOperators;
32 32
33 CodeWriter writer; 33 CodeWriter writer;
34 34
35 CoreJs(): _usedOperators = {}, writer = new CodeWriter(); 35 CoreJs(): _usedOperators = {}, writer = new CodeWriter();
36 36
37 /** 37 /**
38 * Generates the special operator method, e.g. $add. 38 * Generates the special operator method, e.g. $add.
39 * We want to do $add(x, y) instead of x.$add(y) so it doesn't box. 39 * We want to do $add(x, y) instead of x.$add(y) so it doesn't box.
40 * Same idea for the other methods. 40 * Same idea for the other methods.
(...skipping 18 matching lines...) Expand all
59 case ':negate': 59 case ':negate':
60 code = _NEGATE_FUNCTION; 60 code = _NEGATE_FUNCTION;
61 break; 61 break;
62 62
63 case ':add': 63 case ':add':
64 code = _ADD_FUNCTION; 64 code = _ADD_FUNCTION;
65 break; 65 break;
66 66
67 case ':truncdiv': 67 case ':truncdiv':
68 useThrow = true; 68 useThrow = true;
69 // TODO(jimhug): Only do this once!
70 world.gen.markTypeUsed(
71 world.corelib.types['IntegerDivisionByZeroException']);
69 code = _TRUNCDIV_FUNCTION; 72 code = _TRUNCDIV_FUNCTION;
70 break; 73 break;
71 74
72 case ':mod': 75 case ':mod':
73 code = _MOD_FUNCTION; 76 code = _MOD_FUNCTION;
74 break; 77 break;
75 78
76 default: 79 default:
77 // All of the other helpers are generated the same way 80 // All of the other helpers are generated the same way
78 var op = TokenKind.rawOperatorFromMethod(name); 81 var op = TokenKind.rawOperatorFromMethod(name);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (useNotNullBool) { 120 if (useNotNullBool) {
118 useThrow = true; 121 useThrow = true;
119 w.writeln(_NOTNULL_BOOL_FUNCTION); 122 w.writeln(_NOTNULL_BOOL_FUNCTION);
120 } 123 }
121 124
122 if (useThrow) { 125 if (useThrow) {
123 w.writeln(_THROW_FUNCTION); 126 w.writeln(_THROW_FUNCTION);
124 } 127 }
125 128
126 if (useIndex) { 129 if (useIndex) {
127 w.writeln(_INDEX_OPERATORS); 130 w.writeln(options.disableBoundsChecks ?
131 _INDEX_OPERATORS : _CHECKED_INDEX_OPERATORS);
128 } 132 }
129 133
130 if (useSetIndex) { 134 if (useSetIndex) {
131 w.writeln(_SETINDEX_OPERATORS); 135 w.writeln(options.disableBoundsChecks ?
136 _SETINDEX_OPERATORS : _CHECKED_SETINDEX_OPERATORS);
132 } 137 }
133 138
134 if (useIsolates) { 139 if (useIsolates) {
135 if (useWrap0) { 140 if (useWrap0) {
136 w.writeln(_WRAP_CALL0_FUNCTION); 141 w.writeln(_WRAP_CALL0_FUNCTION);
137 } 142 }
138 if (useWrap1) { 143 if (useWrap1) {
139 w.writeln(_WRAP_CALL1_FUNCTION); 144 w.writeln(_WRAP_CALL1_FUNCTION);
140 } 145 }
141 w.writeln(_ISOLATE_INIT_CODE); 146 w.writeln(_ISOLATE_INIT_CODE);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 /** Snippet for `$eq`. */ 184 /** Snippet for `$eq`. */
180 final String _EQ_FUNCTION = @""" 185 final String _EQ_FUNCTION = @"""
181 function $eq(x, y) { 186 function $eq(x, y) {
182 if (x == null) return y == null; 187 if (x == null) return y == null;
183 return (typeof(x) == 'number' && typeof(y) == 'number') || 188 return (typeof(x) == 'number' && typeof(y) == 'number') ||
184 (typeof(x) == 'boolean' && typeof(y) == 'boolean') || 189 (typeof(x) == 'boolean' && typeof(y) == 'boolean') ||
185 (typeof(x) == 'string' && typeof(y) == 'string') 190 (typeof(x) == 'string' && typeof(y) == 'string')
186 ? x == y : x.$eq(y); 191 ? x == y : x.$eq(y);
187 } 192 }
188 // TODO(jimhug): Should this or should it not match equals? 193 // TODO(jimhug): Should this or should it not match equals?
189 Object.defineProperty(Object.prototype, '$eq', { value: function(other) { 194 Object.defineProperty(Object.prototype, '$eq', { value: function(other) {
190 return this === other; 195 return this === other;
191 }, enumerable: false, writable: true, configurable: true });"""; 196 }, enumerable: false, writable: true, configurable: true });""";
192 197
193 /** Snippet for `$bit_not`. */ 198 /** Snippet for `$bit_not`. */
194 final String _BIT_NOT_FUNCTION = @""" 199 final String _BIT_NOT_FUNCTION = @"""
195 function $bit_not(x) { 200 function $bit_not(x) {
196 return (typeof(x) == 'number') ? ~x : x.$bit_not(); 201 return (typeof(x) == 'number') ? ~x : x.$bit_not();
197 }"""; 202 }""";
198 203
199 /** Snippet for `$negate`. */ 204 /** Snippet for `$negate`. */
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 if (entry.map.hasOwnProperty(tag)) { 280 if (entry.map.hasOwnProperty(tag)) {
276 method = methods[entry.tag]; 281 method = methods[entry.tag];
277 if (method) break; 282 if (method) break;
278 } 283 }
279 } 284 }
280 } 285 }
281 method = method || methods.Object; 286 method = method || methods.Object;
282 var proto = Object.getPrototypeOf(obj); 287 var proto = Object.getPrototypeOf(obj);
283 if (!proto.hasOwnProperty(name)) { 288 if (!proto.hasOwnProperty(name)) {
284 Object.defineProperty(proto, name, 289 Object.defineProperty(proto, name,
285 { value: method, enumerable: false, writable: true, 290 { value: method, enumerable: false, writable: true,
286 configurable: true }); 291 configurable: true });
287 } 292 }
288 293
289 return method.apply(this, Array.prototype.slice.call(arguments)); 294 return method.apply(this, Array.prototype.slice.call(arguments));
290 }; 295 };
291 $dynamicBind.methods = methods; 296 $dynamicBind.methods = methods;
292 Object.defineProperty(Object.prototype, name, { value: $dynamicBind, 297 Object.defineProperty(Object.prototype, name, { value: $dynamicBind,
293 enumerable: false, writable: true, configurable: true}); 298 enumerable: false, writable: true, configurable: true});
294 return methods; 299 return methods;
295 } 300 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // prototype. TODO(jmesserly): make this go away by handling index more 393 // prototype. TODO(jmesserly): make this go away by handling index more
389 // like a normal method. 394 // like a normal method.
390 final String _INDEX_OPERATORS = @""" 395 final String _INDEX_OPERATORS = @"""
391 Object.defineProperty(Object.prototype, '$index', { value: function(i) { 396 Object.defineProperty(Object.prototype, '$index', { value: function(i) {
392 var proto = Object.getPrototypeOf(this); 397 var proto = Object.getPrototypeOf(this);
393 if (proto !== Object) { 398 if (proto !== Object) {
394 proto.$index = function(i) { return this[i]; } 399 proto.$index = function(i) { return this[i]; }
395 } 400 }
396 return this[i]; 401 return this[i];
397 }, enumerable: false, writable: true, configurable: true}); 402 }, enumerable: false, writable: true, configurable: true});
398 Object.defineProperty(Array.prototype, '$index', { value: function(i) { 403 Object.defineProperty(Array.prototype, '$index', { value: function(i) {
399 return this[i]; 404 return this[i];
400 }, enumerable: false, writable: true, configurable: true}); 405 }, enumerable: false, writable: true, configurable: true});
401 Object.defineProperty(String.prototype, '$index', { value: function(i) { 406 Object.defineProperty(String.prototype, '$index', { value: function(i) {
402 return this[i]; 407 return this[i];
403 }, enumerable: false, writable: true, configurable: true});"""; 408 }, enumerable: false, writable: true, configurable: true});""";
404 409
410 final String _CHECKED_INDEX_OPERATORS = @"""
411 Object.defineProperty(Object.prototype, '$index', { value: function(i) {
412 var proto = Object.getPrototypeOf(this);
413 if (proto !== Object) {
414 proto.$index = function(i) { return this[i]; }
415 }
416 return this[i];
417 }, enumerable: false, writable: true, configurable: true});
418 Object.defineProperty(Array.prototype, '$index', { value: function(index) {
419 var i = index | 0;
420 if (i !== index) {
421 throw new IllegalArgumentException('index is not int');
422 } else if (i < 0 || i >= this.length) {
423 throw new IndexOutOfRangeException(index);
424 }
425 return this[i];
426 }, enumerable: false, writable: true, configurable: true});
427 Object.defineProperty(String.prototype, '$index', { value: function(i) {
428 return this[i];
429 }, enumerable: false, writable: true, configurable: true});""";
430
431
432
405 /** Snippet for `$setindex` in Object, Array, and String. */ 433 /** Snippet for `$setindex` in Object, Array, and String. */
406 // TODO(jimhug): Add array bounds checking in checked mode
407 /*
408 function $inlineArrayIndexCheck(array, index) {
409 if (index >= 0 && index < array.length) {
410 return index;
411 }
412 native__ArrayJsUtil__throwIndexOutOfRangeException(index);
413 }*/
414 final String _SETINDEX_OPERATORS = @""" 434 final String _SETINDEX_OPERATORS = @"""
415 Object.defineProperty(Object.prototype, '$setindex', { value: function(i, value) { 435 Object.defineProperty(Object.prototype, '$setindex', { value: function(i, value) {
416 var proto = Object.getPrototypeOf(this); 436 var proto = Object.getPrototypeOf(this);
417 if (proto !== Object) { 437 if (proto !== Object) {
418 proto.$setindex = function(i, value) { return this[i] = value; } 438 proto.$setindex = function(i, value) { return this[i] = value; }
419 } 439 }
420 return this[i] = value; 440 return this[i] = value;
421 }, enumerable: false, writable: true, configurable: true}); 441 }, enumerable: false, writable: true, configurable: true});
422 Object.defineProperty(Array.prototype, '$setindex', { value: function(i, value) { 442 Object.defineProperty(Array.prototype, '$setindex', { value: function(i, value) {
423 return this[i] = value; }, enumerable: false, writable: true, 443 return this[i] = value; }, enumerable: false, writable: true,
444 configurable: true});""";
445
446 final String _CHECKED_SETINDEX_OPERATORS = @"""
447 Object.defineProperty(Object.prototype, '$setindex', { value: function(i, value) {
448 var proto = Object.getPrototypeOf(this);
449 if (proto !== Object) {
450 proto.$setindex = function(i, value) { return this[i] = value; }
451 }
452 return this[i] = value;
453 }, enumerable: false, writable: true, configurable: true});
454 Object.defineProperty(Array.prototype, '$setindex', { value: function(index, val ue) {
455 var i = index | 0;
456 if (i !== index) {
457 throw new IllegalArgumentException('index is not int');
458 } else if (i < 0 || i >= this.length) {
459 throw new IndexOutOfRangeException(index);
460 }
461 return this[i] = value; }, enumerable: false, writable: true,
424 configurable: true});"""; 462 configurable: true});""";
425 463
426 /** Snippet for `$wrap_call$0`. */ 464 /** Snippet for `$wrap_call$0`. */
427 final String _WRAP_CALL0_FUNCTION = @""" 465 final String _WRAP_CALL0_FUNCTION = @"""
428 // Wrap a 0-arg dom-callback to bind it with the current isolate: 466 // Wrap a 0-arg dom-callback to bind it with the current isolate:
429 function $wrap_call$0(fn) { return fn && fn.wrap$call$0(); } 467 function $wrap_call$0(fn) { return fn && fn.wrap$call$0(); }
430 Function.prototype.wrap$call$0 = function() { 468 Function.prototype.wrap$call$0 = function() {
431 var isolateContext = $globalState.currentContext; 469 var isolateContext = $globalState.currentContext;
432 var self = this; 470 var self = this;
433 this.wrap$0 = function() { 471 this.wrap$0 = function() {
(...skipping 25 matching lines...) Expand all
459 497
460 /** Snippet for `$wrap_call$1`, in case it was not necessary. */ 498 /** Snippet for `$wrap_call$1`, in case it was not necessary. */
461 final String _EMPTY_WRAP_CALL1_FUNCTION = 499 final String _EMPTY_WRAP_CALL1_FUNCTION =
462 @"function $wrap_call$1(fn) { return fn; }"; 500 @"function $wrap_call$1(fn) { return fn; }";
463 501
464 /** Snippet that initializes the isolates state. */ 502 /** Snippet that initializes the isolates state. */
465 final String _ISOLATE_INIT_CODE = @""" 503 final String _ISOLATE_INIT_CODE = @"""
466 var $globalThis = this; 504 var $globalThis = this;
467 var $globals = null; 505 var $globals = null;
468 var $globalState = null;"""; 506 var $globalState = null;""";
OLDNEW
« no previous file with comments | « no previous file | frog/frog_options.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698