| 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 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
| 8 | 8 |
| 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| (...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 668 | 668 |
| 669 if (constant.isFunction) { | 669 if (constant.isFunction) { |
| 670 FunctionConstant function = constant; | 670 FunctionConstant function = constant; |
| 671 compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element); | 671 compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element); |
| 672 } else if (constant.isInterceptor) { | 672 } else if (constant.isInterceptor) { |
| 673 // An interceptor constant references the class's prototype chain. | 673 // An interceptor constant references the class's prototype chain. |
| 674 InterceptorConstant interceptor = constant; | 674 InterceptorConstant interceptor = constant; |
| 675 registerInstantiatedConstantType(interceptor.dispatchedType, registry); | 675 registerInstantiatedConstantType(interceptor.dispatchedType, registry); |
| 676 } else if (constant.isType) { | 676 } else if (constant.isType) { |
| 677 TypeConstant typeConstant = constant; | 677 TypeConstant typeConstant = constant; |
| 678 registerTypeLiteral(typeConstant.representedType.element, | 678 registerTypeLiteral(typeConstant.representedType, |
| 679 compiler.enqueuer.codegen, registry); | 679 compiler.enqueuer.codegen, registry); |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 | 682 |
| 683 void registerInstantiatedConstantType(DartType type, Registry registry) { | 683 void registerInstantiatedConstantType(DartType type, Registry registry) { |
| 684 Enqueuer enqueuer = compiler.enqueuer.codegen; | 684 Enqueuer enqueuer = compiler.enqueuer.codegen; |
| 685 DartType instantiatedType = | 685 DartType instantiatedType = |
| 686 type.kind == TypeKind.FUNCTION ? compiler.functionClass.rawType : type; | 686 type.isFunctionType ? compiler.functionClass.rawType : type; |
| 687 enqueuer.registerInstantiatedType(instantiatedType, registry); | 687 if (type is InterfaceType) { |
| 688 if (type is InterfaceType && !type.treatAsRaw && | 688 enqueuer.registerInstantiatedType(instantiatedType, registry); |
| 689 classNeedsRti(type.element)) { | 689 if (!type.treatAsRaw && classNeedsRti(type.element)) { |
| 690 enqueuer.registerStaticUse(getSetRuntimeTypeInfo()); | 690 enqueuer.registerStaticUse(getSetRuntimeTypeInfo()); |
| 691 } | 691 } |
| 692 if (type.element == typeImplementation) { | 692 if (type.element == typeImplementation) { |
| 693 // If we use a type literal in a constant, the compile time | 693 // If we use a type literal in a constant, the compile time |
| 694 // constant emitter will generate a call to the createRuntimeType | 694 // constant emitter will generate a call to the createRuntimeType |
| 695 // helper so we register a use of that. | 695 // helper so we register a use of that. |
| 696 enqueuer.registerStaticUse(getCreateRuntimeType()); | 696 enqueuer.registerStaticUse(getCreateRuntimeType()); |
| 697 } |
| 697 } | 698 } |
| 698 } | 699 } |
| 699 | 700 |
| 700 void registerMetadataConstant(Constant constant, Registry registry) { | 701 void registerMetadataConstant(Constant constant, Registry registry) { |
| 701 if (mustRetainMetadata) { | 702 if (mustRetainMetadata) { |
| 702 registerCompileTimeConstant(constant, registry); | 703 registerCompileTimeConstant(constant, registry); |
| 703 } else { | 704 } else { |
| 704 metadataConstants.add(new Dependency(constant, registry)); | 705 metadataConstants.add(new Dependency(constant, registry)); |
| 705 } | 706 } |
| 706 } | 707 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 // statement context or an expression context, so we register both | 886 // statement context or an expression context, so we register both |
| 886 // here, even though we may not need the throwExpression helper. | 887 // here, even though we may not need the throwExpression helper. |
| 887 enqueueInResolution(getWrapExceptionHelper(), registry); | 888 enqueueInResolution(getWrapExceptionHelper(), registry); |
| 888 enqueueInResolution(getThrowExpressionHelper(), registry); | 889 enqueueInResolution(getThrowExpressionHelper(), registry); |
| 889 } | 890 } |
| 890 | 891 |
| 891 void registerLazyField(Registry registry) { | 892 void registerLazyField(Registry registry) { |
| 892 enqueueInResolution(getCyclicThrowHelper(), registry); | 893 enqueueInResolution(getCyclicThrowHelper(), registry); |
| 893 } | 894 } |
| 894 | 895 |
| 895 void registerTypeLiteral(Element element, | 896 void registerTypeLiteral(DartType type, |
| 896 Enqueuer enqueuer, | 897 Enqueuer enqueuer, |
| 897 Registry registry) { | 898 Registry registry) { |
| 898 enqueuer.registerInstantiatedClass(typeImplementation, registry); | 899 enqueuer.registerInstantiatedClass(typeImplementation, registry); |
| 899 enqueueInResolution(getCreateRuntimeType(), registry); | 900 enqueueInResolution(getCreateRuntimeType(), registry); |
| 900 // TODO(ahe): Might want to register [element] as an instantiated class | 901 // TODO(ahe): Might want to register [element] as an instantiated class |
| 901 // when reflection is used. However, as long as we disable tree-shaking | 902 // when reflection is used. However, as long as we disable tree-shaking |
| 902 // eagerly it doesn't matter. | 903 // eagerly it doesn't matter. |
| 903 if (element.isTypedef) { | 904 if (type.isTypedef) { |
| 904 typedefTypeLiterals.add(element); | 905 typedefTypeLiterals.add(type.element); |
| 905 } | 906 } |
| 906 customElementsAnalysis.registerTypeLiteral(element, enqueuer); | 907 customElementsAnalysis.registerTypeLiteral(type, enqueuer); |
| 907 } | 908 } |
| 908 | 909 |
| 909 void registerStackTraceInCatch(Registry registry) { | 910 void registerStackTraceInCatch(Registry registry) { |
| 910 enqueueInResolution(getTraceFromException(), registry); | 911 enqueueInResolution(getTraceFromException(), registry); |
| 911 } | 912 } |
| 912 | 913 |
| 913 void registerGetRuntimeTypeArgument(Registry registry) { | 914 void registerGetRuntimeTypeArgument(Registry registry) { |
| 914 enqueueInResolution(getGetRuntimeTypeArgument(), registry); | 915 enqueueInResolution(getGetRuntimeTypeArgument(), registry); |
| 915 enqueueInResolution(getGetTypeArgumentByIndex(), registry); | 916 enqueueInResolution(getGetTypeArgumentByIndex(), registry); |
| 916 enqueueInResolution(getCopyTypeArguments(), registry); | 917 enqueueInResolution(getCopyTypeArguments(), registry); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 if (helper != null) { | 976 if (helper != null) { |
| 976 enqueue(world, helper.getElement(compiler), registry); | 977 enqueue(world, helper.getElement(compiler), registry); |
| 977 } | 978 } |
| 978 // We also need the native variant of the check (for DOM types). | 979 // We also need the native variant of the check (for DOM types). |
| 979 helper = getNativeCheckedModeHelper(type, typeCast: false); | 980 helper = getNativeCheckedModeHelper(type, typeCast: false); |
| 980 if (helper != null) { | 981 if (helper != null) { |
| 981 enqueue(world, helper.getElement(compiler), registry); | 982 enqueue(world, helper.getElement(compiler), registry); |
| 982 } | 983 } |
| 983 } | 984 } |
| 984 } | 985 } |
| 985 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; | 986 bool isTypeVariable = type.isTypeVariable; |
| 986 if (type.kind == TypeKind.MALFORMED_TYPE) { | 987 if (type.isMalformed) { |
| 987 enqueueInResolution(getThrowTypeError(), registry); | 988 enqueueInResolution(getThrowTypeError(), registry); |
| 988 } | 989 } |
| 989 if (!type.treatAsRaw || type.containsTypeVariables) { | 990 if (!type.treatAsRaw || type.containsTypeVariables) { |
| 990 enqueueInResolution(getSetRuntimeTypeInfo(), registry); | 991 enqueueInResolution(getSetRuntimeTypeInfo(), registry); |
| 991 enqueueInResolution(getGetRuntimeTypeInfo(), registry); | 992 enqueueInResolution(getGetRuntimeTypeInfo(), registry); |
| 992 registerGetRuntimeTypeArgument(registry); | 993 registerGetRuntimeTypeArgument(registry); |
| 993 if (inCheckedMode) { | 994 if (inCheckedMode) { |
| 994 enqueueInResolution(getAssertSubtype(), registry); | 995 enqueueInResolution(getAssertSubtype(), registry); |
| 995 } | 996 } |
| 996 enqueueInResolution(getCheckSubtype(), registry); | 997 enqueueInResolution(getCheckSubtype(), registry); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 if (name == null) return null; | 1301 if (name == null) return null; |
| 1301 CheckedModeHelper helper = checkedModeHelperByName[name]; | 1302 CheckedModeHelper helper = checkedModeHelperByName[name]; |
| 1302 assert(helper != null); | 1303 assert(helper != null); |
| 1303 return helper; | 1304 return helper; |
| 1304 } | 1305 } |
| 1305 | 1306 |
| 1306 String getCheckedModeHelperNameInternal(DartType type, | 1307 String getCheckedModeHelperNameInternal(DartType type, |
| 1307 {bool typeCast, | 1308 {bool typeCast, |
| 1308 bool nativeCheckOnly}) { | 1309 bool nativeCheckOnly}) { |
| 1309 assert(type.kind != TypeKind.TYPEDEF); | 1310 assert(type.kind != TypeKind.TYPEDEF); |
| 1310 if (type.kind == TypeKind.MALFORMED_TYPE) { | 1311 if (type.isMalformed) { |
| 1311 // The same error is thrown for type test and type cast of a malformed | 1312 // The same error is thrown for type test and type cast of a malformed |
| 1312 // type so we only need one check method. | 1313 // type so we only need one check method. |
| 1313 return 'checkMalformedType'; | 1314 return 'checkMalformedType'; |
| 1314 } | 1315 } |
| 1315 Element element = type.element; | 1316 Element element = type.element; |
| 1316 bool nativeCheck = nativeCheckOnly || | 1317 bool nativeCheck = nativeCheckOnly || |
| 1317 emitter.nativeEmitter.requiresNativeIsCheck(element); | 1318 emitter.nativeEmitter.requiresNativeIsCheck(element); |
| 1318 | 1319 |
| 1319 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 1320 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
| 1320 // interceptor. The interceptor should be an argument to HTypeConversion so | 1321 // interceptor. The interceptor should be an argument to HTypeConversion so |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 if (nativeCheck) { | 1384 if (nativeCheck) { |
| 1384 return typeCast | 1385 return typeCast |
| 1385 ? 'listSuperNativeTypeCast' | 1386 ? 'listSuperNativeTypeCast' |
| 1386 : 'listSuperNativeTypeCheck'; | 1387 : 'listSuperNativeTypeCheck'; |
| 1387 } else { | 1388 } else { |
| 1388 return typeCast | 1389 return typeCast |
| 1389 ? 'listSuperTypeCast' | 1390 ? 'listSuperTypeCast' |
| 1390 : 'listSuperTypeCheck'; | 1391 : 'listSuperTypeCheck'; |
| 1391 } | 1392 } |
| 1392 } else { | 1393 } else { |
| 1393 if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) { | 1394 if (type.isInterfaceType && !type.treatAsRaw) { |
| 1394 return typeCast | 1395 return typeCast |
| 1395 ? 'subtypeCast' | 1396 ? 'subtypeCast' |
| 1396 : 'assertSubtype'; | 1397 : 'assertSubtype'; |
| 1397 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1398 } else if (type.isTypeVariable) { |
| 1398 return typeCast | 1399 return typeCast |
| 1399 ? 'subtypeOfRuntimeTypeCast' | 1400 ? 'subtypeOfRuntimeTypeCast' |
| 1400 : 'assertSubtypeOfRuntimeType'; | 1401 : 'assertSubtypeOfRuntimeType'; |
| 1401 } else if (type.kind == TypeKind.FUNCTION) { | 1402 } else if (type.isFunctionType) { |
| 1402 return null; | 1403 return null; |
| 1403 } else { | 1404 } else { |
| 1404 if (nativeCheck) { | 1405 if (nativeCheck) { |
| 1405 // TODO(karlklose): can we get rid of this branch when we use | 1406 // TODO(karlklose): can we get rid of this branch when we use |
| 1406 // interceptors? | 1407 // interceptors? |
| 1407 return typeCast | 1408 return typeCast |
| 1408 ? 'interceptedTypeCast' | 1409 ? 'interceptedTypeCast' |
| 1409 : 'interceptedTypeCheck'; | 1410 : 'interceptedTypeCheck'; |
| 1410 } else { | 1411 } else { |
| 1411 return typeCast | 1412 return typeCast |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 } | 1910 } |
| 1910 | 1911 |
| 1911 /// Records that [constant] is used by the element behind [registry]. | 1912 /// Records that [constant] is used by the element behind [registry]. |
| 1912 class Dependency { | 1913 class Dependency { |
| 1913 final Constant constant; | 1914 final Constant constant; |
| 1914 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. | 1915 // TODO(johnniwinther): Change to [Element] when dependency nodes are added. |
| 1915 final Registry registry; | 1916 final Registry registry; |
| 1916 | 1917 |
| 1917 const Dependency(this.constant, this.registry); | 1918 const Dependency(this.constant, this.registry); |
| 1918 } | 1919 } |
| OLD | NEW |