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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/type_mask_system.dart

Issue 1413613010: Normalize type masks to use the least upper instantiated subclass/type. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix try/poi Created 5 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/enqueue.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library dart2js.type_mask_system; 5 library dart2js.type_mask_system;
6 6
7 import '../common/names.dart' show Selectors, Identifiers; 7 import '../common/names.dart' show Selectors, Identifiers;
8 import '../compiler.dart' as dart2js show Compiler; 8 import '../compiler.dart' as dart2js show Compiler;
9 import '../constants/values.dart'; 9 import '../constants/values.dart';
10 import '../dart_types.dart' as types; 10 import '../dart_types.dart' as types;
11 import '../elements/elements.dart'; 11 import '../elements/elements.dart';
12 import '../js_backend/backend_helpers.dart' show BackendHelpers; 12 import '../js_backend/backend_helpers.dart' show BackendHelpers;
13 import '../js_backend/js_backend.dart' show JavaScriptBackend; 13 import '../js_backend/js_backend.dart' show JavaScriptBackend;
14 import '../types/types.dart'; 14 import '../types/types.dart';
15 import '../types/constants.dart' show computeTypeMask; 15 import '../types/constants.dart' show computeTypeMask;
16 import '../universe/selector.dart' show Selector; 16 import '../universe/selector.dart' show Selector;
17 import '../world.dart' show World; 17 import '../world.dart' show World;
18 18
19 enum AbstractBool { 19 enum AbstractBool {
20 True, False, Maybe, Nothing 20 True, False, Maybe, Nothing
21 } 21 }
22 22
23 class TypeMaskSystem { 23 class TypeMaskSystem {
24 final TypesTask inferrer; 24 final TypesTask inferrer;
25 final World classWorld; 25 final World classWorld;
26 final JavaScriptBackend backend; 26 final JavaScriptBackend backend;
27 27
28 TypeMask _numStringBoolType;
29 TypeMask _fixedLengthType;
30 TypeMask _interceptorType;
31 TypeMask _interceptedTypes; // Does not include null.
32
33 TypeMask __indexableTypeTest;
34
28 TypeMask get dynamicType => inferrer.dynamicType; 35 TypeMask get dynamicType => inferrer.dynamicType;
29 TypeMask get typeType => inferrer.typeType; 36 TypeMask get typeType => inferrer.typeType;
30 TypeMask get functionType => inferrer.functionType; 37 TypeMask get functionType => inferrer.functionType;
31 TypeMask get boolType => inferrer.boolType; 38 TypeMask get boolType => inferrer.boolType;
32 TypeMask get intType => inferrer.intType; 39 TypeMask get intType => inferrer.intType;
33 TypeMask get doubleType => inferrer.doubleType; 40 TypeMask get doubleType => inferrer.doubleType;
34 TypeMask get numType => inferrer.numType; 41 TypeMask get numType => inferrer.numType;
35 TypeMask get stringType => inferrer.stringType; 42 TypeMask get stringType => inferrer.stringType;
36 TypeMask get listType => inferrer.listType; 43 TypeMask get listType => inferrer.listType;
37 TypeMask get mapType => inferrer.mapType; 44 TypeMask get mapType => inferrer.mapType;
38 TypeMask get nonNullType => inferrer.nonNullType; 45 TypeMask get nonNullType => inferrer.nonNullType;
39 TypeMask get nullType => inferrer.nullType; 46 TypeMask get nullType => inferrer.nullType;
40 TypeMask get extendableNativeListType => backend.extendableArrayType; 47 TypeMask get extendableNativeListType => backend.extendableArrayType;
41 48
42 TypeMask get uint31Type => inferrer.uint31Type; 49 TypeMask get uint31Type => inferrer.uint31Type;
43 TypeMask get uint32Type => inferrer.uint32Type; 50 TypeMask get uint32Type => inferrer.uint32Type;
44 TypeMask get uintType => inferrer.positiveIntType; 51 TypeMask get uintType => inferrer.positiveIntType;
45 52
46 TypeMask numStringBoolType; 53 TypeMask get numStringBoolType {
47 TypeMask fixedLengthType; 54 if (_numStringBoolType == null) {
48 TypeMask interceptorType; 55 // Build the number+string+bool type. To make containment tests more
49 TypeMask interceptedTypes; // Does not include null. 56 // inclusive, we use the num, String, bool types for this, not
57 // the JSNumber, JSString, JSBool subclasses.
58 TypeMask anyNum =
59 new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
60 TypeMask anyString =
61 new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
62 TypeMask anyBool =
63 new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
64 _numStringBoolType =
65 new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
66 classWorld);
67 }
68 return _numStringBoolType;
69 }
50 70
51 TypeMask _indexableTypeTest; 71 TypeMask get fixedLengthType {
72 if (_fixedLengthType == null) {
73 List<TypeMask> fixedLengthTypes =
74 <TypeMask>[stringType, backend.fixedArrayType];
75 if (classWorld.isInstantiated(helpers.typedArrayClass)) {
76 fixedLengthTypes.add(nonNullSubclass(helpers.typedArrayClass));
77 }
78 _fixedLengthType = new TypeMask.unionOf(fixedLengthTypes, classWorld);
79 }
80 return _fixedLengthType;
81 }
82
83 TypeMask get interceptorType {
84 if (_interceptorType == null) {
85 _interceptorType =
86 new TypeMask.nonNullSubtype(helpers.jsInterceptorClass, classWorld);
87 }
88 return _interceptorType;
89 }
90
91 TypeMask get interceptedTypes { // Does not include null.
92 if (_interceptedTypes == null) {
93 // We redundantly include subtypes of num/string/bool as intercepted
94 // types, because the type system does not infer that their
95 // implementations are all subclasses of Interceptor.
96 _interceptedTypes = new TypeMask.unionOf(
97 <TypeMask>[interceptorType, numStringBoolType], classWorld);
98 }
99 return _interceptedTypes;
100 }
101
102 TypeMask get _indexableTypeTest {
103 if (__indexableTypeTest == null) {
104 // Make a TypeMask containing Indexable and (redundantly) subtypes of
105 // string because the type inference does not infer that all strings are
106 // indexables.
107 TypeMask indexable =
108 new TypeMask.nonNullSubtype(helpers.jsIndexableClass, classWorld);
109 TypeMask anyString =
110 new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
111 __indexableTypeTest = new TypeMask.unionOf(
112 <TypeMask>[indexable, anyString],
113 classWorld);
114 }
115 return __indexableTypeTest;
116 }
52 117
53 ClassElement get jsNullClass => helpers.jsNullClass; 118 ClassElement get jsNullClass => helpers.jsNullClass;
54 119
55 BackendHelpers get helpers => backend.helpers; 120 BackendHelpers get helpers => backend.helpers;
56 121
57 // TODO(karlklose): remove compiler here. 122 // TODO(karlklose): remove compiler here.
58 TypeMaskSystem(dart2js.Compiler compiler) 123 TypeMaskSystem(dart2js.Compiler compiler)
59 : inferrer = compiler.typesTask, 124 : inferrer = compiler.typesTask,
60 classWorld = compiler.world, 125 classWorld = compiler.world,
61 backend = compiler.backend { 126 backend = compiler.backend {
62
63 // Build the number+string+bool type. To make containment tests more
64 // inclusive, we use the num, String, bool types for this, not
65 // the JSNumber, JSString, JSBool subclasses.
66 TypeMask anyNum =
67 new TypeMask.nonNullSubtype(classWorld.numClass, classWorld);
68 TypeMask anyString =
69 new TypeMask.nonNullSubtype(classWorld.stringClass, classWorld);
70 TypeMask anyBool =
71 new TypeMask.nonNullSubtype(classWorld.boolClass, classWorld);
72 numStringBoolType =
73 new TypeMask.unionOf(<TypeMask>[anyNum, anyString, anyBool],
74 classWorld);
75 interceptorType =
76 new TypeMask.nonNullSubtype(helpers.jsInterceptorClass, classWorld);
77
78 // We redundantly include subtypes of num/string/bool as intercepted types,
79 // because the type system does not infer that their implementations are
80 // all subclasses of Interceptor.
81 interceptedTypes = new TypeMask.unionOf(
82 <TypeMask>[interceptorType, numStringBoolType], classWorld);
83
84 TypeMask typedArray = nonNullSubclass(helpers.typedArrayClass);
85 fixedLengthType = new TypeMask.unionOf(
86 <TypeMask>[stringType, backend.fixedArrayType, typedArray],
87 classWorld);
88
89 // Make a TypeMask containing Indexable and (redundantly) subtypes of
90 // string because the type inference does not infer that all strings are
91 // indexables.
92 TypeMask indexable =
93 new TypeMask.nonNullSubtype(helpers.jsIndexableClass, classWorld);
94 _indexableTypeTest = new TypeMask.unionOf(
95 <TypeMask>[indexable, anyString],
96 classWorld);
97 } 127 }
98 128
99 bool methodUsesReceiverArgument(FunctionElement function) { 129 bool methodUsesReceiverArgument(FunctionElement function) {
100 assert(backend.isInterceptedMethod(function)); 130 assert(backend.isInterceptedMethod(function));
101 ClassElement clazz = function.enclosingClass.declaration; 131 ClassElement clazz = function.enclosingClass.declaration;
102 return clazz.isSubclassOf(helpers.jsInterceptorClass) || 132 return clazz.isSubclassOf(helpers.jsInterceptorClass) ||
103 classWorld.isUsedAsMixin(clazz); 133 classWorld.isUsedAsMixin(clazz);
104 } 134 }
105 135
106 Element locateSingleElement(TypeMask mask, Selector selector) { 136 Element locateSingleElement(TypeMask mask, Selector selector) {
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 452
423 /// The length of something of [type], or `null` if unknown. 453 /// The length of something of [type], or `null` if unknown.
424 int getContainerLength(TypeMask type) { 454 int getContainerLength(TypeMask type) {
425 if (type is ContainerTypeMask) { 455 if (type is ContainerTypeMask) {
426 return type.length; 456 return type.length;
427 } else { 457 } else {
428 return null; 458 return null;
429 } 459 }
430 } 460 }
431 } 461 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698