VM: Remove use of IterableMixinWorkaround from _List, _ImmutableList and _GrowableList.

_List, _ImmutableList and _GrowableList now extend ListBase which uses ListMixin.

Note that typed data lists are still using IterableMixinWorkaround for now.
They will be changed in a separate CL since it involves a few more changes
to the VM.

BUG=dartbug.com/13647
R=lrn@google.com

Review URL: https://codereview.chromium.org//730543002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42061 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
fschneider@google.com 2014-12-02 10:38:51 +00:00
parent d943cfb9e0
commit a49870e721
8 changed files with 11 additions and 471 deletions

View file

@ -4,7 +4,7 @@
// TODO(srdjan): Use shared array implementation.
class _List<E> implements List<E> {
class _List<E> extends FixedLengthListBase<E> {
factory _List(length) native "List_allocate";
@ -12,10 +12,6 @@ class _List<E> implements List<E> {
void operator []=(int index, E value) native "List_setIndexed";
String toString() {
return ListBase.listToString(this);
}
int get length native "List_getLength";
List _slice(int start, int count, bool needsTypeArgument) {
@ -34,38 +30,6 @@ class _List<E> implements List<E> {
List _sliceInternal(int start, int count, bool needsTypeArgument)
native "List_slice";
void insert(int index, E element) {
throw NonGrowableListError.add();
}
void insertAll(int index, Iterable<E> iterable) {
throw NonGrowableListError.add();
}
void setAll(int index, Iterable<E> iterable) {
IterableMixinWorkaround.setAllList(this, index, iterable);
}
E removeAt(int index) {
throw NonGrowableListError.remove();
}
bool remove(Object element) {
throw NonGrowableListError.remove();
}
void removeWhere(bool test(E element)) {
throw NonGrowableListError.remove();
}
void retainWhere(bool test(E element)) {
throw NonGrowableListError.remove();
}
Iterable<E> getRange(int start, [int end]) {
return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
}
// List interface.
void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
if (start < 0 || start > this.length) {
@ -95,18 +59,6 @@ class _List<E> implements List<E> {
}
}
void removeRange(int start, int end) {
throw NonGrowableListError.remove();
}
void replaceRange(int start, int end, Iterable<E> iterable) {
throw NonGrowableListError.remove();
}
void fillRange(int start, int end, [E fillValue]) {
IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
}
List<E> sublist(int start, [int end]) {
Lists.indicesCheck(this, start, end);
if (end == null) end = this.length;
@ -119,10 +71,6 @@ class _List<E> implements List<E> {
// Iterable interface.
bool contains(Object element) {
return IterableMixinWorkaround.contains(this, element);
}
void forEach(f(E element)) {
final length = this.length;
for (int i = 0; i < length; i++) {
@ -130,120 +78,10 @@ class _List<E> implements List<E> {
}
}
String join([String separator = ""]) {
return IterableMixinWorkaround.joinList(this, separator);
}
Iterable map(f(E element)) {
return IterableMixinWorkaround.mapList(this, f);
}
E reduce(E combine(E value, E element)) {
return IterableMixinWorkaround.reduce(this, combine);
}
fold(initialValue, combine(previousValue, E element)) {
return IterableMixinWorkaround.fold(this, initialValue, combine);
}
Iterable<E> where(bool f(E element)) {
return new IterableMixinWorkaround<E>().where(this, f);
}
Iterable expand(Iterable f(E element)) {
return IterableMixinWorkaround.expand(this, f);
}
Iterable<E> take(int n) {
return new IterableMixinWorkaround<E>().takeList(this, n);
}
Iterable<E> takeWhile(bool test(E value)) {
return new IterableMixinWorkaround<E>().takeWhile(this, test);
}
Iterable<E> skip(int n) {
return new IterableMixinWorkaround<E>().skipList(this, n);
}
Iterable<E> skipWhile(bool test(E value)) {
return new IterableMixinWorkaround<E>().skipWhile(this, test);
}
bool every(bool f(E element)) {
return IterableMixinWorkaround.every(this, f);
}
bool any(bool f(E element)) {
return IterableMixinWorkaround.any(this, f);
}
E firstWhere(bool test(E value), {E orElse()}) {
return IterableMixinWorkaround.firstWhere(this, test, orElse);
}
E lastWhere(bool test(E value), {E orElse()}) {
return IterableMixinWorkaround.lastWhereList(this, test, orElse);
}
E singleWhere(bool test(E value)) {
return IterableMixinWorkaround.singleWhere(this, test);
}
E elementAt(int index) {
return this[index];
}
bool get isEmpty {
return this.length == 0;
}
bool get isNotEmpty => !isEmpty;
Iterable<E> get reversed =>
new IterableMixinWorkaround<E>().reversedList(this);
void sort([int compare(E a, E b)]) {
IterableMixinWorkaround.sortList(this, compare);
}
void shuffle([Random random]) {
IterableMixinWorkaround.shuffleList(this, random);
}
int indexOf(Object element, [int start = 0]) {
return Lists.indexOf(this, element, start, this.length);
}
int lastIndexOf(Object element, [int start = null]) {
if (start == null) start = length - 1;
return Lists.lastIndexOf(this, element, start);
}
Iterator<E> get iterator {
return new _FixedSizeArrayIterator<E>(this);
}
void add(E element) {
throw NonGrowableListError.add();
}
void addAll(Iterable<E> iterable) {
throw NonGrowableListError.add();
}
void clear() {
throw NonGrowableListError.remove();
}
void set length(int length) {
throw NonGrowableListError.length();
}
E removeLast() {
throw NonGrowableListError.remove();
}
E get first {
if (length > 0) return this[0];
throw IterableElementError.noElement();
@ -273,14 +111,6 @@ class _List<E> implements List<E> {
// _GrowableList.withData must not be called with empty list.
return growable ? <E>[] : new List<E>(0);
}
Set<E> toSet() {
return new Set<E>.from(this);
}
Map<int, E> asMap() {
return new IterableMixinWorkaround<E>().asMapList(this);
}
}
@ -291,7 +121,7 @@ class _List<E> implements List<E> {
// classes (and inline cache misses) versus a field in the native
// implementation (checks when modifying). We should keep watching
// the inline cache misses.
class _ImmutableList<E> implements List<E> {
class _ImmutableList<E> extends UnmodifiableListBase<E> {
factory _ImmutableList._uninstantiable() {
throw new UnsupportedError(
@ -303,60 +133,8 @@ class _ImmutableList<E> implements List<E> {
E operator [](int index) native "List_getIndexed";
void operator []=(int index, E value) {
throw UnmodifiableListError.change();
}
int get length native "List_getLength";
void insert(int index, E element) {
throw UnmodifiableListError.add();
}
void insertAll(int index, Iterable<E> iterable) {
throw UnmodifiableListError.add();
}
void setAll(int index, Iterable<E> iterable) {
throw UnmodifiableListError.change();
}
E removeAt(int index) {
throw UnmodifiableListError.remove();
}
bool remove(Object element) {
throw UnmodifiableListError.remove();
}
void removeWhere(bool test(E element)) {
throw UnmodifiableListError.remove();
}
void retainWhere(bool test(E element)) {
throw UnmodifiableListError.remove();
}
void copyFrom(List src, int srcStart, int dstStart, int count) {
throw UnmodifiableListError.change();
}
void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
throw UnmodifiableListError.change();
}
void removeRange(int start, int end) {
throw UnmodifiableListError.remove();
}
void fillRange(int start, int end, [E fillValue]) {
throw UnmodifiableListError.change();
}
void replaceRange(int start, int end, Iterable<E> iterable) {
throw UnmodifiableListError.change();
}
List<E> sublist(int start, [int end]) {
Lists.indicesCheck(this, start, end);
if (end == null) end = this.length;
@ -371,16 +149,8 @@ class _ImmutableList<E> implements List<E> {
return result;
}
Iterable<E> getRange(int start, int end) {
return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
}
// Collection interface.
bool contains(Object element) {
return IterableMixinWorkaround.contains(this, element);
}
void forEach(f(E element)) {
final length = this.length;
for (int i = 0; i < length; i++) {
@ -388,124 +158,10 @@ class _ImmutableList<E> implements List<E> {
}
}
Iterable map(f(E element)) {
return IterableMixinWorkaround.mapList(this, f);
}
String join([String separator = ""]) {
return IterableMixinWorkaround.joinList(this, separator);
}
E reduce(E combine(E value, E element)) {
return IterableMixinWorkaround.reduce(this, combine);
}
fold(initialValue, combine(previousValue, E element)) {
return IterableMixinWorkaround.fold(this, initialValue, combine);
}
Iterable<E> where(bool f(E element)) {
return new IterableMixinWorkaround<E>().where(this, f);
}
Iterable expand(Iterable f(E element)) {
return IterableMixinWorkaround.expand(this, f);
}
Iterable<E> take(int n) {
return new IterableMixinWorkaround<E>().takeList(this, n);
}
Iterable<E> takeWhile(bool test(E value)) {
return new IterableMixinWorkaround<E>().takeWhile(this, test);
}
Iterable<E> skip(int n) {
return new IterableMixinWorkaround<E>().skipList(this, n);
}
Iterable<E> skipWhile(bool test(E value)) {
return new IterableMixinWorkaround<E>().skipWhile(this, test);
}
bool every(bool f(E element)) {
return IterableMixinWorkaround.every(this, f);
}
bool any(bool f(E element)) {
return IterableMixinWorkaround.any(this, f);
}
E firstWhere(bool test(E value), {E orElse()}) {
return IterableMixinWorkaround.firstWhere(this, test, orElse);
}
E lastWhere(bool test(E value), {E orElse()}) {
return IterableMixinWorkaround.lastWhereList(this, test, orElse);
}
E singleWhere(bool test(E value)) {
return IterableMixinWorkaround.singleWhere(this, test);
}
E elementAt(int index) {
return this[index];
}
bool get isEmpty {
return this.length == 0;
}
bool get isNotEmpty => !isEmpty;
Iterable<E> get reversed =>
new IterableMixinWorkaround<E>().reversedList(this);
void sort([int compare(E a, E b)]) {
throw UnmodifiableListError.change();
}
void shuffle([Random random]) {
throw UnmodifiableListError.change();
}
String toString() {
return ListBase.listToString(this);
}
int indexOf(Object element, [int start = 0]) {
return Lists.indexOf(this, element, start, this.length);
}
int lastIndexOf(Object element, [int start = null]) {
if (start == null) start = length - 1;
return Lists.lastIndexOf(this, element, start);
}
Iterator<E> get iterator {
return new _FixedSizeArrayIterator<E>(this);
}
void add(E element) {
throw UnmodifiableListError.add();
}
void addAll(Iterable<E> elements) {
throw UnmodifiableListError.add();
}
void clear() {
throw UnmodifiableListError.remove();
}
void set length(int length) {
throw UnmodifiableListError.length();
}
E removeLast() {
throw UnmodifiableListError.remove();
}
E get first {
if (length > 0) return this[0];
throw IterableElementError.noElement();
@ -536,14 +192,6 @@ class _ImmutableList<E> implements List<E> {
}
return growable ? <E>[] : new _List<E>(0);
}
Set<E> toSet() {
return new Set<E>.from(this);
}
Map<int, E> asMap() {
return new IterableMixinWorkaround<E>().asMapList(this);
}
}

View file

@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class _GrowableList<T> implements List<T> {
class _GrowableList<T> extends ListBase<T> {
void insert(int index, T element) {
if ((index < 0) || (index > length)) {
@ -67,37 +67,12 @@ class _GrowableList<T> implements List<T> {
}
}
void removeWhere(bool test(T element)) {
IterableMixinWorkaround.removeWhereList(this, test);
}
void retainWhere(bool test(T element)) {
IterableMixinWorkaround.removeWhereList(this,
(T element) => !test(element));
}
Iterable<T> getRange(int start, int end) {
return new IterableMixinWorkaround<T>().getRangeList(this, start, end);
}
void setRange(int start, int end, Iterable<T> iterable, [int skipCount = 0]) {
IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
}
void removeRange(int start, int end) {
Lists.indicesCheck(this, start, end);
Lists.copy(this, end, this, start, this.length - end);
this.length = this.length - (end - start);
}
void replaceRange(int start, int end, Iterable<T> iterable) {
IterableMixinWorkaround.replaceRangeList(this, start, end, iterable);
}
void fillRange(int start, int end, [T fillValue]) {
IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
}
List<T> sublist(int start, [int end]) {
Lists.indicesCheck(this, start, end);
if (end == null) end = this.length;
@ -226,14 +201,6 @@ class _GrowableList<T> implements List<T> {
throw IterableElementError.tooMany();;
}
int indexOf(Object element, [int start = 0]) {
return IterableMixinWorkaround.indexOfList(this, element, start);
}
int lastIndexOf(Object element, [int start = null]) {
return IterableMixinWorkaround.lastIndexOfList(this, element, start);
}
void _grow(int new_length) {
var new_data = new _List(new_length);
for (int i = 0; i < length; i++) {
@ -244,10 +211,6 @@ class _GrowableList<T> implements List<T> {
// Iterable interface.
bool contains(Object element) {
return IterableMixinWorkaround.contains(this, element);
}
void forEach(f(T element)) {
int initialLength = length;
for (int i = 0; i < length; i++) {
@ -324,62 +287,6 @@ class _GrowableList<T> implements List<T> {
return buffer.toString();
}
Iterable map(f(T element)) {
return IterableMixinWorkaround.mapList(this, f);
}
T reduce(T combine(T value, T element)) {
return IterableMixinWorkaround.reduce(this, combine);
}
fold(initialValue, combine(previousValue, T element)) {
return IterableMixinWorkaround.fold(this, initialValue, combine);
}
Iterable<T> where(bool f(T element)) {
return new IterableMixinWorkaround<T>().where(this, f);
}
Iterable expand(Iterable f(T element)) {
return IterableMixinWorkaround.expand(this, f);
}
Iterable<T> take(int n) {
return new IterableMixinWorkaround<T>().takeList(this, n);
}
Iterable<T> takeWhile(bool test(T value)) {
return new IterableMixinWorkaround<T>().takeWhile(this, test);
}
Iterable<T> skip(int n) {
return new IterableMixinWorkaround<T>().skipList(this, n);
}
Iterable<T> skipWhile(bool test(T value)) {
return new IterableMixinWorkaround<T>().skipWhile(this, test);
}
bool every(bool f(T element)) {
return IterableMixinWorkaround.every(this, f);
}
bool any(bool f(T element)) {
return IterableMixinWorkaround.any(this, f);
}
T firstWhere(bool test(T value), {T orElse()}) {
return IterableMixinWorkaround.firstWhere(this, test, orElse);
}
T lastWhere(bool test(T value), {T orElse()}) {
return IterableMixinWorkaround.lastWhereList(this, test, orElse);
}
T singleWhere(bool test(T value)) {
return IterableMixinWorkaround.singleWhere(this, test);
}
T elementAt(int index) {
return this[index];
}
@ -394,17 +301,6 @@ class _GrowableList<T> implements List<T> {
this.length = 0;
}
Iterable<T> get reversed =>
new IterableMixinWorkaround<T>().reversedList(this);
void sort([int compare(T a, T b)]) {
IterableMixinWorkaround.sortList(this, compare);
}
void shuffle([Random random]) {
IterableMixinWorkaround.shuffleList(this, random);
}
String toString() => ListBase.listToString(this);
Iterator<T> get iterator {
@ -429,8 +325,4 @@ class _GrowableList<T> implements List<T> {
Set<T> toSet() {
return new Set<T>.from(this);
}
Map<int, T> asMap() {
return new IterableMixinWorkaround<T>().asMapList(this);
}
}

View file

@ -2256,9 +2256,6 @@ TEST_CASE(Debug_ListSuperType) {
Dart_Handle list_type = Dart_InstanceGetType(list_access_test_obj);
Dart_Handle super_type = Dart_GetSupertype(list_type);
EXPECT(!Dart_IsError(super_type));
super_type = Dart_GetSupertype(super_type);
EXPECT(!Dart_IsError(super_type));
EXPECT(super_type == Dart_Null());
}
TEST_CASE(Debug_ScriptGetTokenInfo_Basic) {

View file

@ -37,6 +37,7 @@ RECOGNIZED_LIST(KIND_TO_STRING)
void MethodRecognizer::InitializeState() {
GrowableArray<Library*> libs(3);
libs.Add(&Library::ZoneHandle(Library::CoreLibrary()));
libs.Add(&Library::ZoneHandle(Library::CollectionLibrary()));
libs.Add(&Library::ZoneHandle(Library::MathLibrary()));
libs.Add(&Library::ZoneHandle(Library::TypedDataLibrary()));
libs.Add(&Library::ZoneHandle(Library::InternalLibrary()));

View file

@ -331,7 +331,7 @@ namespace dart {
V(_List, ., ObjectArrayAllocate, 335347617) \
V(_List, [], ObjectArrayGetIndexed, 390939163) \
V(_List, []=, ObjectArraySetIndexed, 1768442583) \
V(_List, get:isEmpty, ObjectArrayIsEmpty, 702383416) \
V(ListMixin, get:isEmpty, ListMixinIsEmpty, 2102252776) \
V(_List, get:iterator, ObjectArrayIterator, 308726049) \
V(_List, forEach, ObjectArrayForEach, 1720909126) \
V(_List, _slice, ObjectArraySlice, 1738717516) \

View file

@ -1021,7 +1021,6 @@ RawError* Object::Init(Isolate* isolate) {
// declared in RawArray.
cls.set_type_arguments_field_offset(Array::type_arguments_offset());
cls.set_num_type_arguments(1);
cls.set_num_own_type_arguments(1);
// Set up the growable object array class (Has to be done after the array
// class is setup as one of its field is an array object).
@ -1030,7 +1029,6 @@ RawError* Object::Init(Isolate* isolate) {
cls.set_type_arguments_field_offset(
GrowableObjectArray::type_arguments_offset());
cls.set_num_type_arguments(1);
cls.set_num_own_type_arguments(1);
// canonical_type_arguments_ are Smi terminated.
// Last element contains the count of used slots.
@ -1105,7 +1103,6 @@ RawError* Object::Init(Isolate* isolate) {
object_store->set_immutable_array_class(cls);
cls.set_type_arguments_field_offset(Array::type_arguments_offset());
cls.set_num_type_arguments(1);
cls.set_num_own_type_arguments(1);
ASSERT(object_store->immutable_array_class() != object_store->array_class());
cls.set_is_prefinalized();
RegisterPrivateClass(cls, Symbols::_ImmutableList(), core_lib);

View file

@ -322,7 +322,7 @@ abstract class ListMixin<E> implements List<E> {
}
Map<int, E> asMap() {
return new ListMapView(this);
return new ListMapView<E>(this);
}
List<E> sublist(int start, [int end]) {

View file

@ -16,6 +16,11 @@ checkImplements(object, String name) {
ClassMirror cls = reflect(object).type;
checkClassMirrorMethods(cls);
// The VM implements List via a mixin, so check for that.
if (cls.superinterfaces.isEmpty && object is List) {
cls = cls.superclass.superclass.mixin;
}
List<ClassMirror> superinterfaces = cls.superinterfaces;
String symName = 's($name)';
for (ClassMirror superinterface in superinterfaces) {