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

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

Issue 1316673006: dart2js cps: Use TypeMaskSystem when inserting refinement nodes. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove unused ClassElement variable && rebase Created 5 years, 3 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 5ef491bd3195c94721de5189ef157bd044c059f2..d59a717da9dabbfcaed82bde628b410fb82f1682 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -30,248 +30,7 @@ import '../universe/universe.dart';
import '../world.dart' show World;
import 'cps_fragment.dart';
import 'cps_ir_nodes.dart';
-import 'cps_ir_nodes_sexpr.dart' show SExpressionStringifier;
-
-enum AbstractBool {
- True, False, Maybe, Nothing
-}
-
-class TypeMaskSystem {
- final TypesTask inferrer;
- final World classWorld;
- final JavaScriptBackend backend;
-
- TypeMask get dynamicType => inferrer.dynamicType;
- TypeMask get typeType => inferrer.typeType;
- TypeMask get functionType => inferrer.functionType;
- TypeMask get boolType => inferrer.boolType;
- TypeMask get intType => inferrer.intType;
- TypeMask get doubleType => inferrer.doubleType;
- TypeMask get numType => inferrer.numType;
- TypeMask get stringType => inferrer.stringType;
- TypeMask get listType => inferrer.listType;
- TypeMask get mapType => inferrer.mapType;
- TypeMask get nonNullType => inferrer.nonNullType;
- TypeMask get extendableNativeListType => backend.extendableArrayType;
-
- TypeMask numStringBoolType;
-
- ClassElement get jsNullClass => backend.jsNullClass;
-
- // TODO(karlklose): remove compiler here.
- TypeMaskSystem(dart2js.Compiler compiler)
- : inferrer = compiler.typesTask,
- classWorld = compiler.world,
- backend = compiler.backend {
-
- // Build the number+string+bool type. To make containment tests more
- // inclusive, we use the num, String, bool types for this, not
- // the JSNumber, JSString, JSBool subclasses.
- TypeMask anyNum =
- new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
- TypeMask anyString =
- new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
- TypeMask anyBool =
- new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
- numStringBoolType =
- new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
- classWorld);
- }
-
- bool methodUsesReceiverArgument(FunctionElement function) {
- assert(backend.isInterceptedMethod(function));
- ClassElement clazz = function.enclosingClass.declaration;
- return clazz.isSubclassOf(backend.jsInterceptorClass) ||
- classWorld.isUsedAsMixin(clazz);
- }
-
- Element locateSingleElement(TypeMask mask, Selector selector) {
- return mask.locateSingleElement(selector, mask, classWorld.compiler);
- }
-
- ClassElement singleClass(TypeMask mask) {
- return mask.singleClass(classWorld);
- }
-
- bool needsNoSuchMethodHandling(TypeMask mask, Selector selector) {
- return mask.needsNoSuchMethodHandling(selector, classWorld);
- }
-
- TypeMask getReceiverType(MethodElement method) {
- assert(method.isInstanceMember);
- if (classWorld.isUsedAsMixin(method.enclosingClass.declaration)) {
- // If used as a mixin, the receiver could be any of the classes that mix
- // in the class, and these are not considered subclasses.
- // TODO(asgerf): Exclude the subtypes that only `implement` the class.
- return nonNullSubtype(method.enclosingClass);
- } else {
- return nonNullSubclass(method.enclosingClass);
- }
- }
-
- TypeMask getParameterType(ParameterElement parameter) {
- return inferrer.getGuaranteedTypeOfElement(parameter);
- }
-
- TypeMask getReturnType(FunctionElement function) {
- return inferrer.getGuaranteedReturnTypeOfElement(function);
- }
-
- TypeMask getInvokeReturnType(Selector selector, TypeMask mask) {
- return inferrer.getGuaranteedTypeOfSelector(selector, mask);
- }
-
- TypeMask getFieldType(FieldElement field) {
- return inferrer.getGuaranteedTypeOfElement(field);
- }
-
- TypeMask join(TypeMask a, TypeMask b) {
- return a.union(b, classWorld);
- }
-
- TypeMask getTypeOf(ConstantValue constant) {
- return computeTypeMask(inferrer.compiler, constant);
- }
-
- TypeMask nonNullExact(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;
- return new TypeMask.nonNullExact(element.declaration, classWorld);
- }
-
- TypeMask nonNullSubclass(ClassElement element) {
- if (element.isClosure) return functionType;
- return new TypeMask.nonNullSubclass(element.declaration, classWorld);
- }
-
- TypeMask nonNullSubtype(ClassElement element) {
- if (element.isClosure) return functionType;
- return new TypeMask.nonNullSubtype(element.declaration, classWorld);
- }
-
- bool isDefinitelyBool(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().containsOnlyBool(classWorld);
- }
-
- bool isDefinitelyNum(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().containsOnlyNum(classWorld);
- }
-
- bool isDefinitelyString(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().containsOnlyString(classWorld);
- }
-
- bool isDefinitelyNumStringBool(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return numStringBoolType.containsMask(t.nonNullable(), classWorld);
- }
-
- bool isDefinitelyNotNumStringBool(TypeMask t) {
- return areDisjoint(t, numStringBoolType);
- }
-
- /// True if all values of [t] are either integers or not numbers at all.
- ///
- /// This does not imply that the value is an integer, since most other values
- /// such as null are also not a non-integer double.
- bool isDefinitelyNotNonIntegerDouble(TypeMask t) {
- // Even though int is a subclass of double in the JS type system, we can
- // still check this with disjointness, because [doubleType] is the *exact*
- // double class, so this excludes things that are known to be instances of a
- // more specific class.
- // We currently exploit that there are no subclasses of double that are
- // not integers (e.g. there is no UnsignedDouble class or whatever).
- return areDisjoint(t, doubleType);
- }
-
- bool isDefinitelyInt(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.satisfies(backend.jsIntClass, classWorld);
- }
-
- bool isDefinitelyNativeList(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsArrayClass, classWorld);
- }
-
- bool isDefinitelyMutableNativeList(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsMutableArrayClass, classWorld);
- }
-
- bool isDefinitelyFixedNativeList(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsFixedArrayClass, classWorld);
- }
-
- bool isDefinitelyExtendableNativeList(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsExtendableArrayClass,
- classWorld);
- }
-
- bool isDefinitelyIndexable(TypeMask t, {bool allowNull: false}) {
- if (!allowNull && t.isNullable) return false;
- return t.nonNullable().satisfies(backend.jsIndexableClass, classWorld);
- }
-
- bool areDisjoint(TypeMask leftType, TypeMask rightType) {
- TypeMask intersection = leftType.intersection(rightType, classWorld);
- return intersection.isEmpty && !intersection.isNullable;
- }
-
- AbstractBool isSubtypeOf(TypeMask value,
- types.DartType type,
- {bool allowNull}) {
- assert(allowNull != null);
- if (type is types.DynamicType) {
- return AbstractBool.True;
- }
- if (type is types.InterfaceType) {
- TypeMask typeAsMask = allowNull
- ? new TypeMask.subtype(type.element, classWorld)
- : new TypeMask.nonNullSubtype(type.element, classWorld);
- if (areDisjoint(value, typeAsMask)) {
- // Disprove the subtype relation based on the class alone.
- return AbstractBool.False;
- }
- if (!type.treatAsRaw) {
- // If there are type arguments, we cannot prove the subtype relation,
- // because the type arguments are unknown on both the value and type.
- return AbstractBool.Maybe;
- }
- if (typeAsMask.containsMask(value, classWorld)) {
- // All possible values are contained in the set of allowed values.
- // Note that we exploit the fact that [typeAsMask] is an exact
- // representation of [type], not an approximation.
- return AbstractBool.True;
- }
- // The value is neither contained in the type, nor disjoint from the type.
- return AbstractBool.Maybe;
- }
- // TODO(asgerf): Support function types, and what else might be missing.
- return AbstractBool.Maybe;
- }
-
- /// Returns whether [type] is one of the falsy values: false, 0, -0, NaN,
- /// the empty string, or null.
- AbstractBool boolify(TypeMask type) {
- if (isDefinitelyNotNumStringBool(type) && !type.isNullable) {
- return AbstractBool.True;
- }
- return AbstractBool.Maybe;
- }
-
- AbstractBool strictBoolify(TypeMask type) {
- if (areDisjoint(type, boolType)) return AbstractBool.False;
- return AbstractBool.Maybe;
- }
-}
+import 'type_mask_system.dart';
class ConstantPropagationLattice {
final TypeMaskSystem typeSystem;
@@ -575,17 +334,17 @@ class TypePropagator extends Pass {
final dart2js.Compiler _compiler;
final CpsFunctionCompiler _functionCompiler;
- // The constant system is used for evaluation of expressions with constant
- // arguments.
final ConstantPropagationLattice _lattice;
final dart2js.InternalErrorFunction _internalError;
final Map<Definition, AbstractValue> _values = <Definition, AbstractValue>{};
- TypePropagator(dart2js.Compiler compiler, this._functionCompiler)
+ TypePropagator(dart2js.Compiler compiler,
+ TypeMaskSystem typeSystem,
+ this._functionCompiler)
: _compiler = compiler,
_internalError = compiler.internalError,
_lattice = new ConstantPropagationLattice(
- new TypeMaskSystem(compiler),
+ typeSystem,
compiler.backend.constantSystem,
compiler.types);
@@ -2572,13 +2331,10 @@ class TypePropagationVisitor implements Visitor {
case AbstractBool.Maybe:
setReachable(cont);
- TypeMask type = input.type;
- if (node.type.element is ClassElement) {
- // Narrow type of output to those that survive the cast.
- type = type.intersection(
- new TypeMask.subtype(node.type.element, classWorld),
- classWorld);
- }
+ // Narrow type of output to those that survive the cast.
+ TypeMask type = input.type.intersection(
+ typeSystem.subtypesOf(node.type),
+ classWorld);
setValue(cont.parameters.single, nonConstant(type));
break;
}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/type_mask_system.dart ('k') | pkg/compiler/lib/src/js_backend/codegen/task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698