| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of js_backend; | 5 part of js_backend; |
| 6 | 6 |
| 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 /// List of elements that the user has requested for reflection. | 334 /// List of elements that the user has requested for reflection. |
| 335 final Set<Element> targetsUsed = new Set<Element>(); | 335 final Set<Element> targetsUsed = new Set<Element>(); |
| 336 | 336 |
| 337 /// List of annotations provided by user that indicate that the annotated | 337 /// List of annotations provided by user that indicate that the annotated |
| 338 /// element must be retained. | 338 /// element must be retained. |
| 339 final Set<Element> metaTargetsUsed = new Set<Element>(); | 339 final Set<Element> metaTargetsUsed = new Set<Element>(); |
| 340 | 340 |
| 341 /// List of elements that the backend may use. | 341 /// List of elements that the backend may use. |
| 342 final Set<Element> helpersUsed = new Set<Element>(); | 342 final Set<Element> helpersUsed = new Set<Element>(); |
| 343 | 343 |
| 344 | |
| 345 /// Set of typedefs that are used as type literals. | 344 /// Set of typedefs that are used as type literals. |
| 346 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); | 345 final Set<TypedefElement> typedefTypeLiterals = new Set<TypedefElement>(); |
| 347 | 346 |
| 348 /// All the checked mode helpers. | |
| 349 static const checkedModeHelpers = const [ | |
| 350 const CheckedModeHelper(const SourceString('voidTypeCheck')), | |
| 351 const CheckedModeHelper(const SourceString('stringTypeCast')), | |
| 352 const CheckedModeHelper(const SourceString('stringTypeCheck')), | |
| 353 const CheckedModeHelper(const SourceString('doubleTypeCast')), | |
| 354 const CheckedModeHelper(const SourceString('doubleTypeCheck')), | |
| 355 const CheckedModeHelper(const SourceString('numTypeCast')), | |
| 356 const CheckedModeHelper(const SourceString('numTypeCheck')), | |
| 357 const CheckedModeHelper(const SourceString('boolTypeCast')), | |
| 358 const CheckedModeHelper(const SourceString('boolTypeCheck')), | |
| 359 const CheckedModeHelper(const SourceString('intTypeCast')), | |
| 360 const CheckedModeHelper(const SourceString('intTypeCheck')), | |
| 361 const PropertyCheckedModeHelper( | |
| 362 const SourceString('numberOrStringSuperNativeTypeCast')), | |
| 363 const PropertyCheckedModeHelper( | |
| 364 const SourceString('numberOrStringSuperNativeTypeCheck')), | |
| 365 const PropertyCheckedModeHelper( | |
| 366 const SourceString('numberOrStringSuperTypeCast')), | |
| 367 const PropertyCheckedModeHelper( | |
| 368 const SourceString('numberOrStringSuperTypeCheck')), | |
| 369 const PropertyCheckedModeHelper( | |
| 370 const SourceString('stringSuperNativeTypeCast')), | |
| 371 const PropertyCheckedModeHelper( | |
| 372 const SourceString('stringSuperNativeTypeCheck')), | |
| 373 const PropertyCheckedModeHelper( | |
| 374 const SourceString('stringSuperTypeCast')), | |
| 375 const PropertyCheckedModeHelper( | |
| 376 const SourceString('stringSuperTypeCheck')), | |
| 377 const CheckedModeHelper(const SourceString('listTypeCast')), | |
| 378 const CheckedModeHelper(const SourceString('listTypeCheck')), | |
| 379 const PropertyCheckedModeHelper( | |
| 380 const SourceString('listSuperNativeTypeCast')), | |
| 381 const PropertyCheckedModeHelper( | |
| 382 const SourceString('listSuperNativeTypeCheck')), | |
| 383 const PropertyCheckedModeHelper( | |
| 384 const SourceString('listSuperTypeCast')), | |
| 385 const PropertyCheckedModeHelper( | |
| 386 const SourceString('listSuperTypeCheck')), | |
| 387 const PropertyCheckedModeHelper( | |
| 388 const SourceString('interceptedTypeCast')), | |
| 389 const PropertyCheckedModeHelper( | |
| 390 const SourceString('interceptedTypeCheck')), | |
| 391 const SubtypeCheckedModeHelper( | |
| 392 const SourceString('subtypeCast')), | |
| 393 const SubtypeCheckedModeHelper( | |
| 394 const SourceString('assertSubtype')), | |
| 395 const TypeVariableCheckedModeHelper( | |
| 396 const SourceString('subtypeOfRuntimeTypeCast')), | |
| 397 const TypeVariableCheckedModeHelper( | |
| 398 const SourceString('assertSubtypeOfRuntimeType')), | |
| 399 const FunctionTypeCheckedModeHelper( | |
| 400 const SourceString('functionSubtypeCast')), | |
| 401 const FunctionTypeCheckedModeHelper( | |
| 402 const SourceString('assertFunctionSubtype')), | |
| 403 const PropertyCheckedModeHelper( | |
| 404 const SourceString('propertyTypeCast')), | |
| 405 const PropertyCheckedModeHelper( | |
| 406 const SourceString('propertyTypeCheck')) ]; | |
| 407 | |
| 408 // Checked mode helpers indexed by name. | |
| 409 Map<String, Checkedmodehelpers> checkedModeHelperByName = | |
| 410 new Map<String, CheckedModeHelper>.fromIterable( | |
| 411 checkedModeHelpers, | |
| 412 key: (helper) => helper.name.slowToString()); | |
| 413 | |
| 414 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) | 347 JavaScriptBackend(Compiler compiler, bool generateSourceMap, bool disableEval) |
| 415 : namer = determineNamer(compiler), | 348 : namer = determineNamer(compiler), |
| 416 oneShotInterceptors = new Map<String, Selector>(), | 349 oneShotInterceptors = new Map<String, Selector>(), |
| 417 interceptedElements = new Map<SourceString, Set<Element>>(), | 350 interceptedElements = new Map<SourceString, Set<Element>>(), |
| 418 rti = new RuntimeTypes(compiler), | 351 rti = new RuntimeTypes(compiler), |
| 419 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), | 352 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), |
| 420 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { | 353 super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| 421 emitter = disableEval | 354 emitter = disableEval |
| 422 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) | 355 ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap) |
| 423 : new CodeEmitterTask(compiler, namer, generateSourceMap); | 356 : new CodeEmitterTask(compiler, namer, generateSourceMap); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 ClassElement cls, Enqueuer enqueuer) { | 602 ClassElement cls, Enqueuer enqueuer) { |
| 670 if (enqueuer.isResolutionQueue) { | 603 if (enqueuer.isResolutionQueue) { |
| 671 cls.ensureResolved(compiler); | 604 cls.ensureResolved(compiler); |
| 672 cls.forEachMember((ClassElement classElement, Element member) { | 605 cls.forEachMember((ClassElement classElement, Element member) { |
| 673 if (member.isSynthesized) return; | 606 if (member.isSynthesized) return; |
| 674 // All methods on [Object] are shadowed by [Interceptor]. | 607 // All methods on [Object] are shadowed by [Interceptor]. |
| 675 if (classElement == compiler.objectClass) return; | 608 if (classElement == compiler.objectClass) return; |
| 676 Set<Element> set = interceptedElements.putIfAbsent( | 609 Set<Element> set = interceptedElements.putIfAbsent( |
| 677 member.name, () => new Set<Element>()); | 610 member.name, () => new Set<Element>()); |
| 678 set.add(member); | 611 set.add(member); |
| 612 if (classElement == jsInterceptorClass) return; |
| 613 if (classElement.isMixinApplication) { |
| 614 MixinApplicationElement mixinApplication = classElement; |
| 615 assert(member.getEnclosingClass() == mixinApplication.mixin); |
| 616 classesMixedIntoNativeClasses.add(mixinApplication.mixin); |
| 617 } |
| 679 }, | 618 }, |
| 680 includeSuperAndInjectedMembers: true); | 619 includeSuperAndInjectedMembers: true); |
| 681 | |
| 682 // Walk superclass chain to find mixins. | |
| 683 for (; cls != null; cls = cls.superclass) { | |
| 684 if (cls.isMixinApplication) { | |
| 685 MixinApplicationElement mixinApplication = cls; | |
| 686 classesMixedIntoNativeClasses.add(mixinApplication.mixin); | |
| 687 } | |
| 688 } | |
| 689 } | 620 } |
| 690 } | 621 } |
| 691 | 622 |
| 692 void addInterceptors(ClassElement cls, | 623 void addInterceptors(ClassElement cls, |
| 693 Enqueuer enqueuer, | 624 Enqueuer enqueuer, |
| 694 TreeElements elements) { | 625 TreeElements elements) { |
| 695 if (enqueuer.isResolutionQueue) { | 626 if (enqueuer.isResolutionQueue) { |
| 696 _interceptedClasses.add(jsInterceptorClass); | 627 _interceptedClasses.add(jsInterceptorClass); |
| 697 _interceptedClasses.add(cls); | 628 _interceptedClasses.add(cls); |
| 698 cls.ensureResolved(compiler); | 629 cls.ensureResolved(compiler); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 addInterceptors(jsBoolClass, world, elements); | 770 addInterceptors(jsBoolClass, world, elements); |
| 840 addInterceptors(jsNullClass, world, elements); | 771 addInterceptors(jsNullClass, world, elements); |
| 841 if (compiler.enableTypeAssertions) { | 772 if (compiler.enableTypeAssertions) { |
| 842 // Unconditionally register the helper that checks if the | 773 // Unconditionally register the helper that checks if the |
| 843 // expression in an if/while/for is a boolean. | 774 // expression in an if/while/for is a boolean. |
| 844 // TODO(ngeoffray): Should we have the resolver register those instead? | 775 // TODO(ngeoffray): Should we have the resolver register those instead? |
| 845 Element e = | 776 Element e = |
| 846 compiler.findHelper(const SourceString('boolConversionCheck')); | 777 compiler.findHelper(const SourceString('boolConversionCheck')); |
| 847 if (e != null) enqueue(world, e, elements); | 778 if (e != null) enqueue(world, e, elements); |
| 848 } | 779 } |
| 849 registerCheckedModeHelpers(elements); | |
| 850 } | 780 } |
| 851 | 781 |
| 852 onResolutionComplete() => rti.computeClassesNeedingRti(); | 782 onResolutionComplete() => rti.computeClassesNeedingRti(); |
| 853 | 783 |
| 854 void registerStringInterpolation(TreeElements elements) { | 784 void registerStringInterpolation(TreeElements elements) { |
| 855 enqueueInResolution(getStringInterpolationHelper(), elements); | 785 enqueueInResolution(getStringInterpolationHelper(), elements); |
| 856 } | 786 } |
| 857 | 787 |
| 858 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { | 788 void registerCatchStatement(Enqueuer enqueuer, TreeElements elements) { |
| 859 void ensure(ClassElement classElement) { | 789 void ensure(ClassElement classElement) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 enqueueInResolution(getCreateRuntimeType(), elements); | 872 enqueueInResolution(getCreateRuntimeType(), elements); |
| 943 } | 873 } |
| 944 | 874 |
| 945 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { | 875 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| 946 type = type.unalias(compiler); | 876 type = type.unalias(compiler); |
| 947 enqueueClass(world, compiler.boolClass, elements); | 877 enqueueClass(world, compiler.boolClass, elements); |
| 948 bool inCheckedMode = compiler.enableTypeAssertions; | 878 bool inCheckedMode = compiler.enableTypeAssertions; |
| 949 // [registerIsCheck] is also called for checked mode checks, so we | 879 // [registerIsCheck] is also called for checked mode checks, so we |
| 950 // need to register checked mode helpers. | 880 // need to register checked mode helpers. |
| 951 if (inCheckedMode) { | 881 if (inCheckedMode) { |
| 952 if (!world.isResolutionQueue) { | 882 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); |
| 953 // All helpers are added to resolution queue in enqueueHelpers. These | 883 if (helper != null) enqueue(world, helper.getElement(compiler), elements); |
| 954 // calls to enqueueInResolution serve as assertions that the helper was | 884 // We also need the native variant of the check (for DOM types). |
| 955 // in fact added. | 885 helper = getNativeCheckedModeHelper(type, typeCast: false); |
| 956 // TODO(13155): Find a way to enqueue helpers lazily. | 886 if (helper != null) enqueue(world, helper.getElement(compiler), elements); |
| 957 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); | |
| 958 if (helper != null) { | |
| 959 enqueue(world, helper.getElement(compiler), elements); | |
| 960 } | |
| 961 // We also need the native variant of the check (for DOM types). | |
| 962 helper = getNativeCheckedModeHelper(type, typeCast: false); | |
| 963 if (helper != null) { | |
| 964 enqueue(world, helper.getElement(compiler), elements); | |
| 965 } | |
| 966 } | |
| 967 } | 887 } |
| 968 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; | 888 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
| 969 if (!type.isRaw || type.containsTypeVariables) { | 889 if (!type.isRaw || type.containsTypeVariables) { |
| 970 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 890 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
| 971 enqueueInResolution(getGetRuntimeTypeInfo(), elements); | 891 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
| 972 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 892 enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
| 973 if (inCheckedMode) { | 893 if (inCheckedMode) { |
| 974 enqueueInResolution(getAssertSubtype(), elements); | 894 enqueueInResolution(getAssertSubtype(), elements); |
| 975 } | 895 } |
| 976 enqueueInResolution(getCheckSubtype(), elements); | 896 enqueueInResolution(getCheckSubtype(), elements); |
| 977 if (isTypeVariable) { | 897 if (isTypeVariable) { |
| 978 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); | 898 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); |
| 979 if (inCheckedMode) { | 899 if (inCheckedMode) { |
| 980 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 900 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
| 981 } | 901 } |
| 982 } | 902 } |
| 983 enqueueClass(world, compiler.listClass, elements); | 903 enqueueClass(world, compiler.listClass, elements); |
| 984 } | 904 } |
| 985 if (type is FunctionType) { | 905 if (type is FunctionType) { |
| 986 enqueueInResolution(getCheckFunctionSubtype(), elements); | 906 enqueueInResolution(getCheckFunctionSubtype(), elements); |
| 987 } | 907 } |
| 988 if (type.element.isNative()) { | 908 if (type.element.isNative()) { |
| 989 // We will neeed to add the "$is" and "$as" properties on the | 909 // We will neeed to add the "$is" and "$as" properties on the |
| 990 // JavaScript object prototype, so we make sure | 910 // JavaScript object prototype, so we make sure |
| 991 // [:defineProperty:] is compiled. | 911 // [:defineProperty:] is compiled. |
| 992 enqueue(world, | 912 enqueue(world, |
| 993 compiler.findHelper(const SourceString('defineProperty')), | 913 compiler.findHelper(const SourceString('defineProperty')), |
| 994 elements); | 914 elements); |
| 995 } | 915 } |
| 996 } | 916 } |
| 997 | 917 |
| 998 void registerAsCheck(DartType type, Enqueuer world, TreeElements elements) { | 918 void registerAsCheck(DartType type, TreeElements elements) { |
| 999 type = type.unalias(compiler); | 919 type = type.unalias(compiler); |
| 1000 if (!world.isResolutionQueue) { | 920 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); |
| 1001 // All helpers are added to resolution queue in enqueueHelpers. These | 921 enqueueInResolution(helper.getElement(compiler), elements); |
| 1002 // calls to enqueueInResolution serve as assertions that the helper was in | 922 // We also need the native variant of the check (for DOM types). |
| 1003 // fact added. | 923 helper = getNativeCheckedModeHelper(type, typeCast: true); |
| 1004 // TODO(13155): Find a way to enqueue helpers lazily. | 924 if (helper != null) { |
| 1005 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); | |
| 1006 enqueueInResolution(helper.getElement(compiler), elements); | 925 enqueueInResolution(helper.getElement(compiler), elements); |
| 1007 // We also need the native variant of the check (for DOM types). | |
| 1008 helper = getNativeCheckedModeHelper(type, typeCast: true); | |
| 1009 if (helper != null) { | |
| 1010 enqueueInResolution(helper.getElement(compiler), elements); | |
| 1011 } | |
| 1012 } | 926 } |
| 1013 } | 927 } |
| 1014 | 928 |
| 1015 void registerThrowNoSuchMethod(TreeElements elements) { | 929 void registerThrowNoSuchMethod(TreeElements elements) { |
| 1016 enqueueInResolution(getThrowNoSuchMethod(), elements); | 930 enqueueInResolution(getThrowNoSuchMethod(), elements); |
| 1017 // Also register the types of the arguments passed to this method. | 931 // Also register the types of the arguments passed to this method. |
| 1018 enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements); | 932 enqueueClass(compiler.enqueuer.resolution, compiler.listClass, elements); |
| 1019 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements); | 933 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, elements); |
| 1020 } | 934 } |
| 1021 | 935 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 type, typeCast: typeCast, nativeCheckOnly: true); | 1165 type, typeCast: typeCast, nativeCheckOnly: true); |
| 1252 } | 1166 } |
| 1253 | 1167 |
| 1254 /** | 1168 /** |
| 1255 * Returns the checked mode helper for the type check/type cast for [type]. If | 1169 * Returns the checked mode helper for the type check/type cast for [type]. If |
| 1256 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. | 1170 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. |
| 1257 */ | 1171 */ |
| 1258 CheckedModeHelper getCheckedModeHelperInternal(DartType type, | 1172 CheckedModeHelper getCheckedModeHelperInternal(DartType type, |
| 1259 {bool typeCast, | 1173 {bool typeCast, |
| 1260 bool nativeCheckOnly}) { | 1174 bool nativeCheckOnly}) { |
| 1261 String name = getCheckedModeHelperNameInternal(type, | |
| 1262 typeCast: typeCast, nativeCheckOnly: nativeCheckOnly); | |
| 1263 if (name == null) return null; | |
| 1264 CheckedModeHelper helper = checkedModeHelperByName[name]; | |
| 1265 assert(helper != null); | |
| 1266 return helper; | |
| 1267 } | |
| 1268 | |
| 1269 String getCheckedModeHelperNameInternal(DartType type, | |
| 1270 {bool typeCast, | |
| 1271 bool nativeCheckOnly}) { | |
| 1272 assert(type.kind != TypeKind.TYPEDEF); | 1175 assert(type.kind != TypeKind.TYPEDEF); |
| 1273 Element element = type.element; | 1176 Element element = type.element; |
| 1274 bool nativeCheck = nativeCheckOnly || | 1177 bool nativeCheck = nativeCheckOnly || |
| 1275 emitter.nativeEmitter.requiresNativeIsCheck(element); | 1178 emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 1276 if (type == compiler.types.voidType) { | 1179 if (type == compiler.types.voidType) { |
| 1277 assert(!typeCast); // Cannot cast to void. | 1180 assert(!typeCast); // Cannot cast to void. |
| 1278 if (nativeCheckOnly) return null; | 1181 if (nativeCheckOnly) return null; |
| 1279 return 'voidTypeCheck'; | 1182 return const CheckedModeHelper(const SourceString('voidTypeCheck')); |
| 1280 } else if (element == jsStringClass || element == compiler.stringClass) { | 1183 } else if (element == jsStringClass || element == compiler.stringClass) { |
| 1281 if (nativeCheckOnly) return null; | 1184 if (nativeCheckOnly) return null; |
| 1282 return typeCast | 1185 return typeCast |
| 1283 ? 'stringTypeCast' | 1186 ? const CheckedModeHelper(const SourceString("stringTypeCast")) |
| 1284 : 'stringTypeCheck'; | 1187 : const CheckedModeHelper(const SourceString('stringTypeCheck')); |
| 1285 } else if (element == jsDoubleClass || element == compiler.doubleClass) { | 1188 } else if (element == jsDoubleClass || element == compiler.doubleClass) { |
| 1286 if (nativeCheckOnly) return null; | 1189 if (nativeCheckOnly) return null; |
| 1287 return typeCast | 1190 return typeCast |
| 1288 ? 'doubleTypeCast' | 1191 ? const CheckedModeHelper(const SourceString("doubleTypeCast")) |
| 1289 : 'doubleTypeCheck'; | 1192 : const CheckedModeHelper(const SourceString('doubleTypeCheck')); |
| 1290 } else if (element == jsNumberClass || element == compiler.numClass) { | 1193 } else if (element == jsNumberClass || element == compiler.numClass) { |
| 1291 if (nativeCheckOnly) return null; | 1194 if (nativeCheckOnly) return null; |
| 1292 return typeCast | 1195 return typeCast |
| 1293 ? 'numTypeCast' | 1196 ? const CheckedModeHelper(const SourceString("numTypeCast")) |
| 1294 : 'numTypeCheck'; | 1197 : const CheckedModeHelper(const SourceString('numTypeCheck')); |
| 1295 } else if (element == jsBoolClass || element == compiler.boolClass) { | 1198 } else if (element == jsBoolClass || element == compiler.boolClass) { |
| 1296 if (nativeCheckOnly) return null; | 1199 if (nativeCheckOnly) return null; |
| 1297 return typeCast | 1200 return typeCast |
| 1298 ? 'boolTypeCast' | 1201 ? const CheckedModeHelper(const SourceString("boolTypeCast")) |
| 1299 : 'boolTypeCheck'; | 1202 : const CheckedModeHelper(const SourceString('boolTypeCheck')); |
| 1300 } else if (element == jsIntClass || element == compiler.intClass) { | 1203 } else if (element == jsIntClass || element == compiler.intClass) { |
| 1301 if (nativeCheckOnly) return null; | 1204 if (nativeCheckOnly) return null; |
| 1302 return typeCast | 1205 return typeCast |
| 1303 ? 'intTypeCast' | 1206 ? const CheckedModeHelper(const SourceString("intTypeCast")) |
| 1304 : 'intTypeCheck'; | 1207 : const CheckedModeHelper(const SourceString('intTypeCheck')); |
| 1305 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { | 1208 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { |
| 1306 if (nativeCheck) { | 1209 if (nativeCheck) { |
| 1307 return typeCast | 1210 return typeCast |
| 1308 ? 'numberOrStringSuperNativeTypeCast' | 1211 ? const PropertyCheckedModeHelper( |
| 1309 : 'numberOrStringSuperNativeTypeCheck'; | 1212 const SourceString("numberOrStringSuperNativeTypeCast")) |
| 1213 : const PropertyCheckedModeHelper( |
| 1214 const SourceString('numberOrStringSuperNativeTypeCheck')); |
| 1310 } else { | 1215 } else { |
| 1311 return typeCast | 1216 return typeCast |
| 1312 ? 'numberOrStringSuperTypeCast' | 1217 ? const PropertyCheckedModeHelper( |
| 1313 : 'numberOrStringSuperTypeCheck'; | 1218 const SourceString("numberOrStringSuperTypeCast")) |
| 1219 : const PropertyCheckedModeHelper( |
| 1220 const SourceString('numberOrStringSuperTypeCheck')); |
| 1314 } | 1221 } |
| 1315 } else if (Elements.isStringOnlySupertype(element, compiler)) { | 1222 } else if (Elements.isStringOnlySupertype(element, compiler)) { |
| 1316 if (nativeCheck) { | 1223 if (nativeCheck) { |
| 1317 return typeCast | 1224 return typeCast |
| 1318 ? 'stringSuperNativeTypeCast' | 1225 ? const PropertyCheckedModeHelper( |
| 1319 : 'stringSuperNativeTypeCheck'; | 1226 const SourceString("stringSuperNativeTypeCast")) |
| 1227 : const PropertyCheckedModeHelper( |
| 1228 const SourceString('stringSuperNativeTypeCheck')); |
| 1320 } else { | 1229 } else { |
| 1321 return typeCast | 1230 return typeCast |
| 1322 ? 'stringSuperTypeCast' | 1231 ? const PropertyCheckedModeHelper( |
| 1323 : 'stringSuperTypeCheck'; | 1232 const SourceString("stringSuperTypeCast")) |
| 1233 : const PropertyCheckedModeHelper( |
| 1234 const SourceString('stringSuperTypeCheck')); |
| 1324 } | 1235 } |
| 1325 } else if ((element == compiler.listClass || element == jsArrayClass) && | 1236 } else if ((element == compiler.listClass || element == jsArrayClass) && |
| 1326 type.isRaw) { | 1237 type.isRaw) { |
| 1327 if (nativeCheckOnly) return null; | 1238 if (nativeCheckOnly) return null; |
| 1328 return typeCast | 1239 return typeCast |
| 1329 ? 'listTypeCast' | 1240 ? const CheckedModeHelper(const SourceString("listTypeCast")) |
| 1330 : 'listTypeCheck'; | 1241 : const CheckedModeHelper(const SourceString('listTypeCheck')); |
| 1331 } else { | 1242 } else { |
| 1332 if (Elements.isListSupertype(element, compiler)) { | 1243 if (Elements.isListSupertype(element, compiler)) { |
| 1333 if (nativeCheck) { | 1244 if (nativeCheck) { |
| 1334 return typeCast | 1245 return typeCast |
| 1335 ? 'listSuperNativeTypeCast' | 1246 ? const PropertyCheckedModeHelper( |
| 1336 : 'listSuperNativeTypeCheck'; | 1247 const SourceString("listSuperNativeTypeCast")) |
| 1248 : const PropertyCheckedModeHelper( |
| 1249 const SourceString('listSuperNativeTypeCheck')); |
| 1337 } else { | 1250 } else { |
| 1338 return typeCast | 1251 return typeCast |
| 1339 ? 'listSuperTypeCast' | 1252 ? const PropertyCheckedModeHelper( |
| 1340 : 'listSuperTypeCheck'; | 1253 const SourceString("listSuperTypeCast")) |
| 1254 : const PropertyCheckedModeHelper( |
| 1255 const SourceString('listSuperTypeCheck')); |
| 1341 } | 1256 } |
| 1342 } else { | 1257 } else { |
| 1343 if (nativeCheck) { | 1258 if (nativeCheck) { |
| 1344 // TODO(karlklose): can we get rid of this branch when we use | 1259 // TODO(karlklose): can we get rid of this branch when we use |
| 1345 // interceptors? | 1260 // interceptors? |
| 1346 return typeCast | 1261 return typeCast |
| 1347 ? 'interceptedTypeCast' | 1262 ? const PropertyCheckedModeHelper( |
| 1348 : 'interceptedTypeCheck'; | 1263 const SourceString("interceptedTypeCast")) |
| 1264 : const PropertyCheckedModeHelper( |
| 1265 const SourceString('interceptedTypeCheck')); |
| 1349 } else { | 1266 } else { |
| 1350 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { | 1267 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { |
| 1351 return typeCast | 1268 return typeCast |
| 1352 ? 'subtypeCast' | 1269 ? const SubtypeCheckedModeHelper( |
| 1353 : 'assertSubtype'; | 1270 const SourceString('subtypeCast')) |
| 1271 : const SubtypeCheckedModeHelper( |
| 1272 const SourceString('assertSubtype')); |
| 1354 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1273 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
| 1355 return typeCast | 1274 return typeCast |
| 1356 ? 'subtypeOfRuntimeTypeCast' | 1275 ? const TypeVariableCheckedModeHelper( |
| 1357 : 'assertSubtypeOfRuntimeType'; | 1276 const SourceString('subtypeOfRuntimeTypeCast')) |
| 1277 : const TypeVariableCheckedModeHelper( |
| 1278 const SourceString('assertSubtypeOfRuntimeType')); |
| 1358 } else if (type.kind == TypeKind.FUNCTION) { | 1279 } else if (type.kind == TypeKind.FUNCTION) { |
| 1359 return typeCast | 1280 return typeCast |
| 1360 ? 'functionSubtypeCast' | 1281 ? const FunctionTypeCheckedModeHelper( |
| 1361 : 'assertFunctionSubtype'; | 1282 const SourceString('functionSubtypeCast')) |
| 1283 : const FunctionTypeCheckedModeHelper( |
| 1284 const SourceString('assertFunctionSubtype')); |
| 1362 } else { | 1285 } else { |
| 1363 return typeCast | 1286 return typeCast |
| 1364 ? 'propertyTypeCast' | 1287 ? const PropertyCheckedModeHelper( |
| 1365 : 'propertyTypeCheck'; | 1288 const SourceString('propertyTypeCast')) |
| 1289 : const PropertyCheckedModeHelper( |
| 1290 const SourceString('propertyTypeCheck')); |
| 1366 } | 1291 } |
| 1367 } | 1292 } |
| 1368 } | 1293 } |
| 1369 } | 1294 } |
| 1370 } | 1295 } |
| 1371 | 1296 |
| 1372 void registerCheckedModeHelpers(TreeElements elements) { | |
| 1373 // We register all the helpers in the resolution queue. | |
| 1374 // TODO(13155): Find a way to register fewer helpers. | |
| 1375 for (CheckedModeHelper helper in checkedModeHelpers) { | |
| 1376 enqueueInResolution(helper.getElement(compiler), elements); | |
| 1377 } | |
| 1378 } | |
| 1379 | |
| 1380 /** | 1297 /** |
| 1381 * Returns [:true:] if the checking of [type] is performed directly on the | 1298 * Returns [:true:] if the checking of [type] is performed directly on the |
| 1382 * object and not on an interceptor. | 1299 * object and not on an interceptor. |
| 1383 */ | 1300 */ |
| 1384 bool hasDirectCheckFor(DartType type) { | 1301 bool hasDirectCheckFor(DartType type) { |
| 1385 Element element = type.element; | 1302 Element element = type.element; |
| 1386 return element == compiler.stringClass || | 1303 return element == compiler.stringClass || |
| 1387 element == compiler.boolClass || | 1304 element == compiler.boolClass || |
| 1388 element == compiler.numClass || | 1305 element == compiler.numClass || |
| 1389 element == compiler.intClass || | 1306 element == compiler.intClass || |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 copy(constant.values); | 1696 copy(constant.values); |
| 1780 copy(constant.protoValue); | 1697 copy(constant.protoValue); |
| 1781 copy(constant); | 1698 copy(constant); |
| 1782 } | 1699 } |
| 1783 | 1700 |
| 1784 void visitConstructed(ConstructedConstant constant) { | 1701 void visitConstructed(ConstructedConstant constant) { |
| 1785 copy(constant.fields); | 1702 copy(constant.fields); |
| 1786 copy(constant); | 1703 copy(constant); |
| 1787 } | 1704 } |
| 1788 } | 1705 } |
| OLD | NEW |