Chromium Code Reviews| Index: sdk/lib/typed_data/dart2js/typed_data_dart2js.dart |
| =================================================================== |
| --- sdk/lib/typed_data/dart2js/typed_data_dart2js.dart (revision 26873) |
| +++ sdk/lib/typed_data/dart2js/typed_data_dart2js.dart (working copy) |
| @@ -11,7 +11,7 @@ |
| import 'dart:collection'; |
| import 'dart:_collection-dev'; |
| import 'dart:_js_helper' show Creates, JavaScriptIndexingBehavior, JSName, Null, Returns; |
| -import 'dart:_foreign_helper' show JS; |
| +import 'dart:_foreign_helper' show JS, JS_CONST; |
| import 'dart:math' as Math; |
| /** |
| @@ -35,6 +35,14 @@ |
| final int lengthInBytes; |
| } |
| +// TODO(...): Remove this constant once V8 optimizes length access of |
| +// typed arrays. Firefox does not like accessing a named property of a |
| +// typed array, so we only use the new [:HACK:] property in V8. |
| +const fetchLength = const JS_CONST(''' |
| + typeof version == "function" && typeof system == "function" |
| + ? function(x) { return x.length; } |
| + : function(x) { return x.HACK; }; |
| +'''); |
| class TypedData native "ArrayBufferView" { |
| @Creates('ByteBuffer') |
| @@ -64,6 +72,12 @@ |
| } |
| } |
| + // TODO(...): Remove this method once V8 optimizes length access of |
|
bakster
2013/08/30 07:56:27
Please add an Issues for these todos.
It might be
ngeoffray
2013/08/30 08:51:34
Done.
|
| + // typed arrays. |
| + void _setHackLength() { |
| + JS('void', r'#.HACK = #.length', this, this); |
|
ahe
2013/08/30 08:08:47
Rename "HACK" to $dartCachedLength or something.
ngeoffray
2013/08/30 08:51:34
Done.
|
| + } |
| + |
| int _checkSublistArguments(int start, int end, int length) { |
| // For `sublist` the [start] and [end] indices are allowed to be equal to |
| // [length]. However, [_checkIndex] only allows incides in the range |
| @@ -197,13 +211,14 @@ |
| void setUint8(int byteOffset, int value) native; |
| static ByteData _create1(arg) => |
| - JS('ByteData', 'new DataView(new ArrayBuffer(#))', arg); |
| + JS('ByteData', 'new DataView(new ArrayBuffer(#))', arg).._setHackLength(); |
| static ByteData _create2(arg1, arg2) => |
| - JS('ByteData', 'new DataView(#, #)', arg1, arg2); |
| + JS('ByteData', 'new DataView(#, #)', arg1, arg2).._setHackLength(); |
| static ByteData _create3(arg1, arg2, arg3) => |
| - JS('ByteData', 'new DataView(#, #, #)', arg1, arg2, arg3); |
| + JS('ByteData', 'new DataView(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -224,7 +239,7 @@ |
| static const int BYTES_PER_ELEMENT = 4; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| num operator[](int index) { |
| _checkIndex(index, length); |
| @@ -239,17 +254,20 @@ |
| List<double> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| var source = JS('Float32List', '#.subarray(#, #)', this, start, end); |
| + source._setHackLength(); |
| return _create1(source); |
| } |
| static Float32List _create1(arg) => |
| - JS('Float32List', 'new Float32Array(#)', arg); |
| + JS('Float32List', 'new Float32Array(#)', arg).._setHackLength(); |
| static Float32List _create2(arg1, arg2) => |
| - JS('Float32List', 'new Float32Array(#, #)', arg1, arg2); |
| + JS('Float32List', 'new Float32Array(#, #)', arg1, arg2) |
| + .._setHackLength(); |
| static Float32List _create3(arg1, arg2, arg3) => |
| - JS('Float32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Float32List', 'new Float32Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -270,7 +288,7 @@ |
| static const int BYTES_PER_ELEMENT = 8; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| num operator[](int index) { |
| _checkIndex(index, length); |
| @@ -285,17 +303,23 @@ |
| List<double> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| var source = JS('Float64List', '#.subarray(#, #)', this, start, end); |
| + source._setHackLength(); |
| return _create1(source); |
| } |
| - static Float64List _create1(arg) => |
| - JS('Float64List', 'new Float64Array(#)', arg); |
| + static Float64List _create1(arg) { |
| + return JS('Float64List', 'new Float64Array(#)', arg).._setHackLength(); |
| + } |
| - static Float64List _create2(arg1, arg2) => |
| - JS('Float64List', 'new Float64Array(#, #)', arg1, arg2); |
| + static Float64List _create2(arg1, arg2) { |
| + return JS('Float64List', 'new Float64Array(#, #)', arg1, arg2) |
| + .._setHackLength(); |
| + } |
| - static Float64List _create3(arg1, arg2, arg3) => |
| - JS('Float64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3); |
| + static Float64List _create3(arg1, arg2, arg3) { |
| + return JS('Float64List', 'new Float64Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| + } |
| } |
| @@ -315,7 +339,7 @@ |
| static const int BYTES_PER_ELEMENT = 2; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -329,18 +353,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Int16List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Int16List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Int16List _create1(arg) => |
| - JS('Int16List', 'new Int16Array(#)', arg); |
| + JS('Int16List', 'new Int16Array(#)', arg).._setHackLength(); |
| static Int16List _create2(arg1, arg2) => |
| - JS('Int16List', 'new Int16Array(#, #)', arg1, arg2); |
| + JS('Int16List', 'new Int16Array(#, #)', arg1, arg2).._setHackLength(); |
| static Int16List _create3(arg1, arg2, arg3) => |
| - JS('Int16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Int16List', 'new Int16Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -360,7 +386,7 @@ |
| static const int BYTES_PER_ELEMENT = 4; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -374,18 +400,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Int32List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Int32List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Int32List _create1(arg) => |
| - JS('Int32List', 'new Int32Array(#)', arg); |
| + JS('Int32List', 'new Int32Array(#)', arg).._setHackLength(); |
| static Int32List _create2(arg1, arg2) => |
| - JS('Int32List', 'new Int32Array(#, #)', arg1, arg2); |
| + JS('Int32List', 'new Int32Array(#, #)', arg1, arg2).._setHackLength(); |
| static Int32List _create3(arg1, arg2, arg3) => |
| - JS('Int32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Int32List', 'new Int32Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -405,7 +433,7 @@ |
| static const int BYTES_PER_ELEMENT = 1; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -419,18 +447,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Int8List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Int8List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Int8List _create1(arg) => |
| - JS('Int8List', 'new Int8Array(#)', arg); |
| + JS('Int8List', 'new Int8Array(#)', arg).._setHackLength(); |
| static Int8List _create2(arg1, arg2) => |
| - JS('Int8List', 'new Int8Array(#, #)', arg1, arg2); |
| + JS('Int8List', 'new Int8Array(#, #)', arg1, arg2).._setHackLength(); |
| static Int8List _create3(arg1, arg2, arg3) => |
| - JS('Int8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Int8List', 'new Int8Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -451,7 +481,7 @@ |
| static const int BYTES_PER_ELEMENT = 2; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -465,18 +495,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Uint16List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Uint16List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Uint16List _create1(arg) => |
| - JS('Uint16List', 'new Uint16Array(#)', arg); |
| + JS('Uint16List', 'new Uint16Array(#)', arg).._setHackLength(); |
| static Uint16List _create2(arg1, arg2) => |
| - JS('Uint16List', 'new Uint16Array(#, #)', arg1, arg2); |
| + JS('Uint16List', 'new Uint16Array(#, #)', arg1, arg2).._setHackLength(); |
| static Uint16List _create3(arg1, arg2, arg3) => |
| - JS('Uint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Uint16List', 'new Uint16Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -497,7 +529,7 @@ |
| static const int BYTES_PER_ELEMENT = 4; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -511,18 +543,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Uint32List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Uint32List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Uint32List _create1(arg) => |
| - JS('Uint32List', 'new Uint32Array(#)', arg); |
| + JS('Uint32List', 'new Uint32Array(#)', arg).._setHackLength(); |
| static Uint32List _create2(arg1, arg2) => |
| - JS('Uint32List', 'new Uint32Array(#, #)', arg1, arg2); |
| + JS('Uint32List', 'new Uint32Array(#, #)', arg1, arg2).._setHackLength(); |
| static Uint32List _create3(arg1, arg2, arg3) => |
| - JS('Uint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Uint32List', 'new Uint32Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -556,18 +590,22 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Uint8ClampedList', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Uint8ClampedList', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Uint8ClampedList _create1(arg) => |
| - JS('Uint8ClampedList', 'new Uint8ClampedArray(#)', arg); |
| + JS('Uint8ClampedList', 'new Uint8ClampedArray(#)', arg) |
| + .._setHackLength(); |
| static Uint8ClampedList _create2(arg1, arg2) => |
| - JS('Uint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2); |
| + JS('Uint8ClampedList', 'new Uint8ClampedArray(#, #)', arg1, arg2) |
| + .._setHackLength(); |
| static Uint8ClampedList _create3(arg1, arg2, arg3) => |
| - JS('Uint8ClampedList', 'new Uint8ClampedArray(#, #, #)', arg1, arg2, arg3); |
| + JS('Uint8ClampedList', 'new Uint8ClampedArray(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |
| @@ -588,7 +626,7 @@ |
| static const int BYTES_PER_ELEMENT = 1; |
| - int get length => JS("int", "#.length", this); |
| + int get length => JS("int", '#(#)', fetchLength, this); |
| int operator[](int index) { |
| _checkIndex(index, length); |
| @@ -602,18 +640,20 @@ |
| List<int> sublist(int start, [int end]) { |
| end = _checkSublistArguments(start, end, length); |
| - var source = JS('Uint8List', '#.subarray(#, #)', this, start, end); |
| + var source = JS('Uint8List', '#.subarray(#, #)', this, start, end) |
| + .._setHackLength(); |
| return _create1(source); |
| } |
| static Uint8List _create1(arg) => |
| - JS('Uint8List', 'new Uint8Array(#)', arg); |
| + JS('Uint8List', 'new Uint8Array(#)', arg).._setHackLength(); |
| static Uint8List _create2(arg1, arg2) => |
| - JS('Uint8List', 'new Uint8Array(#, #)', arg1, arg2); |
| + JS('Uint8List', 'new Uint8Array(#, #)', arg1, arg2).._setHackLength(); |
| static Uint8List _create3(arg1, arg2, arg3) => |
| - JS('Uint8List', 'new Uint8Array(#, #, #)', arg1, arg2, arg3); |
| + JS('Uint8List', 'new Uint8Array(#, #, #)', arg1, arg2, arg3) |
| + .._setHackLength(); |
| } |