Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(369)

Unified Diff: pkg/compiler/lib/src/cps_ir/type_propagation.dart

Issue 1159643005: dart2js cps: Do not propagate impure expressions across null receiver. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Extra fix in type propagation Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/cps_ir/type_propagation.dart
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 87f9abeb58e426b238675eff6af539112b913ace..d8892fd01f24a1015571258cf8446673655001eb 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -28,15 +28,20 @@ abstract class TypeSystem<T> {
T get stringType;
T get listType;
T get mapType;
+ T get nonNullType;
T getReturnType(FunctionElement element);
T getSelectorReturnType(Selector selector);
T getParameterType(ParameterElement element);
+ T getFieldType(FieldElement element);
T join(T a, T b);
T typeOf(ConstantValue constant);
+ T exact(ClassElement element);
/// True if all values satisfying [type] are booleans (null is not a boolean).
bool isDefinitelyBool(T type);
+
+ bool isDefinitelyNotNull(T type);
}
class UnitTypeSystem implements TypeSystem<String> {
@@ -50,14 +55,19 @@ class UnitTypeSystem implements TypeSystem<String> {
get mapType => UNIT;
get stringType => UNIT;
get typeType => UNIT;
+ get nonNullType => UNIT;
getParameterType(_) => UNIT;
getReturnType(_) => UNIT;
getSelectorReturnType(_) => UNIT;
+ getFieldType(_) => UNIT;
join(a, b) => UNIT;
typeOf(_) => UNIT;
+ exact(_) => UNIT;
bool isDefinitelyBool(_) => false;
+
+ bool isDefinitelyNotNull(_) => false;
}
class TypeMaskSystem implements TypeSystem<TypeMask> {
@@ -72,6 +82,7 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
TypeMask get stringType => inferrer.stringType;
TypeMask get listType => inferrer.listType;
TypeMask get mapType => inferrer.mapType;
+ TypeMask get nonNullType => inferrer.nonNullType;
// TODO(karlklose): remove compiler here.
TypeMaskSystem(dart2js.Compiler compiler)
@@ -90,6 +101,10 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
return inferrer.getGuaranteedTypeOfSelector(selector);
}
+ TypeMask getFieldType(FieldElement field) {
+ return inferrer.getGuaranteedTypeOfElement(field);
+ }
+
@override
TypeMask join(TypeMask a, TypeMask b) {
return a.union(b, classWorld);
@@ -100,9 +115,19 @@ class TypeMaskSystem implements TypeSystem<TypeMask> {
return computeTypeMask(inferrer.compiler, constant);
}
+ TypeMask exact(ClassElement element) {
+ // The class world does not know about classes created by
+ // closure conversion, so just treat those as a subtypes of Function.
+ // TODO(asgerf): Maybe closure conversion should create a new ClassWorld?
+ if (element.isClosure) return functionType;
karlklose 2015/06/02 12:53:22 We could also create ForwardingTypeMasks that unde
+ return new TypeMask.exact(element, classWorld);
+ }
+
bool isDefinitelyBool(TypeMask t) {
return t.containsOnlyBool(classWorld) && !t.isNullable;
}
+
+ bool isDefinitelyNotNull(TypeMask t) => !t.isNullable;
}
/**
@@ -274,6 +299,8 @@ class _TransformingVisitor<T> extends RecursiveVisitor {
});
if (letPrim == null) {
+ _AbstractValue<T> receiver = getValue(node.receiver.definition);
+ node.receiverIsNotNull = receiver.isDefinitelyNotNull(typeSystem);
super.visitInvokeMethod(node);
} else {
visitLetPrim(letPrim);
@@ -453,7 +480,8 @@ class _TypePropagationVisitor<T> implements Visitor {
void visitFunctionDefinition(FunctionDefinition node) {
if (node.thisParameter != null) {
- setValue(node.thisParameter, nonConstant());
+ // TODO(asgerf): Use a more precise type for 'this'.
+ setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
}
node.parameters.forEach(visit);
setReachable(node.body);
@@ -596,7 +624,7 @@ class _TypePropagationVisitor<T> implements Visitor {
assert(cont.parameters.length == 1);
Parameter returnValue = cont.parameters[0];
- setValue(returnValue, nonConstant());
+ setValue(returnValue, nonConstant(typeSystem.getReturnType(node.target)));
}
void visitConcatenateStrings(ConcatenateStrings node) {
@@ -794,7 +822,11 @@ class _TypePropagationVisitor<T> implements Visitor {
}
void visitGetStatic(GetStatic node) {
- setValue(node, nonConstant());
+ if (node.element.isFunction) {
+ setValue(node, nonConstant(typeSystem.functionType));
+ } else {
+ setValue(node, nonConstant(typeSystem.getFieldType(node.element)));
+ }
}
void visitSetStatic(SetStatic node) {
@@ -807,7 +839,7 @@ class _TypePropagationVisitor<T> implements Visitor {
assert(cont.parameters.length == 1);
Parameter returnValue = cont.parameters[0];
- setValue(returnValue, nonConstant());
+ setValue(returnValue, nonConstant(typeSystem.getFieldType(node.element)));
}
void visitIsTrue(IsTrue node) {
@@ -841,12 +873,12 @@ class _TypePropagationVisitor<T> implements Visitor {
setReachable(node.input.definition);
_AbstractValue<T> value = getValue(node.input.definition);
if (!value.isNothing) {
- setValue(node, nonConstant());
+ setValue(node, nonConstant(typeSystem.nonNullType));
}
}
void visitGetField(GetField node) {
- setValue(node, nonConstant());
+ setValue(node, nonConstant(typeSystem.getFieldType(node.field)));
}
void visitSetField(SetField node) {
@@ -854,11 +886,11 @@ class _TypePropagationVisitor<T> implements Visitor {
}
void visitCreateBox(CreateBox node) {
- setValue(node, nonConstant());
+ setValue(node, nonConstant(typeSystem.nonNullType));
}
void visitCreateInstance(CreateInstance node) {
- setValue(node, nonConstant());
+ setValue(node, nonConstant(typeSystem.exact(node.classElement)));
}
void visitReifyRuntimeType(ReifyRuntimeType node) {
@@ -879,7 +911,8 @@ class _TypePropagationVisitor<T> implements Visitor {
}
void visitCreateInvocationMirror(CreateInvocationMirror node) {
- setValue(node, nonConstant());
+ // TODO(asgerf): Expose [Invocation] type.
+ setValue(node, nonConstant(typeSystem.nonNullType));
}
}
@@ -960,6 +993,13 @@ class _AbstractValue<T> {
if (kind == NOTHING) return true;
return typeSystem.isDefinitelyBool(type);
}
+
+ /// True if null is not a member of this value.
+ bool isDefinitelyNotNull(TypeSystem<T> typeSystem) {
+ if (kind == NOTHING) return true;
+ if (kind == CONSTANT) return !constant.isNull;
+ return typeSystem.isDefinitelyNotNull(type);
+ }
}
class ConstantExpressionCreator
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart ('k') | pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698