Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(160)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/builder.dart

Issue 11365170: Start new design for interceptors and implement String.charCodeAt with it. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 28 matching lines...) Expand all
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 Element getStaticInterceptor(Selector selector) { 48 Element getStaticInterceptor(Selector selector) {
49 // Check if we have an interceptor implemented with classes.
50 List<Element> intercepted =
51 compiler.enqueuer.resolution.interceptedElements[selector.name];
52 if (intercepted != null) {
53 for (Element element in intercepted) {
54 if (selector.applies(element, compiler)) {
55 JavaScriptBackend backend = compiler.backend;
56 backend.usedInterceptors.add(selector);
ahe 2012/11/12 13:24:11 A helper method instead :-)
ngeoffray 2012/11/13 11:45:16 Done.
57 return compiler.getInterceptorMethod;
58 }
59 }
60 }
61
62 // Fall back to the old interceptor mechanism.
49 String name = selector.name.slowToString(); 63 String name = selector.name.slowToString();
50 if (selector.isGetter()) { 64 if (selector.isGetter()) {
51 // TODO(lrn): If there is no get-interceptor, but there is a 65 // TODO(lrn): If there is no get-interceptor, but there is a
52 // method-interceptor, we should generate a get-interceptor automatically. 66 // method-interceptor, we should generate a get-interceptor automatically.
53 String mangledName = "get\$$name"; 67 String mangledName = "get\$$name";
54 return compiler.findInterceptor(new SourceString(mangledName)); 68 return compiler.findInterceptor(new SourceString(mangledName));
55 } else if (selector.isSetter()) { 69 } else if (selector.isSetter()) {
56 String mangledName = "set\$$name"; 70 String mangledName = "set\$$name";
57 return compiler.findInterceptor(new SourceString(mangledName)); 71 return compiler.findInterceptor(new SourceString(mangledName));
58 } else { 72 } else {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 408
395 // If the freeVariableMapping is not empty, then this function was a 409 // If the freeVariableMapping is not empty, then this function was a
396 // nested closure that captures variables. Redirect the captured 410 // nested closure that captures variables. Redirect the captured
397 // variables to fields in the closure. 411 // variables to fields in the closure.
398 closureData.freeVariableMapping.forEach((Element from, Element to) { 412 closureData.freeVariableMapping.forEach((Element from, Element to) {
399 redirectElement(from, to); 413 redirectElement(from, to);
400 }); 414 });
401 if (closureData.isClosure()) { 415 if (closureData.isClosure()) {
402 // Inside closure redirect references to itself to [:this:]. 416 // Inside closure redirect references to itself to [:this:].
403 HInstruction thisInstruction = new HThis(); 417 HInstruction thisInstruction = new HThis();
404 builder.add(thisInstruction); 418 thisInstruction.sourceElement = closureData.thisElement;
ahe 2012/11/12 13:24:11 Should this be an argument to the constructor?
ngeoffray 2012/11/13 11:45:16 Done.
419 builder.graph.entry.addAtEntry(thisInstruction);
405 updateLocal(closureData.closureElement, thisInstruction); 420 updateLocal(closureData.closureElement, thisInstruction);
406 } else if (element.isInstanceMember() 421 } else if (element.isInstanceMember()
407 || element.isGenerativeConstructor()) { 422 || element.isGenerativeConstructor()) {
408 // Once closures have been mapped to classes their instance members might 423 // Once closures have been mapped to classes their instance members might
409 // not have any thisElement if the closure was created inside a static 424 // not have any thisElement if the closure was created inside a static
410 // context. 425 // context.
411 ClassElement cls = element.getEnclosingClass(); 426 ClassElement cls = element.getEnclosingClass();
412 DartType type = cls.computeType(builder.compiler); 427 DartType type = cls.computeType(builder.compiler);
413 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); 428 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type));
414 builder.add(thisInstruction); 429 thisInstruction.sourceElement = closureData.thisElement;
430 builder.graph.entry.addAtEntry(thisInstruction);
415 directLocals[closureData.thisElement] = thisInstruction; 431 directLocals[closureData.thisElement] = thisInstruction;
416 } 432 }
417 } 433 }
418 434
419 bool hasValueForDirectLocal(Element element) { 435 bool hasValueForDirectLocal(Element element) {
420 assert(element != null); 436 assert(element != null);
421 assert(isAccessedDirectly(element)); 437 assert(isAccessedDirectly(element));
422 return directLocals[element] != null; 438 return directLocals[element] != null;
423 } 439 }
424 440
(...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 HInstruction receiver) { 2279 HInstruction receiver) {
2264 assert(Elements.isInstanceSend(send, elements)); 2280 assert(Elements.isInstanceSend(send, elements));
2265 // TODO(kasperl): This is a convoluted way of checking if we're 2281 // TODO(kasperl): This is a convoluted way of checking if we're
2266 // generating code for a compound assignment. If we are, we need 2282 // generating code for a compound assignment. If we are, we need
2267 // to get the selector from the mapping for the AST selector node. 2283 // to get the selector from the mapping for the AST selector node.
2268 Selector selector = (send.asSendSet() == null) 2284 Selector selector = (send.asSendSet() == null)
2269 ? elements.getSelector(send) 2285 ? elements.getSelector(send)
2270 : elements.getSelector(send.selector); 2286 : elements.getSelector(send.selector);
2271 assert(selector.isGetter()); 2287 assert(selector.isGetter());
2272 SourceString getterName = selector.name; 2288 SourceString getterName = selector.name;
2273 Element staticInterceptor = null; 2289 Element interceptor = null;
2274 if (elements[send] == null && methodInterceptionEnabled) { 2290 if (elements[send] == null && methodInterceptionEnabled) {
2275 staticInterceptor = interceptors.getStaticInterceptor(selector); 2291 interceptor = interceptors.getStaticInterceptor(selector);
2276 } 2292 }
2277 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 2293 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
2278 if (staticInterceptor != null) { 2294 if (interceptor != null) {
2279 HStatic target = new HStatic(staticInterceptor); 2295 if (interceptor == compiler.getInterceptorMethod) {
ahe 2012/11/12 13:24:11 Add comment explaining this is the new way.
ngeoffray 2012/11/13 11:45:16 Done.
2280 add(target); 2296 HStatic target = new HStatic(interceptor);
2281 List<HInstruction> inputs = <HInstruction>[target, receiver]; 2297 add(target);
2282 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), 2298 HInstruction instruction =
2283 send); 2299 new HInvokeStatic(<HInstruction>[target, receiver]);
2300 add(instruction);
2301 instruction = new HInvokeDynamicGetter(
2302 selector, null, instruction, true);
ahe 2012/11/12 13:24:11 Document what true means here.
ngeoffray 2012/11/13 11:45:16 Done.
2303 instruction.inputs.add(receiver);
ahe 2012/11/12 13:24:11 Comment here please.
ngeoffray 2012/11/13 11:45:16 Done.
2304 instruction.element = interceptor;
2305 pushWithPosition(instruction, send);
2306 } else {
ahe 2012/11/12 13:24:11 Add comment explaining this is old style, deprecat
ngeoffray 2012/11/13 11:45:16 Done.
2307 HStatic target = new HStatic(interceptor);
2308 add(target);
2309 List<HInstruction> inputs = <HInstruction>[target, receiver];
2310 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter),
2311 send);
2312 }
2284 } else { 2313 } else {
2285 pushWithPosition( 2314 pushWithPosition(
2286 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter), send); 2315 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter), send);
2287 } 2316 }
2288 } 2317 }
2289 2318
2290 void generateGetter(Send send, Element element) { 2319 void generateGetter(Send send, Element element) {
2291 if (Elements.isStaticOrTopLevelField(element)) { 2320 if (Elements.isStaticOrTopLevelField(element)) {
2292 Constant value; 2321 Constant value;
2293 if (element.isField() && !element.isAssignable()) { 2322 if (element.isField() && !element.isAssignable()) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 name, node.argumentsNode is Prefix); 2630 name, node.argumentsNode is Prefix);
2602 } else { 2631 } else {
2603 dartMethodName = node.selector.asIdentifier().source; 2632 dartMethodName = node.selector.asIdentifier().source;
2604 } 2633 }
2605 2634
2606 Element interceptor = null; 2635 Element interceptor = null;
2607 if (methodInterceptionEnabled && elements[node] == null) { 2636 if (methodInterceptionEnabled && elements[node] == null) {
2608 interceptor = interceptors.getStaticInterceptor(selector); 2637 interceptor = interceptors.getStaticInterceptor(selector);
2609 } 2638 }
2610 if (interceptor != null) { 2639 if (interceptor != null) {
2611 HStatic target = new HStatic(interceptor); 2640 if (interceptor == compiler.getInterceptorMethod) {
2612 add(target); 2641 HStatic target = new HStatic(interceptor);
2613 inputs.add(target); 2642 add(target);
2614 visit(node.receiver); 2643 visit(node.receiver);
ahe 2012/11/12 13:24:11 What happens if node.receiver is null?
ngeoffray 2012/11/13 11:45:16 Cannot happen right now, but I added a comment.
2615 inputs.add(pop()); 2644 HInstruction receiver = pop();
2616 addGenericSendArgumentsToList(node.arguments, inputs); 2645 HInstruction instruction =
2617 pushWithPosition(new HInvokeInterceptor(selector, inputs), node); 2646 new HInvokeStatic(<HInstruction>[target, receiver]);
2647 add(instruction);
2648 inputs.add(instruction);
2649 inputs.add(receiver);
2650 addDynamicSendArgumentsToList(node, inputs);
2651 // The first entry in the inputs list is the receiver.
ahe 2012/11/12 13:24:11 Is it the last?
ngeoffray 2012/11/13 11:45:16 No second. Improved the comment.
2652 instruction = new HInvokeDynamicMethod(selector, inputs);
2653 pushWithPosition(instruction, node);
2654 } else {
2655 HStatic target = new HStatic(interceptor);
2656 add(target);
2657 inputs.add(target);
2658 visit(node.receiver);
2659 inputs.add(pop());
2660 addGenericSendArgumentsToList(node.arguments, inputs);
2661 pushWithPosition(new HInvokeInterceptor(selector, inputs), node);
2662 }
2618 return; 2663 return;
2619 } 2664 }
2620 2665
2621 Element element = elements[node]; 2666 Element element = elements[node];
2622 if (element != null && compiler.world.hasNoOverridingMember(element)) { 2667 if (element != null && compiler.world.hasNoOverridingMember(element)) {
2623 if (tryInlineMethod(element, selector, node.arguments)) { 2668 if (tryInlineMethod(element, selector, node.arguments)) {
2624 return; 2669 return;
2625 } 2670 }
2626 } 2671 }
2627 2672
(...skipping 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after
4760 new HSubGraphBlockInformation(elseBranch.graph)); 4805 new HSubGraphBlockInformation(elseBranch.graph));
4761 4806
4762 HBasicBlock conditionStartBlock = conditionBranch.block; 4807 HBasicBlock conditionStartBlock = conditionBranch.block;
4763 conditionStartBlock.setBlockFlow(info, joinBlock); 4808 conditionStartBlock.setBlockFlow(info, joinBlock);
4764 SubGraph conditionGraph = conditionBranch.graph; 4809 SubGraph conditionGraph = conditionBranch.graph;
4765 HIf branch = conditionGraph.end.last; 4810 HIf branch = conditionGraph.end.last;
4766 assert(branch is HIf); 4811 assert(branch is HIf);
4767 branch.blockInformation = conditionStartBlock.blockFlow; 4812 branch.blockInformation = conditionStartBlock.blockFlow;
4768 } 4813 }
4769 } 4814 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698