dart2js cps: More precise rewrite for indexables.
Strings were not sometimes not considered indexables because [subtype=String] is not reduced to [exact=JSString]. We now rewrite the index-set operator to direct access even when the receiver object is potentially null (but is otherwise a mutable indexable). BUG= R=sra@google.com Review URL: https://codereview.chromium.org/1420563002 .
This commit is contained in:
@@ -46,6 +46,8 @@ class TypeMaskSystem {
|
||||
TypeMask fixedLengthType;
|
||||
TypeMask interceptorType;
|
||||
|
||||
TypeMask _indexableTypeTest;
|
||||
|
||||
ClassElement get jsNullClass => backend.jsNullClass;
|
||||
|
||||
// TODO(karlklose): remove compiler here.
|
||||
@@ -71,8 +73,17 @@ class TypeMaskSystem {
|
||||
|
||||
TypeMask typedArray = nonNullSubclass(backend.typedArrayClass);
|
||||
fixedLengthType = new TypeMask.unionOf(
|
||||
<TypeMask>[stringType, backend.fixedArrayType, typedArray],
|
||||
classWorld);
|
||||
<TypeMask>[stringType, backend.fixedArrayType, typedArray],
|
||||
classWorld);
|
||||
|
||||
// Make a TypeMask containing Indexable and (redundantly) subtypes of
|
||||
// string because the type inference does not infer that all strings are
|
||||
// indexables.
|
||||
TypeMask indexable =
|
||||
new TypeMask.nonNullSubtype(backend.jsIndexableClass, classWorld);
|
||||
_indexableTypeTest = new TypeMask.unionOf(
|
||||
<TypeMask>[indexable, anyString],
|
||||
classWorld);
|
||||
}
|
||||
|
||||
bool methodUsesReceiverArgument(FunctionElement function) {
|
||||
@@ -256,7 +267,7 @@ class TypeMaskSystem {
|
||||
|
||||
bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
|
||||
if (!allowNull && t.isNullable) return false;
|
||||
return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld);
|
||||
return _indexableTypeTest.containsMask(t.nonNullable(), classWorld);
|
||||
}
|
||||
|
||||
bool isDefinitelyMutableIndexable(TypeMask t, {bool allowNull: false}) {
|
||||
|
||||
@@ -1238,8 +1238,8 @@ class TransformingVisitor extends DeepRecursiveVisitor {
|
||||
return true;
|
||||
|
||||
case '[]=':
|
||||
if (receiverValue.isNullable) return false;
|
||||
if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type)) {
|
||||
if (!typeSystem.isDefinitelyMutableIndexable(receiverValue.type,
|
||||
allowNull: true)) {
|
||||
return false;
|
||||
}
|
||||
Primitive index = getDartArgument(node, 0);
|
||||
|
||||
Reference in New Issue
Block a user