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

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

Issue 12211013: Allow intercepted calls to have typed selectors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months 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 SsaCodeGeneratorTask extends CompilerTask { 7 class SsaCodeGeneratorTask extends CompilerTask {
8 8
9 final JavaScriptBackend backend; 9 final JavaScriptBackend backend;
10 10
(...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 SourceString name = node.selector.name; 1512 SourceString name = node.selector.name;
1513 String methodName; 1513 String methodName;
1514 List<js.Expression> arguments = visitArguments(node.inputs); 1514 List<js.Expression> arguments = visitArguments(node.inputs);
1515 Element target = node.element; 1515 Element target = node.element;
1516 1516
1517 if (target != null) { 1517 if (target != null) {
1518 // Avoid adding the generative constructor name to the list of 1518 // Avoid adding the generative constructor name to the list of
1519 // seen selectors. 1519 // seen selectors.
1520 if (target.isGenerativeConstructorBody()) { 1520 if (target.isGenerativeConstructorBody()) {
1521 methodName = name.slowToString(); 1521 methodName = name.slowToString();
1522 } else if (target == backend.jsArrayAdd) { 1522 } else if (!node.isInterceptorCall) {
1523 methodName = 'push'; 1523 if (target == backend.jsArrayAdd) {
1524 } else if (target == backend.jsArrayRemoveLast) { 1524 methodName = 'push';
1525 methodName = 'pop'; 1525 } else if (target == backend.jsArrayRemoveLast) {
1526 } else if (target == backend.jsStringSplit) { 1526 methodName = 'pop';
1527 methodName = 'split'; 1527 } else if (target == backend.jsStringSplit) {
1528 // Split returns a List, so we make sure the backend knows the 1528 methodName = 'split';
1529 // list class is instantiated. 1529 // Split returns a List, so we make sure the backend knows the
1530 world.registerInstantiatedClass(compiler.listClass); 1530 // list class is instantiated.
1531 } else if (target == backend.jsStringConcat) { 1531 world.registerInstantiatedClass(compiler.listClass);
1532 push(new js.Binary('+', object, arguments[0]), node); 1532 } else if (target == backend.jsStringConcat) {
1533 return; 1533 push(new js.Binary('+', object, arguments[0]), node);
1534 return;
1535 }
1534 } 1536 }
1535 } 1537 }
1536 1538
1537 if (methodName == null) { 1539 if (methodName == null) {
1538 methodName = backend.namer.invocationName(node.selector); 1540 methodName = backend.namer.invocationName(node.selector);
1539 registerMethodInvoke(node); 1541 registerMethodInvoke(node);
1540 } 1542 }
1541 push(jsPropertyCall(object, methodName, arguments), node); 1543 push(jsPropertyCall(object, methodName, arguments), node);
1542 } 1544 }
1543 1545
1544 void visitOneShotInterceptor(HOneShotInterceptor node) { 1546 void visitOneShotInterceptor(HOneShotInterceptor node) {
1545 List<js.Expression> arguments = visitArguments(node.inputs); 1547 List<js.Expression> arguments = visitArguments(node.inputs);
1546 var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE); 1548 var isolate = new js.VariableUse(backend.namer.CURRENT_ISOLATE);
1547 Selector selector = node.selector; 1549 Selector selector = node.selector;
1548 String methodName = backend.namer.oneShotInterceptorName(selector); 1550 String methodName = backend.namer.oneShotInterceptorName(selector);
1549 push(jsPropertyCall(isolate, methodName, arguments), node); 1551 push(jsPropertyCall(isolate, methodName, arguments), node);
1550 backend.registerSpecializedGetInterceptor(node.interceptedClasses); 1552 backend.registerSpecializedGetInterceptor(node.interceptedClasses);
1551 backend.addOneShotInterceptor(selector); 1553 backend.addOneShotInterceptor(selector);
1552 if (selector.isGetter()) { 1554 if (selector.isGetter()) {
1553 registerGetter(node); 1555 registerGetter(node);
1554 } else if (selector.isSetter()) { 1556 } else if (selector.isSetter()) {
1555 registerSetter(node); 1557 registerSetter(node);
1556 } else { 1558 } else {
1557 registerMethodInvoke(node); 1559 registerMethodInvoke(node);
1558 } 1560 }
1559 } 1561 }
1560 1562
1561 Selector getOptimizedSelectorFor(HInvokeDynamic node, 1563 Selector getOptimizedSelectorFor(HInvokeDynamic node,
1562 Selector defaultSelector) { 1564 Selector defaultSelector) {
1563 // TODO(ngeoffray): Type intercepted calls.
1564 if (node.isInterceptorCall) return defaultSelector;
1565 // If [JSInvocationMirror.invokeOn] has been called, we must not create a 1565 // If [JSInvocationMirror.invokeOn] has been called, we must not create a
1566 // typed selector based on the receiver type. 1566 // typed selector based on the receiver type.
1567 if (node.element == null && // Invocation is not exact. 1567 if (node.element == null && // Invocation is not exact.
1568 backend.compiler.enabledInvokeOn) { 1568 backend.compiler.enabledInvokeOn) {
1569 return defaultSelector; 1569 return defaultSelector;
1570 } 1570 }
1571 HType receiverHType = types[node.inputs[0]]; 1571 int receiverIndex = node.isInterceptorCall ? 1 : 0;
1572 HType receiverHType = types[node.inputs[receiverIndex]];
1572 DartType receiverType = receiverHType.computeType(compiler); 1573 DartType receiverType = receiverHType.computeType(compiler);
1573 if (receiverType != null && 1574 if (receiverType != null &&
1574 !identical(receiverType.kind, TypeKind.MALFORMED_TYPE)) { 1575 !identical(receiverType.kind, TypeKind.MALFORMED_TYPE)) {
1575 return new TypedSelector(receiverType, defaultSelector); 1576 return new TypedSelector(receiverType, defaultSelector);
1576 } else { 1577 } else {
1577 return defaultSelector; 1578 return defaultSelector;
1578 } 1579 }
1579 } 1580 }
1580 1581
1581 void registerInvoke(HInvokeDynamic node) { 1582 void registerInvoke(HInvokeDynamic node) {
(...skipping 26 matching lines...) Expand all
1608 // TODO(kasperl): If we have a typed selector for the call, we 1609 // TODO(kasperl): If we have a typed selector for the call, we
1609 // may know something about the types of closures that need 1610 // may know something about the types of closures that need
1610 // the specific closure call method. 1611 // the specific closure call method.
1611 Selector call = new Selector.callClosureFrom(selector); 1612 Selector call = new Selector.callClosureFrom(selector);
1612 world.registerDynamicInvocation(call.name, call); 1613 world.registerDynamicInvocation(call.name, call);
1613 } 1614 }
1614 1615
1615 if (target != null) { 1616 if (target != null) {
1616 // If we know we're calling a specific method, register that 1617 // If we know we're calling a specific method, register that
1617 // method only. 1618 // method only.
1618 world.registerDynamicInvocationOf(target); 1619 world.registerDynamicInvocationOf(target, selector);
1619 } else { 1620 } else {
1620 SourceString name = node.selector.name; 1621 SourceString name = node.selector.name;
1621 world.registerDynamicInvocation(name, selector); 1622 world.registerDynamicInvocation(name, selector);
1622 } 1623 }
1623 registerInvoke(node); 1624 registerInvoke(node);
1624 } 1625 }
1625 1626
1626 void registerSetter(HInvokeDynamic node) { 1627 void registerSetter(HInvokeDynamic node) {
1627 Selector selector = getOptimizedSelectorFor(node, node.selector); 1628 Selector selector = getOptimizedSelectorFor(node, node.selector);
1628 world.registerDynamicSetter(selector.name, selector); 1629 world.registerDynamicSetter(selector.name, selector);
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2416 "malformedTypeCheck": 2417 "malformedTypeCheck":
2417 const SourceString("malformedTypeCheck") 2418 const SourceString("malformedTypeCheck")
2418 }; 2419 };
2419 2420
2420 if (node.isChecked) { 2421 if (node.isChecked) {
2421 DartType type = node.type.computeType(compiler); 2422 DartType type = node.type.computeType(compiler);
2422 Element element = type.element; 2423 Element element = type.element;
2423 world.registerIsCheck(type); 2424 world.registerIsCheck(type);
2424 2425
2425 if (node.isArgumentTypeCheck) { 2426 if (node.isArgumentTypeCheck) {
2426 if (element == compiler.intClass) { 2427 if (element == backend.jsIntClass) {
2427 checkInt(node.checkedInput, '!=='); 2428 checkInt(node.checkedInput, '!==');
2428 } else { 2429 } else {
2429 assert(element == compiler.numClass); 2430 assert(element == backend.jsNumberClass);
2430 checkNum(node.checkedInput, '!=='); 2431 checkNum(node.checkedInput, '!==');
2431 } 2432 }
2432 js.Expression test = pop(); 2433 js.Expression test = pop();
2433 js.Block oldContainer = currentContainer; 2434 js.Block oldContainer = currentContainer;
2434 js.Statement body = new js.Block.empty(); 2435 js.Statement body = new js.Block.empty();
2435 currentContainer = body; 2436 currentContainer = body;
2436 generateThrowWithHelper('iae', node.checkedInput); 2437 generateThrowWithHelper('iae', node.checkedInput);
2437 currentContainer = oldContainer; 2438 currentContainer = oldContainer;
2438 body = unwrapStatement(body); 2439 body = unwrapStatement(body);
2439 pushStatement(new js.If.noElse(test, body), node); 2440 pushStatement(new js.If.noElse(test, body), node);
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 if (leftType.canBeNull() && rightType.canBeNull()) { 3002 if (leftType.canBeNull() && rightType.canBeNull()) {
3002 if (left.isConstantNull() || right.isConstantNull() || 3003 if (left.isConstantNull() || right.isConstantNull() ||
3003 (leftType.isPrimitive() && leftType == rightType)) { 3004 (leftType.isPrimitive() && leftType == rightType)) {
3004 return '=='; 3005 return '==';
3005 } 3006 }
3006 return null; 3007 return null;
3007 } else { 3008 } else {
3008 return '==='; 3009 return '===';
3009 } 3010 }
3010 } 3011 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698