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 27 matching lines...) Expand all Loading... |
38 if (identical(name, '<<=')) return const SourceString('shl'); | 38 if (identical(name, '<<=')) return const SourceString('shl'); |
39 if (identical(name, '>>=')) return const SourceString('shr'); | 39 if (identical(name, '>>=')) return const SourceString('shr'); |
40 if (identical(name, '|=')) return const SourceString('or'); | 40 if (identical(name, '|=')) return const SourceString('or'); |
41 if (identical(name, '&=')) return const SourceString('and'); | 41 if (identical(name, '&=')) return const SourceString('and'); |
42 if (identical(name, '^=')) return const SourceString('xor'); | 42 if (identical(name, '^=')) return const SourceString('xor'); |
43 if (identical(name, '++')) return const SourceString('add'); | 43 if (identical(name, '++')) return const SourceString('add'); |
44 if (identical(name, '--')) return const SourceString('sub'); | 44 if (identical(name, '--')) return const SourceString('sub'); |
45 compiler.unimplemented('Unknown operator', node: op); | 45 compiler.unimplemented('Unknown operator', node: op); |
46 } | 46 } |
47 | 47 |
48 // TODO(karlklose,kasperl): change uses of getStatic[Get|Set]Interceptor to | 48 Element getStaticInterceptor(Selector selector) { |
49 // use this function. | 49 String name = selector.name.slowToString(); |
50 Element getStaticInterceptorBySelector(Selector selector) { | |
51 if (selector.isGetter()) { | 50 if (selector.isGetter()) { |
52 // TODO(lrn): If there is no get-interceptor, but there is a | 51 // TODO(lrn): If there is no get-interceptor, but there is a |
53 // method-interceptor, we should generate a get-interceptor automatically. | 52 // method-interceptor, we should generate a get-interceptor automatically. |
54 return getStaticGetInterceptor(selector.name); | 53 String mangledName = "get\$$name"; |
| 54 return compiler.findInterceptor(new SourceString(mangledName)); |
55 } else if (selector.isSetter()) { | 55 } else if (selector.isSetter()) { |
56 return getStaticSetInterceptor(selector.name); | 56 String mangledName = "set\$$name"; |
| 57 return compiler.findInterceptor(new SourceString(mangledName)); |
57 } else { | 58 } else { |
58 return getStaticInterceptor(selector.name, selector.argumentCount); | 59 Element element = compiler.findInterceptor(new SourceString(name)); |
| 60 if (element != null && element.isFunction()) { |
| 61 // Only pick the function element with the short name if the |
| 62 // number of parameters it expects matches the number we're |
| 63 // passing modulo the receiver. |
| 64 FunctionElement function = element; |
| 65 if (function.parameterCount(compiler) == selector.argumentCount + 1) { |
| 66 return element; |
| 67 } |
| 68 } |
| 69 String longMangledName = "$name\$${selector.argumentCount}"; |
| 70 return compiler.findInterceptor(new SourceString(longMangledName)); |
59 } | 71 } |
60 } | 72 } |
61 | 73 |
62 Element getStaticInterceptor(SourceString name, int parameters) { | |
63 String mangledName = name.slowToString(); | |
64 Element element = compiler.findInterceptor(new SourceString(mangledName)); | |
65 if (element != null && element.isFunction()) { | |
66 // Only pick the function element with the short name if the | |
67 // number of parameters it expects matches the number we're | |
68 // passing modulo the receiver. | |
69 FunctionElement function = element; | |
70 if (function.parameterCount(compiler) == parameters + 1) return element; | |
71 } | |
72 String longMangledName = "$mangledName\$$parameters"; | |
73 return compiler.findInterceptor(new SourceString(longMangledName)); | |
74 } | |
75 | |
76 Element getStaticGetInterceptor(SourceString name) { | |
77 String mangledName = "get\$${name.slowToString()}"; | |
78 return compiler.findInterceptor(new SourceString(mangledName)); | |
79 } | |
80 | |
81 Element getStaticSetInterceptor(SourceString name) { | |
82 String mangledName = "set\$${name.slowToString()}"; | |
83 return compiler.findInterceptor(new SourceString(mangledName)); | |
84 } | |
85 | |
86 Element getOperatorInterceptor(Operator op) { | 74 Element getOperatorInterceptor(Operator op) { |
87 SourceString name = mapOperatorToMethodName(op); | 75 SourceString name = mapOperatorToMethodName(op); |
88 return compiler.findHelper(name); | 76 return compiler.findHelper(name); |
89 } | 77 } |
90 | 78 |
91 Element getBoolifiedVersionOf(Element interceptor) { | 79 Element getBoolifiedVersionOf(Element interceptor) { |
92 if (interceptor == null) return interceptor; | 80 if (interceptor == null) return interceptor; |
93 String boolifiedName = "${interceptor.name.slowToString()}B"; | 81 String boolifiedName = "${interceptor.name.slowToString()}B"; |
94 return compiler.findHelper(new SourceString(boolifiedName)); | 82 return compiler.findHelper(new SourceString(boolifiedName)); |
95 } | 83 } |
(...skipping 2181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2277 // TODO(kasperl): This is a convoluted way of checking if we're | 2265 // TODO(kasperl): This is a convoluted way of checking if we're |
2278 // generating code for a compound assignment. If we are, we need | 2266 // generating code for a compound assignment. If we are, we need |
2279 // to get the selector from the mapping for the AST selector node. | 2267 // to get the selector from the mapping for the AST selector node. |
2280 Selector selector = (send.asSendSet() == null) | 2268 Selector selector = (send.asSendSet() == null) |
2281 ? elements.getSelector(send) | 2269 ? elements.getSelector(send) |
2282 : elements.getSelector(send.selector); | 2270 : elements.getSelector(send.selector); |
2283 assert(selector.isGetter()); | 2271 assert(selector.isGetter()); |
2284 SourceString getterName = selector.name; | 2272 SourceString getterName = selector.name; |
2285 Element staticInterceptor = null; | 2273 Element staticInterceptor = null; |
2286 if (elements[send] == null && methodInterceptionEnabled) { | 2274 if (elements[send] == null && methodInterceptionEnabled) { |
2287 staticInterceptor = interceptors.getStaticGetInterceptor(getterName); | 2275 staticInterceptor = interceptors.getStaticInterceptor(selector); |
2288 } | 2276 } |
2289 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 2277 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
2290 if (staticInterceptor != null) { | 2278 if (staticInterceptor != null) { |
2291 HStatic target = new HStatic(staticInterceptor); | 2279 HStatic target = new HStatic(staticInterceptor); |
2292 add(target); | 2280 add(target); |
2293 List<HInstruction> inputs = <HInstruction>[target, receiver]; | 2281 List<HInstruction> inputs = <HInstruction>[target, receiver]; |
2294 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), | 2282 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), |
2295 send); | 2283 send); |
2296 } else { | 2284 } else { |
2297 pushWithPosition( | 2285 pushWithPosition( |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2340 | 2328 |
2341 void generateInstanceSetterWithCompiledReceiver(Send send, | 2329 void generateInstanceSetterWithCompiledReceiver(Send send, |
2342 HInstruction receiver, | 2330 HInstruction receiver, |
2343 HInstruction value) { | 2331 HInstruction value) { |
2344 assert(Elements.isInstanceSend(send, elements)); | 2332 assert(Elements.isInstanceSend(send, elements)); |
2345 Selector selector = elements.getSelector(send); | 2333 Selector selector = elements.getSelector(send); |
2346 assert(selector.isSetter()); | 2334 assert(selector.isSetter()); |
2347 SourceString setterName = selector.name; | 2335 SourceString setterName = selector.name; |
2348 Element staticInterceptor = null; | 2336 Element staticInterceptor = null; |
2349 if (elements[send] == null && methodInterceptionEnabled) { | 2337 if (elements[send] == null && methodInterceptionEnabled) { |
2350 staticInterceptor = interceptors.getStaticSetInterceptor(setterName); | 2338 staticInterceptor = interceptors.getStaticInterceptor(selector); |
2351 } | 2339 } |
2352 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); | 2340 bool hasSetter = compiler.world.hasAnyUserDefinedSetter(selector); |
2353 if (staticInterceptor != null) { | 2341 if (staticInterceptor != null) { |
2354 HStatic target = new HStatic(staticInterceptor); | 2342 HStatic target = new HStatic(staticInterceptor); |
2355 add(target); | 2343 add(target); |
2356 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; | 2344 List<HInstruction> inputs = <HInstruction>[target, receiver, value]; |
2357 addWithPosition(new HInvokeInterceptor(selector, inputs), send); | 2345 addWithPosition(new HInvokeInterceptor(selector, inputs), send); |
2358 } else { | 2346 } else { |
2359 addWithPosition( | 2347 addWithPosition( |
2360 new HInvokeDynamicSetter(selector, null, receiver, value, !hasSetter), | 2348 new HInvokeDynamicSetter(selector, null, receiver, value, !hasSetter), |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2610 SourceString name = node.selector.asIdentifier().source; | 2598 SourceString name = node.selector.asIdentifier().source; |
2611 isNotEquals = identical(name.stringValue, '!='); | 2599 isNotEquals = identical(name.stringValue, '!='); |
2612 dartMethodName = Elements.constructOperatorName( | 2600 dartMethodName = Elements.constructOperatorName( |
2613 name, node.argumentsNode is Prefix); | 2601 name, node.argumentsNode is Prefix); |
2614 } else { | 2602 } else { |
2615 dartMethodName = node.selector.asIdentifier().source; | 2603 dartMethodName = node.selector.asIdentifier().source; |
2616 } | 2604 } |
2617 | 2605 |
2618 Element interceptor = null; | 2606 Element interceptor = null; |
2619 if (methodInterceptionEnabled && elements[node] == null) { | 2607 if (methodInterceptionEnabled && elements[node] == null) { |
2620 interceptor = interceptors.getStaticInterceptor(dartMethodName, | 2608 interceptor = interceptors.getStaticInterceptor(selector); |
2621 node.argumentCount()); | |
2622 } | 2609 } |
2623 if (interceptor != null) { | 2610 if (interceptor != null) { |
2624 HStatic target = new HStatic(interceptor); | 2611 HStatic target = new HStatic(interceptor); |
2625 add(target); | 2612 add(target); |
2626 inputs.add(target); | 2613 inputs.add(target); |
2627 visit(node.receiver); | 2614 visit(node.receiver); |
2628 inputs.add(pop()); | 2615 inputs.add(pop()); |
2629 addGenericSendArgumentsToList(node.arguments, inputs); | 2616 addGenericSendArgumentsToList(node.arguments, inputs); |
2630 pushWithPosition(new HInvokeInterceptor(selector, inputs), node); | 2617 pushWithPosition(new HInvokeInterceptor(selector, inputs), node); |
2631 return; | 2618 return; |
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3679 // Iterator<E> $iter = <iterable>.iterator() | 3666 // Iterator<E> $iter = <iterable>.iterator() |
3680 // while ($iter.hasNext) { | 3667 // while ($iter.hasNext) { |
3681 // E <declaredIdentifier> = $iter.next(); | 3668 // E <declaredIdentifier> = $iter.next(); |
3682 // <body> | 3669 // <body> |
3683 // } | 3670 // } |
3684 | 3671 |
3685 // The iterator is shared between initializer, condition and body. | 3672 // The iterator is shared between initializer, condition and body. |
3686 HInstruction iterator; | 3673 HInstruction iterator; |
3687 void buildInitializer() { | 3674 void buildInitializer() { |
3688 SourceString iteratorName = const SourceString("iterator"); | 3675 SourceString iteratorName = const SourceString("iterator"); |
3689 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); | 3676 Selector selector = |
| 3677 new Selector.call(iteratorName, work.element.getLibrary(), 0); |
| 3678 Element interceptor = interceptors.getStaticInterceptor(selector); |
3690 assert(interceptor != null); | 3679 assert(interceptor != null); |
3691 visit(node.expression); | 3680 visit(node.expression); |
3692 pushInvokeHelper1(interceptor, pop()); | 3681 pushInvokeHelper1(interceptor, pop()); |
3693 iterator = pop(); | 3682 iterator = pop(); |
3694 } | 3683 } |
3695 HInstruction buildCondition() { | 3684 HInstruction buildCondition() { |
3696 SourceString name = const SourceString('hasNext'); | 3685 SourceString name = const SourceString('hasNext'); |
3697 Selector selector = new Selector.getter(name, work.element.getLibrary()); | 3686 Selector selector = new Selector.getter(name, work.element.getLibrary()); |
3698 if (interceptors.getStaticGetInterceptor(name) != null) { | 3687 if (interceptors.getStaticInterceptor(selector) != null) { |
3699 compiler.internalError("hasNext getter must not be intercepted", | 3688 compiler.internalError("hasNext getter must not be intercepted", |
3700 node: node); | 3689 node: node); |
3701 } | 3690 } |
3702 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 3691 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
3703 push(new HInvokeDynamicGetter(selector, null, iterator, !hasGetter)); | 3692 push(new HInvokeDynamicGetter(selector, null, iterator, !hasGetter)); |
3704 return popBoolified(); | 3693 return popBoolified(); |
3705 } | 3694 } |
3706 void buildBody() { | 3695 void buildBody() { |
3707 SourceString name = const SourceString('next'); | 3696 SourceString name = const SourceString('next'); |
3708 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 3697 Selector call = new Selector.call(name, work.element.getLibrary(), 0); |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4771 new HSubGraphBlockInformation(elseBranch.graph)); | 4760 new HSubGraphBlockInformation(elseBranch.graph)); |
4772 | 4761 |
4773 HBasicBlock conditionStartBlock = conditionBranch.block; | 4762 HBasicBlock conditionStartBlock = conditionBranch.block; |
4774 conditionStartBlock.setBlockFlow(info, joinBlock); | 4763 conditionStartBlock.setBlockFlow(info, joinBlock); |
4775 SubGraph conditionGraph = conditionBranch.graph; | 4764 SubGraph conditionGraph = conditionBranch.graph; |
4776 HIf branch = conditionGraph.end.last; | 4765 HIf branch = conditionGraph.end.last; |
4777 assert(branch is HIf); | 4766 assert(branch is HIf); |
4778 branch.blockInformation = conditionStartBlock.blockFlow; | 4767 branch.blockInformation = conditionStartBlock.blockFlow; |
4779 } | 4768 } |
4780 } | 4769 } |
OLD | NEW |