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 import 'dart:math' as math; | 5 import 'dart:math' as math; |
6 import '../common.dart'; | 6 import '../common.dart'; |
7 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 7 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
8 import '../common/tasks.dart' show CompilerTask; | 8 import '../common/tasks.dart' show CompilerTask; |
9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
10 import '../constants/constant_system.dart'; | 10 import '../constants/constant_system.dart'; |
(...skipping 2875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2886 registry.registerTypeUse(new TypeUse.isCheck(type)); | 2886 registry.registerTypeUse(new TypeUse.isCheck(type)); |
2887 | 2887 |
2888 CheckedModeHelper helper; | 2888 CheckedModeHelper helper; |
2889 if (node.isBooleanConversionCheck) { | 2889 if (node.isBooleanConversionCheck) { |
2890 helper = const CheckedModeHelper('boolConversionCheck'); | 2890 helper = const CheckedModeHelper('boolConversionCheck'); |
2891 } else { | 2891 } else { |
2892 helper = backend.checkedModeHelpers | 2892 helper = backend.checkedModeHelpers |
2893 .getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); | 2893 .getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); |
2894 } | 2894 } |
2895 | 2895 |
2896 if (helper == null) { | 2896 push(helper.generateCall(this, node)); |
2897 assert(type.isFunctionType); | |
2898 assert(node.usesMethodOnType); | |
2899 | |
2900 String name = node.isCastTypeCheck ? '_asCheck' : '_assertCheck'; | |
2901 HInstruction reifiedType = node.inputs[0]; | |
2902 HInstruction checkedInput = node.inputs[1]; | |
2903 use(reifiedType); | |
2904 js.Expression receiver = pop(); | |
2905 use(checkedInput); | |
2906 Selector selector = new Selector.call( | |
2907 new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG); | |
2908 registry.registerDynamicUse( | |
2909 new DynamicUse(selector, reifiedType.instructionType)); | |
2910 js.Name methodLiteral = backend.namer.invocationName(selector); | |
2911 push(js.js('#.#(#)', [receiver, methodLiteral, pop()])); | |
2912 } else { | |
2913 assert(!node.usesMethodOnType); | |
2914 push(helper.generateCall(this, node)); | |
2915 } | |
2916 } | 2897 } |
2917 | 2898 |
2918 void visitTypeKnown(HTypeKnown node) { | 2899 void visitTypeKnown(HTypeKnown node) { |
2919 // [HTypeKnown] instructions are removed before generating code. | 2900 // [HTypeKnown] instructions are removed before generating code. |
2920 assert(false); | 2901 assert(false); |
2921 } | 2902 } |
2922 | 2903 |
2923 void visitFunctionType(HFunctionType node) { | |
2924 FunctionType type = node.dartType; | |
2925 int inputCount = 0; | |
2926 use(node.inputs[inputCount++]); | |
2927 js.Expression returnType = pop(); | |
2928 | |
2929 List<js.Expression> parameterTypes = <js.Expression>[]; | |
2930 for (var _ in type.parameterTypes) { | |
2931 use(node.inputs[inputCount++]); | |
2932 parameterTypes.add(pop()); | |
2933 } | |
2934 | |
2935 List<js.Expression> optionalParameterTypes = <js.Expression>[]; | |
2936 for (var _ in type.optionalParameterTypes) { | |
2937 use(node.inputs[inputCount++]); | |
2938 optionalParameterTypes.add(pop()); | |
2939 } | |
2940 | |
2941 List<js.Property> namedParameters = <js.Property>[]; | |
2942 for (var _ in type.namedParameters) { | |
2943 use(node.inputs[inputCount++]); | |
2944 js.Expression name = pop(); | |
2945 use(node.inputs[inputCount++]); | |
2946 namedParameters.add(new js.Property(name, pop())); | |
2947 } | |
2948 | |
2949 if (namedParameters.isEmpty) { | |
2950 var arguments = [returnType]; | |
2951 if (!parameterTypes.isEmpty || !optionalParameterTypes.isEmpty) { | |
2952 arguments.add(new js.ArrayInitializer(parameterTypes)); | |
2953 } | |
2954 if (!optionalParameterTypes.isEmpty) { | |
2955 arguments.add(new js.ArrayInitializer(optionalParameterTypes)); | |
2956 } | |
2957 push(js.js('#(#)', [accessHelper(helpers.buildFunctionType), arguments])); | |
2958 } else { | |
2959 var arguments = [ | |
2960 returnType, | |
2961 new js.ArrayInitializer(parameterTypes), | |
2962 new js.ObjectInitializer(namedParameters) | |
2963 ]; | |
2964 push(js.js( | |
2965 '#(#)', [accessHelper(helpers.buildNamedFunctionType), arguments])); | |
2966 } | |
2967 } | |
2968 | |
2969 void visitTypeInfoReadRaw(HTypeInfoReadRaw node) { | 2904 void visitTypeInfoReadRaw(HTypeInfoReadRaw node) { |
2970 use(node.inputs[0]); | 2905 use(node.inputs[0]); |
2971 js.Expression receiver = pop(); | 2906 js.Expression receiver = pop(); |
2972 push(js.js(r'#.#', [receiver, backend.namer.rtiFieldJsName])); | 2907 push(js.js(r'#.#', [receiver, backend.namer.rtiFieldJsName])); |
2973 } | 2908 } |
2974 | 2909 |
2975 void visitTypeInfoReadVariable(HTypeInfoReadVariable node) { | 2910 void visitTypeInfoReadVariable(HTypeInfoReadVariable node) { |
2976 TypeVariableEntity element = node.variable.element; | 2911 TypeVariableEntity element = node.variable.element; |
2977 | 2912 |
2978 int index = element.index; | 2913 int index = element.index; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3041 } | 2976 } |
3042 } | 2977 } |
3043 | 2978 |
3044 if (closedWorld.isUsedAsMixin(cls)) return true; | 2979 if (closedWorld.isUsedAsMixin(cls)) return true; |
3045 | 2980 |
3046 return closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { | 2981 return closedWorld.anyStrictSubclassOf(cls, (ClassEntity subclass) { |
3047 return !backend.rti.isTrivialSubstitution(subclass, cls); | 2982 return !backend.rti.isTrivialSubstitution(subclass, cls); |
3048 }); | 2983 }); |
3049 } | 2984 } |
3050 | 2985 |
3051 void visitReadTypeVariable(HReadTypeVariable node) { | |
3052 TypeVariableEntity element = node.dartType.element; | |
3053 FunctionEntity helperElement = helpers.convertRtiToRuntimeType; | |
3054 registry.registerStaticUse( | |
3055 new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG)); | |
3056 | |
3057 use(node.inputs[0]); | |
3058 if (node.hasReceiver) { | |
3059 if (backend.interceptorData.isInterceptorClass(element.typeDeclaration)) { | |
3060 int index = element.index; | |
3061 js.Expression receiver = pop(); | |
3062 js.Expression helper = | |
3063 backend.emitter.staticFunctionAccess(helperElement); | |
3064 js.Expression rtiFieldName = backend.namer.rtiFieldJsName; | |
3065 push(js.js(r'#(#.# && #.#[#])', [ | |
3066 helper, | |
3067 receiver, | |
3068 rtiFieldName, | |
3069 receiver, | |
3070 rtiFieldName, | |
3071 js.js.number(index) | |
3072 ])); | |
3073 } else { | |
3074 backend.emitter.registerReadTypeVariable(element); | |
3075 push(js.js( | |
3076 '#.#()', [pop(), backend.namer.nameForReadTypeVariable(element)])); | |
3077 } | |
3078 } else { | |
3079 push(js.js('#(#)', | |
3080 [backend.emitter.staticFunctionAccess(helperElement), pop()])); | |
3081 } | |
3082 } | |
3083 | |
3084 void visitInterfaceType(HInterfaceType node) { | |
3085 List<js.Expression> typeArguments = <js.Expression>[]; | |
3086 for (HInstruction type in node.inputs) { | |
3087 use(type); | |
3088 typeArguments.add(pop()); | |
3089 } | |
3090 InterfaceType type = node.dartType; | |
3091 ClassEntity cls = type.element; | |
3092 var arguments = [backend.emitter.typeAccess(cls)]; | |
3093 if (!typeArguments.isEmpty) { | |
3094 arguments.add(new js.ArrayInitializer(typeArguments)); | |
3095 } | |
3096 push(js.js('#(#)', [ | |
3097 accessHelper(helpers.buildInterfaceType, arguments.length), | |
3098 arguments | |
3099 ])); | |
3100 } | |
3101 | |
3102 void visitVoidType(HVoidType node) { | |
3103 push(js.js('#()', accessHelper(helpers.getVoidRuntimeType))); | |
3104 } | |
3105 | |
3106 void visitDynamicType(HDynamicType node) { | |
3107 push(js.js('#()', accessHelper(helpers.getDynamicRuntimeType))); | |
3108 } | |
3109 | |
3110 js.PropertyAccess accessHelper(FunctionEntity helper, | |
3111 [int argumentCount = 0]) { | |
3112 if (helper == null) { | |
3113 // For mocked-up tests. | |
3114 return js.js('(void 0).dummy'); | |
3115 } | |
3116 registry.registerStaticUse(new StaticUse.staticInvoke( | |
3117 helper, new CallStructure.unnamed(argumentCount))); | |
3118 return backend.emitter.staticFunctionAccess(helper); | |
3119 } | |
3120 | |
3121 @override | 2986 @override |
3122 void visitRef(HRef node) { | 2987 void visitRef(HRef node) { |
3123 visit(node.value); | 2988 visit(node.value); |
3124 } | 2989 } |
3125 } | 2990 } |
OLD | NEW |