| 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 ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class Interceptors { | 7 class Interceptors { |
| 8 Compiler compiler; | 8 Compiler compiler; |
| 9 Interceptors(Compiler this.compiler); | 9 Interceptors(Compiler this.compiler); |
| 10 | 10 |
| (...skipping 2282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2293 | 2293 |
| 2294 void pushInvokeHelper3(Element helper, HInstruction a0, HInstruction a1, | 2294 void pushInvokeHelper3(Element helper, HInstruction a0, HInstruction a1, |
| 2295 HInstruction a2) { | 2295 HInstruction a2) { |
| 2296 HInstruction reference = new HStatic(helper); | 2296 HInstruction reference = new HStatic(helper); |
| 2297 add(reference); | 2297 add(reference); |
| 2298 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; | 2298 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2]; |
| 2299 HInstruction result = new HInvokeStatic(inputs); | 2299 HInstruction result = new HInvokeStatic(inputs); |
| 2300 push(result); | 2300 push(result); |
| 2301 } | 2301 } |
| 2302 | 2302 |
| 2303 void pushInvokeHelper4(Element helper, HInstruction a0, HInstruction a1, |
| 2304 HInstruction a2, HInstruction a3) { |
| 2305 HInstruction reference = new HStatic(helper); |
| 2306 add(reference); |
| 2307 List<HInstruction> inputs = <HInstruction>[reference, a0, a1, a2, a3]; |
| 2308 HInstruction result = new HInvokeStatic(inputs); |
| 2309 push(result); |
| 2310 } |
| 2311 |
| 2303 visitOperatorSend(node) { | 2312 visitOperatorSend(node) { |
| 2304 assert(node.selector is Operator); | 2313 assert(node.selector is Operator); |
| 2305 if (!methodInterceptionEnabled) { | 2314 if (!methodInterceptionEnabled) { |
| 2306 visitDynamicSend(node); | 2315 visitDynamicSend(node); |
| 2307 return; | 2316 return; |
| 2308 } | 2317 } |
| 2309 | 2318 |
| 2310 Operator op = node.selector; | 2319 Operator op = node.selector; |
| 2311 if (const SourceString("[]") == op.source) { | 2320 if (const SourceString("[]") == op.source) { |
| 2312 HStatic target = new HStatic(interceptors.getIndexInterceptor()); | 2321 HStatic target = new HStatic(interceptors.getIndexInterceptor()); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2726 // creating an [HStatic]. | 2735 // creating an [HStatic]. |
| 2727 HInstruction target = new HStatic(element.declaration); | 2736 HInstruction target = new HStatic(element.declaration); |
| 2728 HInstruction context = localsHandler.readThis(); | 2737 HInstruction context = localsHandler.readThis(); |
| 2729 add(target); | 2738 add(target); |
| 2730 var inputs = <HInstruction>[target, context]; | 2739 var inputs = <HInstruction>[target, context]; |
| 2731 if (node.isPropertyAccess) { | 2740 if (node.isPropertyAccess) { |
| 2732 push(new HInvokeSuper(inputs)); | 2741 push(new HInvokeSuper(inputs)); |
| 2733 } else if (element.isFunction() || element.isGenerativeConstructor()) { | 2742 } else if (element.isFunction() || element.isGenerativeConstructor()) { |
| 2734 // TODO(5347): Try to avoid the need for calling [implementation] before | 2743 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 2735 // calling [addStaticSendArgumentsToList]. | 2744 // calling [addStaticSendArgumentsToList]. |
| 2745 FunctionElement function = element.implementation; |
| 2736 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 2746 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 2737 element.implementation, | 2747 function, inputs); |
| 2738 inputs); | |
| 2739 if (!succeeded) { | 2748 if (!succeeded) { |
| 2740 // TODO(ngeoffray): Match the VM behavior and throw an | 2749 generateWrongArgumentCountError(node, element, node.arguments); |
| 2741 // exception at runtime. | 2750 } else { |
| 2742 compiler.cancel('Unimplemented non-matching static call', node: node); | 2751 push(new HInvokeSuper(inputs)); |
| 2743 } | 2752 } |
| 2744 push(new HInvokeSuper(inputs)); | |
| 2745 } else { | 2753 } else { |
| 2746 target = new HInvokeSuper(inputs); | 2754 target = new HInvokeSuper(inputs); |
| 2747 add(target); | 2755 add(target); |
| 2748 inputs = <HInstruction>[target]; | 2756 inputs = <HInstruction>[target]; |
| 2749 addDynamicSendArgumentsToList(node, inputs); | 2757 addDynamicSendArgumentsToList(node, inputs); |
| 2750 push(new HInvokeClosure(selector, inputs)); | 2758 push(new HInvokeClosure(selector, inputs)); |
| 2751 } | 2759 } |
| 2752 } | 2760 } |
| 2753 | 2761 |
| 2754 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 2762 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2933 HInstruction target = new HStatic(constructor.declaration); | 2941 HInstruction target = new HStatic(constructor.declaration); |
| 2934 add(target); | 2942 add(target); |
| 2935 var inputs = <HInstruction>[]; | 2943 var inputs = <HInstruction>[]; |
| 2936 inputs.add(target); | 2944 inputs.add(target); |
| 2937 // TODO(5347): Try to avoid the need for calling [implementation] before | 2945 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 2938 // calling [addStaticSendArgumentsToList]. | 2946 // calling [addStaticSendArgumentsToList]. |
| 2939 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 2947 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 2940 constructor.implementation, | 2948 constructor.implementation, |
| 2941 inputs); | 2949 inputs); |
| 2942 if (!succeeded) { | 2950 if (!succeeded) { |
| 2943 // TODO(ngeoffray): Match the VM behavior and throw an | 2951 generateWrongArgumentCountError(node, constructor, node.arguments); |
| 2944 // exception at runtime. | 2952 return; |
| 2945 compiler.cancel('Unimplemented non-matching static call', node: node); | |
| 2946 } | 2953 } |
| 2947 | 2954 |
| 2948 TypeAnnotation annotation = node.getTypeAnnotation(); | 2955 TypeAnnotation annotation = node.getTypeAnnotation(); |
| 2949 if (annotation == null) { | 2956 if (annotation == null) { |
| 2950 compiler.internalError("malformed send in new expression"); | 2957 compiler.internalError("malformed send in new expression"); |
| 2951 } | 2958 } |
| 2952 InterfaceType type = elements.getType(annotation); | 2959 InterfaceType type = elements.getType(annotation); |
| 2953 if (type.element.modifiers.isAbstract() && | 2960 if (type.element.modifiers.isAbstract() && |
| 2954 constructor.isGenerativeConstructor()) { | 2961 constructor.isGenerativeConstructor()) { |
| 2955 generateAbstractClassInstantiationError(node, type.name.slowToString()); | 2962 generateAbstractClassInstantiationError(node, type.name.slowToString()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2976 | 2983 |
| 2977 visitStaticSend(Send node) { | 2984 visitStaticSend(Send node) { |
| 2978 Selector selector = elements.getSelector(node); | 2985 Selector selector = elements.getSelector(node); |
| 2979 Element element = elements[node]; | 2986 Element element = elements[node]; |
| 2980 if (element.isErroneous()) { | 2987 if (element.isErroneous()) { |
| 2981 generateThrowNoSuchMethod(node, | 2988 generateThrowNoSuchMethod(node, |
| 2982 getTargetName(element), | 2989 getTargetName(element), |
| 2983 argumentNodes: node.arguments); | 2990 argumentNodes: node.arguments); |
| 2984 return; | 2991 return; |
| 2985 } | 2992 } |
| 2986 if (identical(element, compiler.assertMethod) && !compiler.enableUserAsserti
ons) { | 2993 if (identical(element, compiler.assertMethod) |
| 2994 && !compiler.enableUserAssertions) { |
| 2987 stack.add(graph.addConstantNull(constantSystem)); | 2995 stack.add(graph.addConstantNull(constantSystem)); |
| 2988 return; | 2996 return; |
| 2989 } | 2997 } |
| 2990 compiler.ensure(!element.isGenerativeConstructor()); | 2998 compiler.ensure(!element.isGenerativeConstructor()); |
| 2991 if (element.isFunction()) { | 2999 if (element.isFunction()) { |
| 2992 if (tryInlineMethod(element, selector, node.arguments)) { | 3000 if (tryInlineMethod(element, selector, node.arguments)) { |
| 2993 return; | 3001 return; |
| 2994 } | 3002 } |
| 2995 | 3003 |
| 2996 HInstruction target = new HStatic(element); | 3004 HInstruction target = new HStatic(element); |
| 2997 add(target); | 3005 add(target); |
| 2998 var inputs = <HInstruction>[target]; | 3006 var inputs = <HInstruction>[target]; |
| 2999 // TODO(5347): Try to avoid the need for calling [implementation] before | 3007 // TODO(5347): Try to avoid the need for calling [implementation] before |
| 3000 // calling [addStaticSendArgumentsToList]. | 3008 // calling [addStaticSendArgumentsToList]. |
| 3001 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, | 3009 bool succeeded = addStaticSendArgumentsToList(selector, node.arguments, |
| 3002 element.implementation, | 3010 element.implementation, |
| 3003 inputs); | 3011 inputs); |
| 3004 if (!succeeded) { | 3012 if (!succeeded) { |
| 3005 // TODO(ngeoffray): Match the VM behavior and throw an | 3013 generateWrongArgumentCountError(node, element, node.arguments); |
| 3006 // exception at runtime. | 3014 return; |
| 3007 compiler.cancel('Unimplemented non-matching static call', node: node); | |
| 3008 } | 3015 } |
| 3009 | 3016 |
| 3010 // TODO(kasperl): Try to use the general inlining infrastructure for | 3017 // TODO(kasperl): Try to use the general inlining infrastructure for |
| 3011 // inlining the identical function. | 3018 // inlining the identical function. |
| 3012 if (identical(element, compiler.identicalFunction)) { | 3019 if (identical(element, compiler.identicalFunction)) { |
| 3013 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node); | 3020 pushWithPosition(new HIdentity(target, inputs[1], inputs[2]), node); |
| 3014 return; | 3021 return; |
| 3015 } | 3022 } |
| 3016 | 3023 |
| 3017 HInvokeStatic instruction = new HInvokeStatic(inputs); | 3024 HInvokeStatic instruction = new HInvokeStatic(inputs); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 | 3060 |
| 3054 void generateAbstractClassInstantiationError(Node node, String message) { | 3061 void generateAbstractClassInstantiationError(Node node, String message) { |
| 3055 generateError(node, | 3062 generateError(node, |
| 3056 message, | 3063 message, |
| 3057 interceptors.getThrowAbstractClassInstantiationError()); | 3064 interceptors.getThrowAbstractClassInstantiationError()); |
| 3058 } | 3065 } |
| 3059 | 3066 |
| 3060 void generateThrowNoSuchMethod(Node diagnosticNode, | 3067 void generateThrowNoSuchMethod(Node diagnosticNode, |
| 3061 String methodName, | 3068 String methodName, |
| 3062 {Link<Node> argumentNodes, | 3069 {Link<Node> argumentNodes, |
| 3063 List<HInstruction> argumentValues}) { | 3070 List<HInstruction> argumentValues, |
| 3071 List<String> existingArguments}) { |
| 3064 Element helper = | 3072 Element helper = |
| 3065 compiler.findHelper(const SourceString('throwNoSuchMethod')); | 3073 compiler.findHelper(const SourceString('throwNoSuchMethod')); |
| 3066 Constant receiverConstant = | 3074 Constant receiverConstant = |
| 3067 constantSystem.createString(new DartString.empty(), diagnosticNode); | 3075 constantSystem.createString(new DartString.empty(), diagnosticNode); |
| 3068 HInstruction receiver = graph.addConstant(receiverConstant); | 3076 HInstruction receiver = graph.addConstant(receiverConstant); |
| 3069 DartString dartString = new DartString.literal(methodName); | 3077 DartString dartString = new DartString.literal(methodName); |
| 3070 Constant nameConstant = | 3078 Constant nameConstant = |
| 3071 constantSystem.createString(dartString, diagnosticNode); | 3079 constantSystem.createString(dartString, diagnosticNode); |
| 3072 HInstruction name = graph.addConstant(nameConstant); | 3080 HInstruction name = graph.addConstant(nameConstant); |
| 3073 if (argumentValues == null) { | 3081 if (argumentValues == null) { |
| 3074 argumentValues = <HInstruction>[]; | 3082 argumentValues = <HInstruction>[]; |
| 3075 argumentNodes.forEach((argumentNode) { | 3083 argumentNodes.forEach((argumentNode) { |
| 3076 visit(argumentNode); | 3084 visit(argumentNode); |
| 3077 HInstruction value = pop(); | 3085 HInstruction value = pop(); |
| 3078 argumentValues.add(value); | 3086 argumentValues.add(value); |
| 3079 }); | 3087 }); |
| 3080 } | 3088 } |
| 3081 HInstruction arguments = new HLiteralList(argumentValues); | 3089 HInstruction arguments = new HLiteralList(argumentValues); |
| 3082 add(arguments); | 3090 add(arguments); |
| 3083 pushInvokeHelper3(helper, receiver, name, arguments); | 3091 HInstruction existingNamesList; |
| 3092 if (existingArguments != null) { |
| 3093 List<HInstruction> existingNames = <HInstruction>[]; |
| 3094 for (String name in existingArguments) { |
| 3095 HInstruction nameConstant = |
| 3096 graph.addConstantString(new DartString.literal(name), |
| 3097 diagnosticNode, constantSystem); |
| 3098 existingNames.add(nameConstant); |
| 3099 } |
| 3100 existingNamesList = new HLiteralList(existingNames); |
| 3101 add(existingNamesList); |
| 3102 } else { |
| 3103 existingNamesList = graph.addConstantNull(constantSystem); |
| 3104 } |
| 3105 pushInvokeHelper4(helper, receiver, name, arguments, existingNamesList); |
| 3106 } |
| 3107 |
| 3108 /** |
| 3109 * Generate code to throw a [NoSuchMethodError] exception for calling a |
| 3110 * method with a wrong number of arguments or mismatching named optional |
| 3111 * arguments. |
| 3112 */ |
| 3113 void generateWrongArgumentCountError(Node diagnosticNode, |
| 3114 FunctionElement function, |
| 3115 Link<Node> argumentNodes) { |
| 3116 List<String> existingArguments = <String>[]; |
| 3117 FunctionSignature signature = function.computeSignature(compiler); |
| 3118 signature.forEachParameter((Element parameter) { |
| 3119 existingArguments.add(parameter.name.slowToString()); |
| 3120 }); |
| 3121 generateThrowNoSuchMethod(diagnosticNode, |
| 3122 function.name.slowToString(), |
| 3123 argumentNodes: argumentNodes, |
| 3124 existingArguments: existingArguments); |
| 3084 } | 3125 } |
| 3085 | 3126 |
| 3086 visitNewExpression(NewExpression node) { | 3127 visitNewExpression(NewExpression node) { |
| 3087 Element element = elements[node.send]; | 3128 Element element = elements[node.send]; |
| 3088 if (Elements.isErroneousElement(element)) { | 3129 if (Elements.isErroneousElement(element)) { |
| 3089 ErroneousElement error = element; | 3130 ErroneousElement error = element; |
| 3090 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 3131 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 3091 generateThrowNoSuchMethod(node.send, | 3132 generateThrowNoSuchMethod(node.send, |
| 3092 getTargetName(error, 'constructor'), | 3133 getTargetName(error, 'constructor'), |
| 3093 argumentNodes: node.send.arguments); | 3134 argumentNodes: node.send.arguments); |
| (...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4509 new HSubGraphBlockInformation(elseBranch.graph)); | 4550 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4510 | 4551 |
| 4511 HBasicBlock conditionStartBlock = conditionBranch.block; | 4552 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4512 conditionStartBlock.setBlockFlow(info, joinBlock); | 4553 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4513 SubGraph conditionGraph = conditionBranch.graph; | 4554 SubGraph conditionGraph = conditionBranch.graph; |
| 4514 HIf branch = conditionGraph.end.last; | 4555 HIf branch = conditionGraph.end.last; |
| 4515 assert(branch is HIf); | 4556 assert(branch is HIf); |
| 4516 branch.blockInformation = conditionStartBlock.blockFlow; | 4557 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4517 } | 4558 } |
| 4518 } | 4559 } |
| OLD | NEW |