Chromium Code Reviews| Index: runtime/lib/typed_data.dart |
| diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart |
| index 376acb33bdc84a791d5644389e0dbfd48ffef9c9..a7910f83061463c845659e5d6d7dc9a98d34d6c8 100644 |
| --- a/runtime/lib/typed_data.dart |
| +++ b/runtime/lib/typed_data.dart |
| @@ -298,7 +298,7 @@ patch class Int32x4 { |
| patch class ByteData { |
| /* patch */ factory ByteData(int length) { |
| var list = new _Uint8Array(length); |
| - return new _ByteDataView(list.buffer, 0, length); |
| + return new _ByteDataView(list, 0, length); |
| } |
| /* patch */ factory ByteData.view(ByteBuffer buffer, |
| @@ -306,8 +306,13 @@ patch class ByteData { |
| if (length == null) { |
| length = buffer.lengthInBytes - offsetInBytes; |
| } |
| - return new _ByteDataView(buffer, offsetInBytes, length); |
| + _ByteBuffer internalBuffer = buffer; |
| + return new _ByteDataView(internalBuffer._typedData, offsetInBytes, length); |
| } |
| + |
| + // Called directly from C code. |
| + factory ByteData._view(TypedData typedData, int offsetInBytes, int length) |
| + => new _ByteDataView(typedData, offsetInBytes, length); |
| } |
| @@ -554,11 +559,14 @@ abstract class _TypedListBase { |
| if (needsClamping) { |
| Lists.copy(from, skipCount, this, start, count); |
| return; |
| - } else if (this.buffer._setRange( |
| - start * elementSizeInBytes + this.offsetInBytes, |
| - count * elementSizeInBytes, |
| - from.buffer, |
| - skipCount * elementSizeInBytes + from.offsetInBytes)) { |
| + } |
| + _ByteBuffer buffer = this.buffer; |
| + _ByteBuffer fromBuffer = from.buffer; |
| + if (buffer._typedData._setRange( |
| + start * elementSizeInBytes + this.offsetInBytes, |
| + count * elementSizeInBytes, |
| + fromBuffer._typedData, |
| + skipCount * elementSizeInBytes + from.offsetInBytes)) { |
| return; |
| } |
| } else if (from.buffer == this.buffer) { |
| @@ -607,7 +615,13 @@ abstract class _TypedListBase { |
| } |
| -abstract class _TypedList extends _TypedListBase implements ByteBuffer { |
| +abstract class _TypedList extends _TypedListBase { |
| + // The [buffer] getter should return the same value each time. |
| + // Store it here the first time it is created. |
| + // We don't want to store it on the object, since not all typed lists |
| + // have a buffer extracted. |
|
Søren Gjesse
2014/01/14 12:00:17
Is this just to save an instance variable? You are
Lasse Reichstein Nielsen
2014/01/14 12:19:17
Yes.
|
| + static var _buffers = new Expando(); |
| + |
| // Default method implementing parts of the TypedData interface. |
| int get offsetInBytes { |
| return 0; |
| @@ -618,7 +632,12 @@ abstract class _TypedList extends _TypedListBase implements ByteBuffer { |
| } |
| ByteBuffer get buffer { |
| - return this; |
| + _ByteBuffer buffer = _buffers[this]; |
| + if (buffer == null) { |
| + buffer = new _ByteBuffer(this); |
| + _buffers[this] = buffer; |
| + } |
| + return buffer; |
| } |
| // Methods implementing the collection interface. |
| @@ -2334,11 +2353,14 @@ class _TypedListIterator<E> implements Iterator<E> { |
| class _TypedListView extends _TypedListBase implements TypedData { |
| + final TypedData _typedData; |
| + final int offsetInBytes; |
| + final int length; |
| + |
| _TypedListView(ByteBuffer _buffer, int _offset, int _length) |
| - : _typedData = _buffer, // This assignment is type safe. |
| - offsetInBytes = _offset, |
| - length = _length { |
| - } |
| + : _typedData = (_buffer as _ByteBuffer)._typedData, |
| + offsetInBytes = _offset, |
| + length = _length; |
| // Method(s) implementing the TypedData interface. |
| @@ -2349,10 +2371,6 @@ class _TypedListView extends _TypedListBase implements TypedData { |
| ByteBuffer get buffer { |
| return _typedData.buffer; |
| } |
| - |
| - final TypedData _typedData; |
| - final int offsetInBytes; |
| - final int length; |
| } |
| @@ -3033,14 +3051,17 @@ class _Int32x4ArrayView extends _TypedListView implements Int32x4List { |
| class _ByteDataView implements ByteData { |
| - _ByteDataView(ByteBuffer _buffer, int _offsetInBytes, int _lengthInBytes) |
| - : _typedData = _buffer, // _buffer is guaranteed to be a TypedData here. |
| + final TypedData _typedData; |
| + final int _offset; |
| + final int length; |
| + |
| + _ByteDataView(TypedData typedData, int _offsetInBytes, int _lengthInBytes) |
| + : _typedData = typedData, |
| _offset = _offsetInBytes, |
| length = _lengthInBytes { |
| - _rangeCheck(_buffer.lengthInBytes, _offset, length); |
| + _rangeCheck(typedData.lengthInBytes, _offset, length); |
| } |
| - |
| // Method(s) implementing TypedData interface. |
| ByteBuffer get buffer { |
| @@ -3311,11 +3332,6 @@ class _ByteDataView implements ByteData { |
| native "ByteData_ToEndianFloat32"; |
| static double _toEndianFloat64(double host_value, bool little_endian) |
| native "ByteData_ToEndianFloat64"; |
| - |
| - |
| - final TypedData _typedData; |
| - final int _offset; |
| - final int length; |
| } |
| @@ -3407,3 +3423,18 @@ void _throwRangeError(int index, int length) { |
| String message = "$index must be in the range [0..$length)"; |
| throw new RangeError(message); |
| } |
| + |
| +/** |
| + * Internal implementation of [ByteBuffer]. |
| + */ |
| +class _ByteBuffer implements ByteBuffer { |
| + final _TypedList _typedData; |
| + |
| + _ByteBuffer(this._typedData); |
| + |
| + int get lengthInBytes => _typedData.lengthInBytes; |
| + |
| + int get hashCode => _typedData.hashCode; |
| + bool operator==(Object other) => |
| + other is _ByteBuffer && _typedData == other._typedData; |
| +} |