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 |