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

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.
ahe 2012/11/13 12:42:41 How about: // Check if we have an interceptor met
ngeoffray 2012/11/13 12:51:50 Done.
50 JavaScriptBackend backend = compiler.backend;
51 if (backend.shouldInterceptSelector(selector)) {
52 backend.addInterceptedSelector(selector);
53 return backend.getInterceptorMethod;
54 }
55
56 // Fall back to the old interceptor mechanism.
49 String name = selector.name.slowToString(); 57 String name = selector.name.slowToString();
50 if (selector.isGetter()) { 58 if (selector.isGetter()) {
51 // TODO(lrn): If there is no get-interceptor, but there is a 59 // TODO(lrn): If there is no get-interceptor, but there is a
52 // method-interceptor, we should generate a get-interceptor automatically. 60 // method-interceptor, we should generate a get-interceptor automatically.
53 String mangledName = "get\$$name"; 61 String mangledName = "get\$$name";
54 return compiler.findInterceptor(new SourceString(mangledName)); 62 return compiler.findInterceptor(new SourceString(mangledName));
55 } else if (selector.isSetter()) { 63 } else if (selector.isSetter()) {
56 String mangledName = "set\$$name"; 64 String mangledName = "set\$$name";
57 return compiler.findInterceptor(new SourceString(mangledName)); 65 return compiler.findInterceptor(new SourceString(mangledName));
58 } else { 66 } else {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 enterScope(node, element); 401 enterScope(node, element);
394 402
395 // If the freeVariableMapping is not empty, then this function was a 403 // If the freeVariableMapping is not empty, then this function was a
396 // nested closure that captures variables. Redirect the captured 404 // nested closure that captures variables. Redirect the captured
397 // variables to fields in the closure. 405 // variables to fields in the closure.
398 closureData.freeVariableMapping.forEach((Element from, Element to) { 406 closureData.freeVariableMapping.forEach((Element from, Element to) {
399 redirectElement(from, to); 407 redirectElement(from, to);
400 }); 408 });
401 if (closureData.isClosure()) { 409 if (closureData.isClosure()) {
402 // Inside closure redirect references to itself to [:this:]. 410 // Inside closure redirect references to itself to [:this:].
403 HInstruction thisInstruction = new HThis(); 411 HInstruction thisInstruction = new HThis(closureData.thisElement);
404 builder.add(thisInstruction); 412 builder.graph.entry.addAtEntry(thisInstruction);
405 updateLocal(closureData.closureElement, thisInstruction); 413 updateLocal(closureData.closureElement, thisInstruction);
406 } else if (element.isInstanceMember() 414 } else if (element.isInstanceMember()
407 || element.isGenerativeConstructor()) { 415 || element.isGenerativeConstructor()) {
408 // Once closures have been mapped to classes their instance members might 416 // Once closures have been mapped to classes their instance members might
409 // not have any thisElement if the closure was created inside a static 417 // not have any thisElement if the closure was created inside a static
410 // context. 418 // context.
411 ClassElement cls = element.getEnclosingClass(); 419 ClassElement cls = element.getEnclosingClass();
412 DartType type = cls.computeType(builder.compiler); 420 DartType type = cls.computeType(builder.compiler);
413 HInstruction thisInstruction = new HThis(new HBoundedType.nonNull(type)); 421 HInstruction thisInstruction = new HThis(closureData.thisElement,
414 builder.add(thisInstruction); 422 new HBoundedType.nonNull(type));
423 thisInstruction.sourceElement = closureData.thisElement;
424 builder.graph.entry.addAtEntry(thisInstruction);
415 directLocals[closureData.thisElement] = thisInstruction; 425 directLocals[closureData.thisElement] = thisInstruction;
416 } 426 }
417 } 427 }
418 428
419 bool hasValueForDirectLocal(Element element) { 429 bool hasValueForDirectLocal(Element element) {
420 assert(element != null); 430 assert(element != null);
421 assert(isAccessedDirectly(element)); 431 assert(isAccessedDirectly(element));
422 return directLocals[element] != null; 432 return directLocals[element] != null;
423 } 433 }
424 434
(...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2263 HInstruction receiver) { 2273 HInstruction receiver) {
2264 assert(Elements.isInstanceSend(send, elements)); 2274 assert(Elements.isInstanceSend(send, elements));
2265 // TODO(kasperl): This is a convoluted way of checking if we're 2275 // TODO(kasperl): This is a convoluted way of checking if we're
2266 // generating code for a compound assignment. If we are, we need 2276 // generating code for a compound assignment. If we are, we need
2267 // to get the selector from the mapping for the AST selector node. 2277 // to get the selector from the mapping for the AST selector node.
2268 Selector selector = (send.asSendSet() == null) 2278 Selector selector = (send.asSendSet() == null)
2269 ? elements.getSelector(send) 2279 ? elements.getSelector(send)
2270 : elements.getSelector(send.selector); 2280 : elements.getSelector(send.selector);
2271 assert(selector.isGetter()); 2281 assert(selector.isGetter());
2272 SourceString getterName = selector.name; 2282 SourceString getterName = selector.name;
2273 Element staticInterceptor = null; 2283 Element interceptor = null;
2274 if (elements[send] == null && methodInterceptionEnabled) { 2284 if (elements[send] == null && methodInterceptionEnabled) {
2275 staticInterceptor = interceptors.getStaticInterceptor(selector); 2285 interceptor = interceptors.getStaticInterceptor(selector);
2276 } 2286 }
2277 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); 2287 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector);
2278 if (staticInterceptor != null) { 2288 if (interceptor != null) {
2279 HStatic target = new HStatic(staticInterceptor); 2289 if (interceptor == backend.getInterceptorMethod) {
2280 add(target); 2290 // If we're using an interceptor class, emit a call to the
2281 List<HInstruction> inputs = <HInstruction>[target, receiver]; 2291 // interceptor method and then the actuall dynamic call on the
ahe 2012/11/13 12:42:41 actuall -> actual
ngeoffray 2012/11/13 12:51:50 Done.
2282 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter), 2292 // interceptor object.
2283 send); 2293 HStatic target = new HStatic(interceptor);
2294 add(target);
2295 HInstruction instruction =
2296 new HInvokeStatic(<HInstruction>[target, receiver]);
2297 add(instruction);
2298 instruction = new HInvokeDynamicGetter(
2299 selector, null, instruction, !hasGetter);
2300 // Add the receiver as an argument to the getter call on the
2301 // interceptor.
2302 instruction.inputs.add(receiver);
2303 pushWithPosition(instruction, send);
2304 } else {
2305 // Use the old, deprecated interceptor mechanism.
2306 HStatic target = new HStatic(interceptor);
2307 add(target);
2308 List<HInstruction> inputs = <HInstruction>[target, receiver];
2309 pushWithPosition(new HInvokeInterceptor(selector, inputs, !hasGetter),
2310 send);
2311 }
2284 } else { 2312 } else {
2285 pushWithPosition( 2313 pushWithPosition(
2286 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter), send); 2314 new HInvokeDynamicGetter(selector, null, receiver, !hasGetter), send);
2287 } 2315 }
2288 } 2316 }
2289 2317
2290 void generateGetter(Send send, Element element) { 2318 void generateGetter(Send send, Element element) {
2291 if (Elements.isStaticOrTopLevelField(element)) { 2319 if (Elements.isStaticOrTopLevelField(element)) {
2292 Constant value; 2320 Constant value;
2293 if (element.isField() && !element.isAssignable()) { 2321 if (element.isField() && !element.isAssignable()) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 name, node.argumentsNode is Prefix); 2629 name, node.argumentsNode is Prefix);
2602 } else { 2630 } else {
2603 dartMethodName = node.selector.asIdentifier().source; 2631 dartMethodName = node.selector.asIdentifier().source;
2604 } 2632 }
2605 2633
2606 Element interceptor = null; 2634 Element interceptor = null;
2607 if (methodInterceptionEnabled && elements[node] == null) { 2635 if (methodInterceptionEnabled && elements[node] == null) {
2608 interceptor = interceptors.getStaticInterceptor(selector); 2636 interceptor = interceptors.getStaticInterceptor(selector);
2609 } 2637 }
2610 if (interceptor != null) { 2638 if (interceptor != null) {
2611 HStatic target = new HStatic(interceptor); 2639 // TODO(ngeoffray): This is currently the case, but should be
ahe 2012/11/13 12:42:41 What does "This" mean here?
ngeoffray 2012/11/13 12:51:50 The assertion. Comment added.
2612 add(target); 2640 // updated once we start implementing more of the interceptors class.
2613 inputs.add(target); 2641 assert(node.receiver != null);
2614 visit(node.receiver); 2642 if (interceptor == backend.getInterceptorMethod) {
2615 inputs.add(pop()); 2643 HStatic target = new HStatic(interceptor);
2616 addGenericSendArgumentsToList(node.arguments, inputs); 2644 add(target);
2617 pushWithPosition(new HInvokeInterceptor(selector, inputs), node); 2645 visit(node.receiver);
2646 HInstruction receiver = pop();
2647 HInstruction instruction =
2648 new HInvokeStatic(<HInstruction>[target, receiver]);
2649 add(instruction);
2650 inputs.add(instruction);
2651 inputs.add(receiver);
2652 addDynamicSendArgumentsToList(node, inputs);
2653 // The first entry in the inputs list is the interceptor. The
2654 // second is the receiver, and the others are the arguments.
2655 instruction = new HInvokeDynamicMethod(selector, inputs);
2656 pushWithPosition(instruction, node);
2657 } else {
2658 HStatic target = new HStatic(interceptor);
2659 add(target);
2660 inputs.add(target);
2661 visit(node.receiver);
2662 inputs.add(pop());
2663 addGenericSendArgumentsToList(node.arguments, inputs);
2664 pushWithPosition(new HInvokeInterceptor(selector, inputs), node);
2665 }
2618 return; 2666 return;
2619 } 2667 }
2620 2668
2621 Element element = elements[node]; 2669 Element element = elements[node];
2622 if (element != null && compiler.world.hasNoOverridingMember(element)) { 2670 if (element != null && compiler.world.hasNoOverridingMember(element)) {
2623 if (tryInlineMethod(element, selector, node.arguments)) { 2671 if (tryInlineMethod(element, selector, node.arguments)) {
2624 return; 2672 return;
2625 } 2673 }
2626 } 2674 }
2627 2675
(...skipping 2132 matching lines...) Expand 10 before | Expand all | Expand 10 after
4760 new HSubGraphBlockInformation(elseBranch.graph)); 4808 new HSubGraphBlockInformation(elseBranch.graph));
4761 4809
4762 HBasicBlock conditionStartBlock = conditionBranch.block; 4810 HBasicBlock conditionStartBlock = conditionBranch.block;
4763 conditionStartBlock.setBlockFlow(info, joinBlock); 4811 conditionStartBlock.setBlockFlow(info, joinBlock);
4764 SubGraph conditionGraph = conditionBranch.graph; 4812 SubGraph conditionGraph = conditionBranch.graph;
4765 HIf branch = conditionGraph.end.last; 4813 HIf branch = conditionGraph.end.last;
4766 assert(branch is HIf); 4814 assert(branch is HIf);
4767 branch.blockInformation = conditionStartBlock.blockFlow; 4815 branch.blockInformation = conditionStartBlock.blockFlow;
4768 } 4816 }
4769 } 4817 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698