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