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