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() |
11 : boundsChecked = new Set<HInstruction>(); | 11 : boundsChecked = new Set<HInstruction>(); |
12 } | 12 } |
13 | 13 |
| 14 |
| 15 class CheckedModeHelper { |
| 16 final SourceString name; |
| 17 |
| 18 const CheckedModeHelper(SourceString this.name); |
| 19 |
| 20 Element getElement(Compiler compiler) => compiler.findHelper(name); |
| 21 |
| 22 jsAst.Expression generateCall(SsaCodeGenerator codegen, |
| 23 HTypeConversion node) { |
| 24 Element helperElement = getElement(codegen.compiler); |
| 25 codegen.world.registerStaticUse(helperElement); |
| 26 List<jsAst.Expression> arguments = <jsAst.Expression>[]; |
| 27 codegen.use(node.checkedInput); |
| 28 arguments.add(codegen.pop()); |
| 29 generateAdditionalArguments(codegen, node, arguments); |
| 30 String helperName = codegen.backend.namer.isolateAccess(helperElement); |
| 31 return new jsAst.Call(new jsAst.VariableUse(helperName), arguments); |
| 32 } |
| 33 |
| 34 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 35 HTypeConversion node, |
| 36 List<jsAst.Expression> arguments) { |
| 37 assert(!node.typeExpression.isMalformed); |
| 38 // No additional arguments needed. |
| 39 } |
| 40 } |
| 41 |
| 42 class PropertyCheckedModeHelper extends CheckedModeHelper { |
| 43 const PropertyCheckedModeHelper(SourceString name) : super(name); |
| 44 |
| 45 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 46 HTypeConversion node, |
| 47 List<jsAst.Expression> arguments) { |
| 48 DartType type = node.typeExpression; |
| 49 assert(!type.isMalformed); |
| 50 String additionalArgument = codegen.backend.namer.operatorIsType(type); |
| 51 arguments.add(js.string(additionalArgument)); |
| 52 } |
| 53 } |
| 54 |
| 55 class TypeVariableCheckedModeHelper extends CheckedModeHelper { |
| 56 const TypeVariableCheckedModeHelper(SourceString name) : super(name); |
| 57 |
| 58 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 59 HTypeConversion node, |
| 60 List<jsAst.Expression> arguments) { |
| 61 assert(node.typeExpression.kind == TypeKind.TYPE_VARIABLE); |
| 62 codegen.use(node.typeRepresentation); |
| 63 arguments.add(codegen.pop()); |
| 64 } |
| 65 } |
| 66 |
| 67 class SubtypeCheckedModeHelper extends CheckedModeHelper { |
| 68 const SubtypeCheckedModeHelper(SourceString name) : super(name); |
| 69 |
| 70 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 71 HTypeConversion node, |
| 72 List<jsAst.Expression> arguments) { |
| 73 DartType type = node.typeExpression; |
| 74 Element element = type.element; |
| 75 String isField = codegen.backend.namer.operatorIs(element); |
| 76 arguments.add(js.string(isField)); |
| 77 codegen.use(node.typeRepresentation); |
| 78 arguments.add(codegen.pop()); |
| 79 String asField = codegen.backend.namer.substitutionName(element); |
| 80 arguments.add(js.string(asField)); |
| 81 } |
| 82 } |
| 83 |
| 84 class FunctionTypeCheckedModeHelper extends CheckedModeHelper { |
| 85 const FunctionTypeCheckedModeHelper(SourceString name) : super(name); |
| 86 |
| 87 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 88 HTypeConversion node, |
| 89 List<jsAst.Expression> arguments) { |
| 90 DartType type = node.typeExpression; |
| 91 String signatureName = codegen.backend.namer.getFunctionTypeName(type); |
| 92 arguments.add(js.string(signatureName)); |
| 93 |
| 94 if (type.containsTypeVariables) { |
| 95 ClassElement contextClass = Types.getClassContext(type); |
| 96 String contextName = codegen.backend.namer.getName(contextClass); |
| 97 arguments.add(js.string(contextName)); |
| 98 |
| 99 if (node.contextIsTypeArguments) { |
| 100 arguments.add(new jsAst.LiteralNull()); |
| 101 codegen.use(node.context); |
| 102 arguments.add(codegen.pop()); |
| 103 } else { |
| 104 codegen.use(node.context); |
| 105 arguments.add(codegen.pop()); |
| 106 } |
| 107 } |
| 108 } |
| 109 } |
| 110 |
| 111 class MalformedCheckedModeHelper extends CheckedModeHelper { |
| 112 const MalformedCheckedModeHelper(SourceString name) : super(name); |
| 113 |
| 114 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 115 HTypeConversion node, |
| 116 List<jsAst.Expression> arguments) { |
| 117 DartType type = node.typeExpression; |
| 118 assert(type.isMalformed); |
| 119 String reasons = Types.fetchReasonsFromMalformedType(type); |
| 120 arguments.add(js.string('$type')); |
| 121 // TODO(johnniwinther): Handle escaping correctly. |
| 122 arguments.add(js.string(reasons)); |
| 123 } |
| 124 } |
| 125 |
| 126 |
14 class JavaScriptBackend extends Backend { | 127 class JavaScriptBackend extends Backend { |
15 SsaBuilderTask builder; | 128 SsaBuilderTask builder; |
16 SsaOptimizerTask optimizer; | 129 SsaOptimizerTask optimizer; |
17 SsaCodeGeneratorTask generator; | 130 SsaCodeGeneratorTask generator; |
18 CodeEmitterTask emitter; | 131 CodeEmitterTask emitter; |
19 | 132 |
20 /** | 133 /** |
21 * The generated code as a js AST for compiled methods. | 134 * The generated code as a js AST for compiled methods. |
22 */ | 135 */ |
23 Map<Element, jsAst.Expression> get generatedCode { | 136 Map<Element, jsAst.Expression> get generatedCode { |
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 } | 719 } |
607 | 720 |
608 void registerSetRuntimeType(TreeElements elements) { | 721 void registerSetRuntimeType(TreeElements elements) { |
609 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 722 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
610 } | 723 } |
611 | 724 |
612 void registerGetRuntimeTypeArgument(TreeElements elements) { | 725 void registerGetRuntimeTypeArgument(TreeElements elements) { |
613 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 726 enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
614 } | 727 } |
615 | 728 |
616 void registerRuntimeType(TreeElements elements) { | 729 void registerGenericCallMethod(Element callMethod, |
| 730 Enqueuer enqueuer, TreeElements elements) { |
| 731 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { |
| 732 registerComputeSignature(enqueuer, elements); |
| 733 } |
| 734 } |
| 735 |
| 736 void registerGenericClosure(Element closure, |
| 737 Enqueuer enqueuer, TreeElements elements) { |
| 738 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { |
| 739 registerComputeSignature(enqueuer, elements); |
| 740 } |
| 741 } |
| 742 |
| 743 void registerComputeSignature(Enqueuer enqueuer, TreeElements elements) { |
| 744 // Calls to [:computeSignature:] are generated by the emitter and we |
| 745 // therefore need to enqueue the used elements in the codegen enqueuer as |
| 746 // well as in the resolution enqueuer. |
| 747 enqueue(enqueuer, getSetRuntimeTypeInfo(), elements); |
| 748 enqueue(enqueuer, getGetRuntimeTypeInfo(), elements); |
| 749 enqueue(enqueuer, getComputeSignature(), elements); |
| 750 enqueue(enqueuer, getGetRuntimeTypeArguments(), elements); |
| 751 enqueuer.registerInstantiatedClass(compiler.listClass, elements); |
| 752 } |
| 753 |
| 754 void registerRuntimeType(Enqueuer enqueuer, TreeElements elements) { |
| 755 registerComputeSignature(enqueuer, elements); |
617 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 756 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
618 enqueueInResolution(getGetRuntimeTypeInfo(), elements); | 757 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
619 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 758 registerGetRuntimeTypeArgument(elements); |
620 compiler.enqueuer.resolution.registerInstantiatedClass( | 759 compiler.enqueuer.resolution.registerInstantiatedClass( |
621 compiler.listClass, elements); | 760 compiler.listClass, elements); |
622 } | 761 } |
623 | 762 |
624 void registerTypeVariableExpression(TreeElements elements) { | 763 void registerTypeVariableExpression(TreeElements elements) { |
625 registerRuntimeType(elements); | 764 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
| 765 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
| 766 registerGetRuntimeTypeArgument(elements); |
| 767 compiler.enqueuer.resolution.registerInstantiatedClass( |
| 768 compiler.listClass, elements); |
626 enqueueInResolution(getRuntimeTypeToString(), elements); | 769 enqueueInResolution(getRuntimeTypeToString(), elements); |
627 enqueueInResolution(getCreateRuntimeType(), elements); | 770 enqueueInResolution(getCreateRuntimeType(), elements); |
628 } | 771 } |
629 | 772 |
630 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { | 773 void registerIsCheck(DartType type, Enqueuer world, TreeElements elements) { |
| 774 type = type.unalias(compiler); |
631 world.registerInstantiatedClass(compiler.boolClass, elements); | 775 world.registerInstantiatedClass(compiler.boolClass, elements); |
| 776 bool inCheckedMode = compiler.enableTypeAssertions; |
| 777 // [registerIsCheck] is also called for checked mode checks, so we |
| 778 // need to register checked mode helpers. |
| 779 if (inCheckedMode) { |
| 780 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: false); |
| 781 if (helper != null) world.addToWorkList(helper.getElement(compiler)); |
| 782 // We also need the native variant of the check (for DOM types). |
| 783 helper = getNativeCheckedModeHelper(type, typeCast: false); |
| 784 if (helper != null) world.addToWorkList(helper.getElement(compiler)); |
| 785 if (type.isMalformed) { |
| 786 enqueueInResolution(getThrowMalformedSubtypeError(), elements); |
| 787 return; |
| 788 } |
| 789 } else if (type.isMalformed) { |
| 790 registerThrowRuntimeError(elements); |
| 791 return; |
| 792 } |
632 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; | 793 bool isTypeVariable = type.kind == TypeKind.TYPE_VARIABLE; |
633 bool inCheckedMode = compiler.enableTypeAssertions; | 794 if (!type.isRaw || type.containsTypeVariables) { |
634 if (!type.isRaw || isTypeVariable) { | |
635 enqueueInResolution(getSetRuntimeTypeInfo(), elements); | 795 enqueueInResolution(getSetRuntimeTypeInfo(), elements); |
636 enqueueInResolution(getGetRuntimeTypeInfo(), elements); | 796 enqueueInResolution(getGetRuntimeTypeInfo(), elements); |
637 enqueueInResolution(getGetRuntimeTypeArgument(), elements); | 797 enqueueInResolution(getGetRuntimeTypeArgument(), elements); |
638 if (inCheckedMode) { | 798 if (inCheckedMode) { |
639 enqueueInResolution(getAssertSubtype(), elements); | 799 enqueueInResolution(getAssertSubtype(), elements); |
640 } | 800 } |
641 enqueueInResolution(getCheckSubtype(), elements); | 801 enqueueInResolution(getCheckSubtype(), elements); |
642 if (isTypeVariable) { | 802 if (isTypeVariable) { |
643 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); | 803 enqueueInResolution(getCheckSubtypeOfRuntimeType(), elements); |
644 if (inCheckedMode) { | 804 if (inCheckedMode) { |
645 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); | 805 enqueueInResolution(getAssertSubtypeOfRuntimeType(), elements); |
646 } | 806 } |
647 } | 807 } |
648 world.registerInstantiatedClass(compiler.listClass, elements); | 808 world.registerInstantiatedClass(compiler.listClass, elements); |
649 } | 809 } |
650 // [registerIsCheck] is also called for checked mode checks, so we | 810 if (type is FunctionType) { |
651 // need to register checked mode helpers. | 811 enqueueInResolution(getCheckFunctionSubtype(), elements); |
652 if (inCheckedMode) { | |
653 Element e = getCheckedModeHelper(type, typeCast: false); | |
654 if (e != null) world.addToWorkList(e); | |
655 // We also need the native variant of the check (for DOM types). | |
656 e = getNativeCheckedModeHelper(type, typeCast: false); | |
657 if (e != null) world.addToWorkList(e); | |
658 } | 812 } |
659 if (type.element.isNative()) { | 813 if (type.element.isNative()) { |
660 // We will neeed to add the "$is" and "$as" properties on the | 814 // We will neeed to add the "$is" and "$as" properties on the |
661 // JavaScript object prototype, so we make sure | 815 // JavaScript object prototype, so we make sure |
662 // [:defineProperty:] is compiled. | 816 // [:defineProperty:] is compiled. |
663 world.addToWorkList( | 817 world.addToWorkList( |
664 compiler.findHelper(const SourceString('defineProperty'))); | 818 compiler.findHelper(const SourceString('defineProperty'))); |
665 } | 819 } |
666 } | 820 } |
667 | 821 |
668 void registerAsCheck(DartType type, TreeElements elements) { | 822 void registerAsCheck(DartType type, TreeElements elements) { |
669 Element e = getCheckedModeHelper(type, typeCast: true); | 823 type = type.unalias(compiler); |
670 enqueueInResolution(e, elements); | 824 CheckedModeHelper helper = getCheckedModeHelper(type, typeCast: true); |
| 825 enqueueInResolution(helper.getElement(compiler), elements); |
671 // We also need the native variant of the check (for DOM types). | 826 // We also need the native variant of the check (for DOM types). |
672 e = getNativeCheckedModeHelper(type, typeCast: true); | 827 helper = getNativeCheckedModeHelper(type, typeCast: true); |
673 enqueueInResolution(e, elements); | 828 if (helper != null) { |
| 829 enqueueInResolution(helper.getElement(compiler), elements); |
| 830 } |
674 } | 831 } |
675 | 832 |
676 void registerThrowNoSuchMethod(TreeElements elements) { | 833 void registerThrowNoSuchMethod(TreeElements elements) { |
677 enqueueInResolution(getThrowNoSuchMethod(), elements); | 834 enqueueInResolution(getThrowNoSuchMethod(), elements); |
678 } | 835 } |
679 | 836 |
680 void registerThrowRuntimeError(TreeElements elements) { | 837 void registerThrowRuntimeError(TreeElements elements) { |
681 enqueueInResolution(getThrowRuntimeError(), elements); | 838 enqueueInResolution(getThrowRuntimeError(), elements); |
682 } | 839 } |
683 | 840 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 analyzeTypeArgument(type, argument); | 884 analyzeTypeArgument(type, argument); |
728 }); | 885 }); |
729 } | 886 } |
730 // TODO(ngeoffray): Also handle T a (in checked mode). | 887 // TODO(ngeoffray): Also handle T a (in checked mode). |
731 } | 888 } |
732 | 889 |
733 void registerClassUsingVariableExpression(ClassElement cls) { | 890 void registerClassUsingVariableExpression(ClassElement cls) { |
734 rti.classesUsingTypeVariableExpression.add(cls); | 891 rti.classesUsingTypeVariableExpression.add(cls); |
735 } | 892 } |
736 | 893 |
737 bool needsRti(ClassElement cls) { | 894 bool classNeedsRti(ClassElement cls) { |
738 return rti.classesNeedingRti.contains(cls.declaration) || | 895 return rti.classesNeedingRti.contains(cls.declaration) || |
739 compiler.enabledRuntimeType; | 896 compiler.enabledRuntimeType; |
740 } | 897 } |
741 | 898 |
742 bool isDefaultNoSuchMethodImplementation(Element element) { | 899 bool isDefaultNoSuchMethodImplementation(Element element) { |
743 assert(element.name == Compiler.NO_SUCH_METHOD); | 900 assert(element.name == Compiler.NO_SUCH_METHOD); |
744 ClassElement classElement = element.getEnclosingClass(); | 901 ClassElement classElement = element.getEnclosingClass(); |
745 return classElement == compiler.objectClass | 902 return classElement == compiler.objectClass |
746 || classElement == jsInterceptorClass; | 903 || classElement == jsInterceptorClass; |
747 } | 904 } |
748 | 905 |
749 bool isDefaultEqualityImplementation(Element element) { | 906 bool isDefaultEqualityImplementation(Element element) { |
750 assert(element.name == const SourceString('==')); | 907 assert(element.name == const SourceString('==')); |
751 ClassElement classElement = element.getEnclosingClass(); | 908 ClassElement classElement = element.getEnclosingClass(); |
752 return classElement == compiler.objectClass | 909 return classElement == compiler.objectClass |
753 || classElement == jsInterceptorClass | 910 || classElement == jsInterceptorClass |
754 || classElement == jsNullClass; | 911 || classElement == jsNullClass; |
755 } | 912 } |
756 | 913 |
| 914 bool methodNeedsRti(FunctionElement function) { |
| 915 return rti.methodsNeedingRti.contains(function) || |
| 916 compiler.enabledRuntimeType; |
| 917 } |
| 918 |
| 919 void enqueue(Enqueuer enqueuer, Element e, TreeElements elements) { |
| 920 enqueuer.addToWorkList(e); |
| 921 elements.registerDependency(e); |
| 922 } |
| 923 |
757 void enqueueInResolution(Element e, TreeElements elements) { | 924 void enqueueInResolution(Element e, TreeElements elements) { |
758 if (e == null) return; | 925 if (e == null) return; |
759 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; | 926 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; |
760 enqueuer.addToWorkList(e); | 927 enqueue(enqueuer, e, elements); |
761 elements.registerDependency(e); | |
762 } | 928 } |
763 | 929 |
764 void registerConstantMap(TreeElements elements) { | 930 void registerConstantMap(TreeElements elements) { |
765 Element e = compiler.findHelper(const SourceString('ConstantMap')); | 931 Element e = compiler.findHelper(const SourceString('ConstantMap')); |
766 if (e != null) { | 932 if (e != null) { |
767 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements); | 933 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements); |
768 } | 934 } |
769 e = compiler.findHelper(const SourceString('ConstantProtoMap')); | 935 e = compiler.findHelper(const SourceString('ConstantProtoMap')); |
770 if (e != null) { | 936 if (e != null) { |
771 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements); | 937 compiler.enqueuer.resolution.registerInstantiatedClass(e, elements); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 return element; | 1016 return element; |
851 } | 1017 } |
852 } | 1018 } |
853 | 1019 |
854 /** | 1020 /** |
855 * Returns the checked mode helper that will be needed to do a type check/type | 1021 * Returns the checked mode helper that will be needed to do a type check/type |
856 * cast on [type] at runtime. Note that this method is being called both by | 1022 * cast on [type] at runtime. Note that this method is being called both by |
857 * the resolver with interface types (int, String, ...), and by the SSA | 1023 * the resolver with interface types (int, String, ...), and by the SSA |
858 * backend with implementation types (JSInt, JSString, ...). | 1024 * backend with implementation types (JSInt, JSString, ...). |
859 */ | 1025 */ |
860 Element getCheckedModeHelper(DartType type, {bool typeCast}) { | 1026 CheckedModeHelper getCheckedModeHelper(DartType type, {bool typeCast}) { |
861 SourceString name = getCheckedModeHelperName( | 1027 return getCheckedModeHelperInternal( |
862 type, typeCast: typeCast, nativeCheckOnly: false); | 1028 type, typeCast: typeCast, nativeCheckOnly: false); |
863 return compiler.findHelper(name); | |
864 } | 1029 } |
865 | 1030 |
866 /** | 1031 /** |
867 * Returns the native checked mode helper that will be needed to do a type | 1032 * Returns the native checked mode helper that will be needed to do a type |
868 * check/type cast on [type] at runtime. If no native helper exists for | 1033 * check/type cast on [type] at runtime. If no native helper exists for |
869 * [type], [:null:] is returned. | 1034 * [type], [:null:] is returned. |
870 */ | 1035 */ |
871 Element getNativeCheckedModeHelper(DartType type, {bool typeCast}) { | 1036 CheckedModeHelper getNativeCheckedModeHelper(DartType type, {bool typeCast}) { |
872 SourceString sourceName = getCheckedModeHelperName( | 1037 return getCheckedModeHelperInternal( |
873 type, typeCast: typeCast, nativeCheckOnly: true); | 1038 type, typeCast: typeCast, nativeCheckOnly: true); |
874 if (sourceName == null) return null; | |
875 return compiler.findHelper(sourceName); | |
876 } | 1039 } |
877 | 1040 |
878 /** | 1041 /** |
879 * Returns the name of the type check/type cast helper method for [type]. If | 1042 * Returns the checked mode helper for the type check/type cast for [type]. If |
880 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. | 1043 * [nativeCheckOnly] is [:true:], only names for native helpers are returned. |
881 */ | 1044 */ |
882 SourceString getCheckedModeHelperName(DartType type, | 1045 CheckedModeHelper getCheckedModeHelperInternal(DartType type, |
883 {bool typeCast, | 1046 {bool typeCast, |
884 bool nativeCheckOnly}) { | 1047 bool nativeCheckOnly}) { |
| 1048 assert(type.kind != TypeKind.TYPEDEF); |
885 Element element = type.element; | 1049 Element element = type.element; |
886 bool nativeCheck = nativeCheckOnly || | 1050 bool nativeCheck = nativeCheckOnly || |
887 emitter.nativeEmitter.requiresNativeIsCheck(element); | 1051 emitter.nativeEmitter.requiresNativeIsCheck(element); |
888 if (type.isMalformed) { | 1052 if (type.isMalformed) { |
889 // Check for malformed types first, because the type may be a list type | 1053 // Check for malformed types first, because the type may be a list type |
890 // with a malformed argument type. | 1054 // with a malformed argument type. |
891 if (nativeCheckOnly) return null; | 1055 if (nativeCheckOnly) return null; |
892 return typeCast | 1056 return typeCast |
893 ? const SourceString('malformedTypeCast') | 1057 ? const MalformedCheckedModeHelper( |
894 : const SourceString('malformedTypeCheck'); | 1058 const SourceString('malformedTypeCast')) |
| 1059 : const MalformedCheckedModeHelper( |
| 1060 const SourceString('malformedTypeCheck')); |
895 } else if (type == compiler.types.voidType) { | 1061 } else if (type == compiler.types.voidType) { |
896 assert(!typeCast); // Cannot cast to void. | 1062 assert(!typeCast); // Cannot cast to void. |
897 if (nativeCheckOnly) return null; | 1063 if (nativeCheckOnly) return null; |
898 return const SourceString('voidTypeCheck'); | 1064 return const CheckedModeHelper(const SourceString('voidTypeCheck')); |
899 } else if (element == jsStringClass || element == compiler.stringClass) { | 1065 } else if (element == jsStringClass || element == compiler.stringClass) { |
900 if (nativeCheckOnly) return null; | 1066 if (nativeCheckOnly) return null; |
901 return typeCast | 1067 return typeCast |
902 ? const SourceString("stringTypeCast") | 1068 ? const CheckedModeHelper(const SourceString("stringTypeCast")) |
903 : const SourceString('stringTypeCheck'); | 1069 : const CheckedModeHelper(const SourceString('stringTypeCheck')); |
904 } else if (element == jsDoubleClass || element == compiler.doubleClass) { | 1070 } else if (element == jsDoubleClass || element == compiler.doubleClass) { |
905 if (nativeCheckOnly) return null; | 1071 if (nativeCheckOnly) return null; |
906 return typeCast | 1072 return typeCast |
907 ? const SourceString("doubleTypeCast") | 1073 ? const CheckedModeHelper(const SourceString("doubleTypeCast")) |
908 : const SourceString('doubleTypeCheck'); | 1074 : const CheckedModeHelper(const SourceString('doubleTypeCheck')); |
909 } else if (element == jsNumberClass || element == compiler.numClass) { | 1075 } else if (element == jsNumberClass || element == compiler.numClass) { |
910 if (nativeCheckOnly) return null; | 1076 if (nativeCheckOnly) return null; |
911 return typeCast | 1077 return typeCast |
912 ? const SourceString("numTypeCast") | 1078 ? const CheckedModeHelper(const SourceString("numTypeCast")) |
913 : const SourceString('numTypeCheck'); | 1079 : const CheckedModeHelper(const SourceString('numTypeCheck')); |
914 } else if (element == jsBoolClass || element == compiler.boolClass) { | 1080 } else if (element == jsBoolClass || element == compiler.boolClass) { |
915 if (nativeCheckOnly) return null; | 1081 if (nativeCheckOnly) return null; |
916 return typeCast | 1082 return typeCast |
917 ? const SourceString("boolTypeCast") | 1083 ? const CheckedModeHelper(const SourceString("boolTypeCast")) |
918 : const SourceString('boolTypeCheck'); | 1084 : const CheckedModeHelper(const SourceString('boolTypeCheck')); |
919 } else if (element == jsIntClass || element == compiler.intClass) { | 1085 } else if (element == jsIntClass || element == compiler.intClass) { |
920 if (nativeCheckOnly) return null; | 1086 if (nativeCheckOnly) return null; |
921 return typeCast ? | 1087 return typeCast |
922 const SourceString("intTypeCast") : | 1088 ? const CheckedModeHelper(const SourceString("intTypeCast")) |
923 const SourceString('intTypeCheck'); | 1089 : const CheckedModeHelper(const SourceString('intTypeCheck')); |
924 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { | 1090 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { |
925 if (nativeCheck) { | 1091 if (nativeCheck) { |
926 return typeCast | 1092 return typeCast |
927 ? const SourceString("numberOrStringSuperNativeTypeCast") | 1093 ? const PropertyCheckedModeHelper( |
928 : const SourceString('numberOrStringSuperNativeTypeCheck'); | 1094 const SourceString("numberOrStringSuperNativeTypeCast")) |
| 1095 : const PropertyCheckedModeHelper( |
| 1096 const SourceString('numberOrStringSuperNativeTypeCheck')); |
929 } else { | 1097 } else { |
930 return typeCast | 1098 return typeCast |
931 ? const SourceString("numberOrStringSuperTypeCast") | 1099 ? const PropertyCheckedModeHelper( |
932 : const SourceString('numberOrStringSuperTypeCheck'); | 1100 const SourceString("numberOrStringSuperTypeCast")) |
| 1101 : const PropertyCheckedModeHelper( |
| 1102 const SourceString('numberOrStringSuperTypeCheck')); |
933 } | 1103 } |
934 } else if (Elements.isStringOnlySupertype(element, compiler)) { | 1104 } else if (Elements.isStringOnlySupertype(element, compiler)) { |
935 if (nativeCheck) { | 1105 if (nativeCheck) { |
936 return typeCast | 1106 return typeCast |
937 ? const SourceString("stringSuperNativeTypeCast") | 1107 ? const PropertyCheckedModeHelper( |
938 : const SourceString('stringSuperNativeTypeCheck'); | 1108 const SourceString("stringSuperNativeTypeCast")) |
| 1109 : const PropertyCheckedModeHelper( |
| 1110 const SourceString('stringSuperNativeTypeCheck')); |
939 } else { | 1111 } else { |
940 return typeCast | 1112 return typeCast |
941 ? const SourceString("stringSuperTypeCast") | 1113 ? const PropertyCheckedModeHelper( |
942 : const SourceString('stringSuperTypeCheck'); | 1114 const SourceString("stringSuperTypeCast")) |
| 1115 : const PropertyCheckedModeHelper( |
| 1116 const SourceString('stringSuperTypeCheck')); |
943 } | 1117 } |
944 } else if ((element == compiler.listClass || element == jsArrayClass) && | 1118 } else if ((element == compiler.listClass || element == jsArrayClass) && |
945 type.isRaw) { | 1119 type.isRaw) { |
946 if (nativeCheckOnly) return null; | 1120 if (nativeCheckOnly) return null; |
947 return typeCast | 1121 return typeCast |
948 ? const SourceString("listTypeCast") | 1122 ? const CheckedModeHelper(const SourceString("listTypeCast")) |
949 : const SourceString('listTypeCheck'); | 1123 : const CheckedModeHelper(const SourceString('listTypeCheck')); |
950 } else { | 1124 } else { |
951 if (Elements.isListSupertype(element, compiler)) { | 1125 if (Elements.isListSupertype(element, compiler)) { |
952 if (nativeCheck) { | 1126 if (nativeCheck) { |
953 return typeCast | 1127 return typeCast |
954 ? const SourceString("listSuperNativeTypeCast") | 1128 ? const PropertyCheckedModeHelper( |
955 : const SourceString('listSuperNativeTypeCheck'); | 1129 const SourceString("listSuperNativeTypeCast")) |
| 1130 : const PropertyCheckedModeHelper( |
| 1131 const SourceString('listSuperNativeTypeCheck')); |
956 } else { | 1132 } else { |
957 return typeCast | 1133 return typeCast |
958 ? const SourceString("listSuperTypeCast") | 1134 ? const PropertyCheckedModeHelper( |
959 : const SourceString('listSuperTypeCheck'); | 1135 const SourceString("listSuperTypeCast")) |
| 1136 : const PropertyCheckedModeHelper( |
| 1137 const SourceString('listSuperTypeCheck')); |
960 } | 1138 } |
961 } else { | 1139 } else { |
962 if (nativeCheck) { | 1140 if (nativeCheck) { |
963 // TODO(karlklose): can we get rid of this branch when we use | 1141 // TODO(karlklose): can we get rid of this branch when we use |
964 // interceptors? | 1142 // interceptors? |
965 return typeCast | 1143 return typeCast |
966 ? const SourceString("interceptedTypeCast") | 1144 ? const PropertyCheckedModeHelper( |
967 : const SourceString('interceptedTypeCheck'); | 1145 const SourceString("interceptedTypeCast")) |
| 1146 : const PropertyCheckedModeHelper( |
| 1147 const SourceString('interceptedTypeCheck')); |
968 } else { | 1148 } else { |
969 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { | 1149 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { |
970 return typeCast | 1150 return typeCast |
971 ? const SourceString('subtypeCast') | 1151 ? const SubtypeCheckedModeHelper( |
972 : const SourceString('assertSubtype'); | 1152 const SourceString('subtypeCast')) |
| 1153 : const SubtypeCheckedModeHelper( |
| 1154 const SourceString('assertSubtype')); |
973 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1155 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
974 return typeCast | 1156 return typeCast |
975 ? const SourceString('subtypeOfRuntimeTypeCast') | 1157 ? const TypeVariableCheckedModeHelper( |
976 : const SourceString('assertSubtypeOfRuntimeType'); | 1158 const SourceString('subtypeOfRuntimeTypeCast')) |
| 1159 : const TypeVariableCheckedModeHelper( |
| 1160 const SourceString('assertSubtypeOfRuntimeType')); |
| 1161 } else if (type.kind == TypeKind.FUNCTION) { |
| 1162 return typeCast |
| 1163 ? const FunctionTypeCheckedModeHelper( |
| 1164 const SourceString('functionSubtypeCast')) |
| 1165 : const FunctionTypeCheckedModeHelper( |
| 1166 const SourceString('assertFunctionSubtype')); |
977 } else { | 1167 } else { |
978 return typeCast | 1168 return typeCast |
979 ? const SourceString('propertyTypeCast') | 1169 ? const PropertyCheckedModeHelper( |
980 : const SourceString('propertyTypeCheck'); | 1170 const SourceString('propertyTypeCast')) |
| 1171 : const PropertyCheckedModeHelper( |
| 1172 const SourceString('propertyTypeCheck')); |
981 } | 1173 } |
982 } | 1174 } |
983 } | 1175 } |
984 } | 1176 } |
985 } | 1177 } |
986 | 1178 |
987 Element getExceptionUnwrapper() { | 1179 Element getExceptionUnwrapper() { |
988 return compiler.findHelper(const SourceString('unwrapException')); | 1180 return compiler.findHelper(const SourceString('unwrapException')); |
989 } | 1181 } |
990 | 1182 |
991 Element getThrowRuntimeError() { | 1183 Element getThrowRuntimeError() { |
992 return compiler.findHelper(const SourceString('throwRuntimeError')); | 1184 return compiler.findHelper(const SourceString('throwRuntimeError')); |
993 } | 1185 } |
994 | 1186 |
| 1187 Element getMalformedTypeCheck() { |
| 1188 return compiler.findHelper(const SourceString('malformedTypeCheck')); |
| 1189 } |
| 1190 |
995 Element getThrowMalformedSubtypeError() { | 1191 Element getThrowMalformedSubtypeError() { |
996 return compiler.findHelper( | 1192 return compiler.findHelper( |
997 const SourceString('throwMalformedSubtypeError')); | 1193 const SourceString('throwMalformedSubtypeError')); |
998 } | 1194 } |
999 | 1195 |
1000 Element getThrowAbstractClassInstantiationError() { | 1196 Element getThrowAbstractClassInstantiationError() { |
1001 return compiler.findHelper( | 1197 return compiler.findHelper( |
1002 const SourceString('throwAbstractClassInstantiationError')); | 1198 const SourceString('throwAbstractClassInstantiationError')); |
1003 } | 1199 } |
1004 | 1200 |
(...skipping 22 matching lines...) Expand all Loading... |
1027 } | 1223 } |
1028 | 1224 |
1029 Element getSetRuntimeTypeInfo() { | 1225 Element getSetRuntimeTypeInfo() { |
1030 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); | 1226 return compiler.findHelper(const SourceString('setRuntimeTypeInfo')); |
1031 } | 1227 } |
1032 | 1228 |
1033 Element getGetRuntimeTypeInfo() { | 1229 Element getGetRuntimeTypeInfo() { |
1034 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); | 1230 return compiler.findHelper(const SourceString('getRuntimeTypeInfo')); |
1035 } | 1231 } |
1036 | 1232 |
| 1233 Element getComputeSignature() { |
| 1234 return compiler.findHelper(const SourceString('computeSignature')); |
| 1235 } |
| 1236 |
| 1237 Element getGetRuntimeTypeArguments() { |
| 1238 return compiler.findHelper(const SourceString('getRuntimeTypeArguments')); |
| 1239 } |
| 1240 |
1037 Element getGetRuntimeTypeArgument() { | 1241 Element getGetRuntimeTypeArgument() { |
1038 return compiler.findHelper(const SourceString('getRuntimeTypeArgument')); | 1242 return compiler.findHelper(const SourceString('getRuntimeTypeArgument')); |
1039 } | 1243 } |
1040 | 1244 |
1041 Element getRuntimeTypeToString() { | 1245 Element getRuntimeTypeToString() { |
1042 return compiler.findHelper(const SourceString('runtimeTypeToString')); | 1246 return compiler.findHelper(const SourceString('runtimeTypeToString')); |
1043 } | 1247 } |
1044 | 1248 |
1045 Element getCheckSubtype() { | 1249 Element getCheckSubtype() { |
1046 return compiler.findHelper(const SourceString('checkSubtype')); | 1250 return compiler.findHelper(const SourceString('checkSubtype')); |
1047 } | 1251 } |
1048 | 1252 |
1049 Element getAssertSubtype() { | 1253 Element getAssertSubtype() { |
1050 return compiler.findHelper(const SourceString('assertSubtype')); | 1254 return compiler.findHelper(const SourceString('assertSubtype')); |
1051 } | 1255 } |
1052 | 1256 |
1053 Element getCheckSubtypeOfRuntimeType() { | 1257 Element getCheckSubtypeOfRuntimeType() { |
1054 return compiler.findHelper(const SourceString('checkSubtypeOfRuntimeType')); | 1258 return compiler.findHelper(const SourceString('checkSubtypeOfRuntimeType')); |
1055 } | 1259 } |
1056 | 1260 |
1057 Element getAssertSubtypeOfRuntimeType() { | 1261 Element getAssertSubtypeOfRuntimeType() { |
1058 return compiler.findHelper( | 1262 return compiler.findHelper( |
1059 const SourceString('assertSubtypeOfRuntimeType')); | 1263 const SourceString('assertSubtypeOfRuntimeType')); |
1060 } | 1264 } |
1061 | 1265 |
| 1266 Element getCheckFunctionSubtype() { |
| 1267 return compiler.findHelper(const SourceString('checkFunctionSubtype')); |
| 1268 } |
| 1269 |
1062 Element getThrowNoSuchMethod() { | 1270 Element getThrowNoSuchMethod() { |
1063 return compiler.findHelper(const SourceString('throwNoSuchMethod')); | 1271 return compiler.findHelper(const SourceString('throwNoSuchMethod')); |
1064 } | 1272 } |
1065 | 1273 |
1066 Element getCreateRuntimeType() { | 1274 Element getCreateRuntimeType() { |
1067 return compiler.findHelper(const SourceString('createRuntimeType')); | 1275 return compiler.findHelper(const SourceString('createRuntimeType')); |
1068 } | 1276 } |
1069 | 1277 |
1070 Element getFallThroughError() { | 1278 Element getFallThroughError() { |
1071 return compiler.findHelper(const SourceString("getFallThroughError")); | 1279 return compiler.findHelper(const SourceString("getFallThroughError")); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 } | 1327 } |
1120 | 1328 |
1121 void registerStaticUse(Element element, Enqueuer enqueuer) { | 1329 void registerStaticUse(Element element, Enqueuer enqueuer) { |
1122 if (element == disableTreeShakingMarker) { | 1330 if (element == disableTreeShakingMarker) { |
1123 enqueuer.enqueueEverything(); | 1331 enqueuer.enqueueEverything(); |
1124 compiler.disableTypeInferenceForMirrors = true; | 1332 compiler.disableTypeInferenceForMirrors = true; |
1125 } else if (element == preserveNamesMarker) { | 1333 } else if (element == preserveNamesMarker) { |
1126 } | 1334 } |
1127 } | 1335 } |
1128 } | 1336 } |
OLD | NEW |