OLD | NEW |
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 part of _interceptors; | 5 part of _interceptors; |
6 | 6 |
7 /** | 7 /** |
8 * The interceptor class for [List]. The compiler recognizes this | 8 * The interceptor class for [List]. The compiler recognizes this |
9 * class as an interceptor, and changes references to [:this:] to | 9 * class as an interceptor, and changes references to [:this:] to |
10 * actually use the receiver of the method, which is generated as an extra | 10 * actually use the receiver of the method, which is generated as an extra |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
598 * 'isGrowable' and 'isMutable' checks into the getInterceptor implementation so | 598 * 'isGrowable' and 'isMutable' checks into the getInterceptor implementation so |
599 * these classes can have specialized implementations. Doing so will challenge | 599 * these classes can have specialized implementations. Doing so will challenge |
600 * many assuptions in the JS backend. | 600 * many assuptions in the JS backend. |
601 */ | 601 */ |
602 class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {} | 602 class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {} |
603 class JSFixedArray<E> extends JSMutableArray<E> {} | 603 class JSFixedArray<E> extends JSMutableArray<E> {} |
604 class JSExtendableArray<E> extends JSMutableArray<E> {} | 604 class JSExtendableArray<E> extends JSMutableArray<E> {} |
605 | 605 |
606 | 606 |
607 /// An [Iterator] that iterates a JSArray. | 607 /// An [Iterator] that iterates a JSArray. |
608 /// | |
609 class ArrayIterator<E> implements Iterator<E> { | 608 class ArrayIterator<E> implements Iterator<E> { |
610 final JSArray<E> _iterable; | 609 final JSArray<E> _iterable; |
611 final int _length; | 610 final int _originalLength; |
612 int _index; | 611 int _index; |
613 E _current; | 612 E _current; |
614 | 613 |
615 ArrayIterator(JSArray<E> iterable) | 614 ArrayIterator(JSArray<E> iterable) |
616 : _iterable = iterable, _length = iterable.length, _index = 0; | 615 : _iterable = iterable, _originalLength = iterable.length, _index = 0; |
617 | 616 |
618 E get current => _current; | 617 E get current => _current; |
619 | 618 |
620 bool moveNext() { | 619 bool moveNext() { |
621 int length = _iterable.length; | 620 // Check for concurrent modifiction at each step in checked mode. |
622 | 621 assert((_originalLength == _iterable.length) || |
623 // We have to do the length check even on fixed length Arrays. If we can | 622 (throw new ConcurrentModificationError(_iterable))); |
624 // inline moveNext() we might be able to GVN the length and eliminate this | 623 if (_index < _iterable.length) { |
625 // check on known fixed length JSArray. | 624 _current = _iterable.elementAt(_index); |
626 if (_length != length) { | 625 _index++; |
| 626 return true; |
| 627 } |
| 628 // Check for concurrent modification only at the end in production mode. |
| 629 if (_originalLength != _iterable.length) { |
627 throw new ConcurrentModificationError(_iterable); | 630 throw new ConcurrentModificationError(_iterable); |
628 } | 631 } |
629 | 632 _current = null; |
630 if (_index >= length) { | 633 return false; |
631 _current = null; | |
632 return false; | |
633 } | |
634 _current = _iterable[_index]; | |
635 _index++; | |
636 return true; | |
637 } | 634 } |
638 } | 635 } |
OLD | NEW |