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 class Interceptors { | 5 class Interceptors { |
6 Compiler compiler; | 6 Compiler compiler; |
7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
8 | 8 |
9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
(...skipping 2856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2867 | 2867 |
2868 // Construct the runtime type information. | 2868 // Construct the runtime type information. |
2869 StringBuffer runtimeCode = new StringBuffer(); | 2869 StringBuffer runtimeCode = new StringBuffer(); |
2870 List<HInstruction> runtimeCodeInputs = <HInstruction>[]; | 2870 List<HInstruction> runtimeCodeInputs = <HInstruction>[]; |
2871 if (runtimeTypeIsUsed) { | 2871 if (runtimeTypeIsUsed) { |
2872 String runtimeTypeString = | 2872 String runtimeTypeString = |
2873 rti.generateRuntimeTypeString(element, rtiInputs.length); | 2873 rti.generateRuntimeTypeString(element, rtiInputs.length); |
2874 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs); | 2874 HInstruction runtimeType = createForeign(runtimeTypeString, rtiInputs); |
2875 add(runtimeType); | 2875 add(runtimeType); |
2876 runtimeCodeInputs.add(runtimeType); | 2876 runtimeCodeInputs.add(runtimeType); |
2877 runtimeCode.add('runtimeType: #'); | 2877 runtimeCode.add("runtimeType: '#'"); |
2878 } | 2878 } |
2879 if (needsRti) { | 2879 if (needsRti) { |
2880 if (runtimeTypeIsUsed) runtimeCode.add(', '); | 2880 if (runtimeTypeIsUsed) runtimeCode.add(', '); |
2881 String typeVariablesString = | 2881 String typeVariablesString = |
2882 RuntimeTypeInformation.generateTypeVariableString(element, | 2882 RuntimeTypeInformation.generateTypeVariableString(element, |
2883 rtiInputs.length); | 2883 rtiInputs.length); |
2884 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs); | 2884 HInstruction typeInfo = createForeign(typeVariablesString, rtiInputs); |
2885 add(typeInfo); | 2885 add(typeInfo); |
2886 runtimeCodeInputs.add(typeInfo); | 2886 runtimeCodeInputs.add(typeInfo); |
2887 runtimeCode.add('#'); | 2887 runtimeCode.add('#'); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2945 if (annotation == null) { | 2945 if (annotation == null) { |
2946 compiler.internalError("malformed send in new expression"); | 2946 compiler.internalError("malformed send in new expression"); |
2947 } | 2947 } |
2948 InterfaceType type = elements.getType(annotation); | 2948 InterfaceType type = elements.getType(annotation); |
2949 if (type.element.modifiers.isAbstract() && | 2949 if (type.element.modifiers.isAbstract() && |
2950 constructor.isGenerativeConstructor()) { | 2950 constructor.isGenerativeConstructor()) { |
2951 generateAbstractClassInstantiationError(node, type.name.slowToString()); | 2951 generateAbstractClassInstantiationError(node, type.name.slowToString()); |
2952 return; | 2952 return; |
2953 } | 2953 } |
2954 if (compiler.world.needsRti(constructor.enclosingElement)) { | 2954 if (compiler.world.needsRti(constructor.enclosingElement)) { |
2955 type.arguments.forEach((DartType argument) { | 2955 if (!type.arguments.isEmpty()) { |
2956 inputs.add(analyzeTypeArgument(argument, node)); | 2956 type.arguments.forEach((DartType argument) { |
2957 }); | 2957 inputs.add(analyzeTypeArgument(argument, node)); |
| 2958 }); |
| 2959 } else if (compiler.enabledRuntimeType) { |
| 2960 Link<DartType> variables = |
| 2961 constructor.getEnclosingClass().typeVariables; |
| 2962 if (!variables.isEmpty()) { |
| 2963 // If the class has type variables but no type arguments have been |
| 2964 // provided, add [:dynamic:] as argument for all type variables. |
| 2965 DartString stringDynamic = new DartString.literal('dynamic'); |
| 2966 HInstruction input = graph.addConstantString(stringDynamic, |
| 2967 node, |
| 2968 constantSystem); |
| 2969 variables.forEach((_) => inputs.add(input)); |
| 2970 } |
| 2971 } |
2958 } | 2972 } |
2959 | 2973 |
2960 HType elementType = computeType(constructor); | 2974 HType elementType = computeType(constructor); |
2961 HInstruction newInstance = new HInvokeStatic(inputs, elementType); | 2975 HInstruction newInstance = new HInvokeStatic(inputs, elementType); |
2962 pushWithPosition(newInstance, node); | 2976 pushWithPosition(newInstance, node); |
2963 | 2977 |
2964 // The List constructor forwards to a Dart static method that does | 2978 // The List constructor forwards to a Dart static method that does |
2965 // not know about the type argument. Therefore we special case | 2979 // not know about the type argument. Therefore we special case |
2966 // this constructor to have the setRuntimeTypeInfo called where | 2980 // this constructor to have the setRuntimeTypeInfo called where |
2967 // the 'new' is done. | 2981 // the 'new' is done. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3017 if (returnType != null) instruction.guaranteedType = returnType; | 3031 if (returnType != null) instruction.guaranteedType = returnType; |
3018 pushWithPosition(instruction, node); | 3032 pushWithPosition(instruction, node); |
3019 } else { | 3033 } else { |
3020 generateGetter(node, element); | 3034 generateGetter(node, element); |
3021 List<HInstruction> inputs = <HInstruction>[pop()]; | 3035 List<HInstruction> inputs = <HInstruction>[pop()]; |
3022 addDynamicSendArgumentsToList(node, inputs); | 3036 addDynamicSendArgumentsToList(node, inputs); |
3023 pushWithPosition(new HInvokeClosure(selector, inputs), node); | 3037 pushWithPosition(new HInvokeClosure(selector, inputs), node); |
3024 } | 3038 } |
3025 } | 3039 } |
3026 | 3040 |
| 3041 visitTypeReferenceSend(Send node) { |
| 3042 ClassElement element = elements[node]; |
| 3043 String string = rti.generateRuntimeTypeString(element, 0); |
| 3044 DartString className = new DartString.literal(string); |
| 3045 Element helper = |
| 3046 compiler.findHelper(const SourceString('getOrCreateCachedRuntimeType')); |
| 3047 Constant typeName = constantSystem.createString(className, node.selector); |
| 3048 pushInvokeHelper1(helper, graph.addConstant(typeName)); |
| 3049 } |
| 3050 |
3027 visitGetterSend(Send node) { | 3051 visitGetterSend(Send node) { |
3028 generateGetter(node, elements[node]); | 3052 generateGetter(node, elements[node]); |
3029 } | 3053 } |
3030 | 3054 |
3031 // TODO(antonm): migrate rest of SsaBuilder to internalError. | 3055 // TODO(antonm): migrate rest of SsaBuilder to internalError. |
3032 internalError(String reason, {Node node}) { | 3056 internalError(String reason, {Node node}) { |
3033 compiler.internalError(reason, node: node); | 3057 compiler.internalError(reason, node: node); |
3034 } | 3058 } |
3035 | 3059 |
3036 void generateError(Node node, String message, Element helper) { | 3060 void generateError(Node node, String message, Element helper) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3176 } else { | 3200 } else { |
3177 assert(const SourceString("++") == op.source || | 3201 assert(const SourceString("++") == op.source || |
3178 const SourceString("--") == op.source || | 3202 const SourceString("--") == op.source || |
3179 node.assignmentOperator.source.stringValue.endsWith("=")); | 3203 node.assignmentOperator.source.stringValue.endsWith("=")); |
3180 Element element = elements[node]; | 3204 Element element = elements[node]; |
3181 bool isCompoundAssignment = !node.arguments.isEmpty(); | 3205 bool isCompoundAssignment = !node.arguments.isEmpty(); |
3182 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. | 3206 bool isPrefix = !node.isPostfix; // Compound assignments are prefix. |
3183 | 3207 |
3184 // [receiver] is only used if the node is an instance send. | 3208 // [receiver] is only used if the node is an instance send. |
3185 HInstruction receiver = null; | 3209 HInstruction receiver = null; |
3186 if (Elements.isInstanceSend(node, elements)) { | 3210 Element selectorElement = elements[node.selector]; |
| 3211 if (!Elements.isUnresolved(selectorElement) |
| 3212 && selectorElement.kind == ElementKind.CLASS) { |
| 3213 visitTypeReferenceSend(node); |
| 3214 } else if (Elements.isInstanceSend(node, elements)) { |
3187 receiver = generateInstanceSendReceiver(node); | 3215 receiver = generateInstanceSendReceiver(node); |
3188 generateInstanceGetterWithCompiledReceiver(node, receiver); | 3216 generateInstanceGetterWithCompiledReceiver(node, receiver); |
3189 } else { | 3217 } else { |
3190 generateGetter(node, elements[node.selector]); | 3218 generateGetter(node, elements[node.selector]); |
3191 } | 3219 } |
3192 HInstruction left = pop(); | 3220 HInstruction left = pop(); |
3193 HInstruction right; | 3221 HInstruction right; |
3194 if (isCompoundAssignment) { | 3222 if (isCompoundAssignment) { |
3195 visit(node.argumentsNode); | 3223 visit(node.argumentsNode); |
3196 right = pop(); | 3224 right = pop(); |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4498 new HSubGraphBlockInformation(elseBranch.graph)); | 4526 new HSubGraphBlockInformation(elseBranch.graph)); |
4499 | 4527 |
4500 HBasicBlock conditionStartBlock = conditionBranch.block; | 4528 HBasicBlock conditionStartBlock = conditionBranch.block; |
4501 conditionStartBlock.setBlockFlow(info, joinBlock); | 4529 conditionStartBlock.setBlockFlow(info, joinBlock); |
4502 SubGraph conditionGraph = conditionBranch.graph; | 4530 SubGraph conditionGraph = conditionBranch.graph; |
4503 HIf branch = conditionGraph.end.last; | 4531 HIf branch = conditionGraph.end.last; |
4504 assert(branch is HIf); | 4532 assert(branch is HIf); |
4505 branch.blockInformation = conditionStartBlock.blockFlow; | 4533 branch.blockInformation = conditionStartBlock.blockFlow; |
4506 } | 4534 } |
4507 } | 4535 } |
OLD | NEW |