| 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 SsaCodeGeneratorTask extends CompilerTask { | 7 class SsaCodeGeneratorTask extends CompilerTask { |
| 8 | 8 |
| 9 final JavaScriptBackend backend; | 9 final JavaScriptBackend backend; |
| 10 | 10 |
| (...skipping 1508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1519 return new js.Call(new js.PropertyAccess.field(receiver, fieldName), | 1519 return new js.Call(new js.PropertyAccess.field(receiver, fieldName), |
| 1520 arguments); | 1520 arguments); |
| 1521 } | 1521 } |
| 1522 | 1522 |
| 1523 // TODO(ngeoffray): Once we remove the old interceptors, we can | 1523 // TODO(ngeoffray): Once we remove the old interceptors, we can |
| 1524 // start using HInvokeInterceptor to represent interceptor calls on | 1524 // start using HInvokeInterceptor to represent interceptor calls on |
| 1525 // an Interceptor class. Currently we recognize if a call is a call | 1525 // an Interceptor class. Currently we recognize if a call is a call |
| 1526 // on an interceptor by checking if the arguments in the inputs list | 1526 // on an interceptor by checking if the arguments in the inputs list |
| 1527 // is one more than the arguments in the selector. The extra | 1527 // is one more than the arguments in the selector. The extra |
| 1528 // argument in an interceptor call is the actual receiver. | 1528 // argument in an interceptor call is the actual receiver. |
| 1529 bool isInterceptorCall(HInvokeDynamicMethod node) { | 1529 bool isInterceptorCall(HInvokeDynamic node) { |
| 1530 return node.inputs.length - 1 != node.selector.argumentCount; | 1530 return node.inputs.length - 1 != node.selector.argumentCount; |
| 1531 } | 1531 } |
| 1532 | 1532 |
| 1533 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 1533 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 1534 use(node.receiver); | 1534 use(node.receiver); |
| 1535 js.Expression object = pop(); | 1535 js.Expression object = pop(); |
| 1536 SourceString name = node.selector.name; | 1536 SourceString name = node.selector.name; |
| 1537 String methodName; | 1537 String methodName; |
| 1538 List<js.Expression> arguments; | 1538 List<js.Expression> arguments; |
| 1539 Element target = node.element; | 1539 Element target = node.element; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1551 | 1551 |
| 1552 // Register this invocation to collect the types used at all call sites. | 1552 // Register this invocation to collect the types used at all call sites. |
| 1553 Selector selector = getOptimizedSelectorFor(node, node.selector); | 1553 Selector selector = getOptimizedSelectorFor(node, node.selector); |
| 1554 // TODO(ngeoffray): Remove the following restriction. Because | 1554 // TODO(ngeoffray): Remove the following restriction. Because |
| 1555 // the second input of this interceptor call is the actual | 1555 // the second input of this interceptor call is the actual |
| 1556 // receiver (the first is the interceptor), the backend gets | 1556 // receiver (the first is the interceptor), the backend gets |
| 1557 // confused. We should pass a list of types instead of a node to | 1557 // confused. We should pass a list of types instead of a node to |
| 1558 // [registerDynamicInvocation]. | 1558 // [registerDynamicInvocation]. |
| 1559 if (!isInterceptorCall(node)) { | 1559 if (!isInterceptorCall(node)) { |
| 1560 backend.registerDynamicInvocation(node, selector, types); | 1560 backend.registerDynamicInvocation(node, selector, types); |
| 1561 } else { |
| 1562 backend.addInterceptedSelector(selector); |
| 1561 } | 1563 } |
| 1562 | 1564 |
| 1563 // If we don't know what we're calling or if we are calling a getter, | 1565 // If we don't know what we're calling or if we are calling a getter, |
| 1564 // we need to register that fact that we may be calling a closure | 1566 // we need to register that fact that we may be calling a closure |
| 1565 // with the same arguments. | 1567 // with the same arguments. |
| 1566 if (target == null || target.isGetter()) { | 1568 if (target == null || target.isGetter()) { |
| 1567 // TODO(kasperl): If we have a typed selector for the call, we | 1569 // TODO(kasperl): If we have a typed selector for the call, we |
| 1568 // may know something about the types of closures that need | 1570 // may know something about the types of closures that need |
| 1569 // the specific closure call method. | 1571 // the specific closure call method. |
| 1570 Selector call = new Selector.callClosureFrom(selector); | 1572 Selector call = new Selector.callClosureFrom(selector); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1581 world.registerDynamicInvocation(name, selector); | 1583 world.registerDynamicInvocation(name, selector); |
| 1582 } | 1584 } |
| 1583 } | 1585 } |
| 1584 push(jsPropertyCall(object, methodName, arguments), node); | 1586 push(jsPropertyCall(object, methodName, arguments), node); |
| 1585 } | 1587 } |
| 1586 | 1588 |
| 1587 Selector getOptimizedSelectorFor(HInvokeDynamic node, | 1589 Selector getOptimizedSelectorFor(HInvokeDynamic node, |
| 1588 Selector defaultSelector) { | 1590 Selector defaultSelector) { |
| 1589 // TODO(4434): For private members we need to use the untyped selector. | 1591 // TODO(4434): For private members we need to use the untyped selector. |
| 1590 if (defaultSelector.name.isPrivate()) return defaultSelector; | 1592 if (defaultSelector.name.isPrivate()) return defaultSelector; |
| 1593 // TODO(ngeoffray): Type intercepted calls. |
| 1594 if (isInterceptorCall(node)) return defaultSelector; |
| 1591 // If [JSInvocationMirror.invokeOn] has been called, we must not create a | 1595 // If [JSInvocationMirror.invokeOn] has been called, we must not create a |
| 1592 // typed selector based on the receiver type. | 1596 // typed selector based on the receiver type. |
| 1593 if (node.element == null && // Invocation is not exact. | 1597 if (node.element == null && // Invocation is not exact. |
| 1594 backend.compiler.enabledInvokeOn) { | 1598 backend.compiler.enabledInvokeOn) { |
| 1595 return defaultSelector; | 1599 return defaultSelector; |
| 1596 } | 1600 } |
| 1597 HType receiverHType = types[node.inputs[0]]; | 1601 HType receiverHType = types[node.inputs[0]]; |
| 1598 DartType receiverType = receiverHType.computeType(compiler); | 1602 DartType receiverType = receiverHType.computeType(compiler); |
| 1599 if (receiverType != null) { | 1603 if (receiverType != null) { |
| 1600 return new TypedSelector(receiverType, defaultSelector); | 1604 return new TypedSelector(receiverType, defaultSelector); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1613 backend.addedDynamicSetter(selector, types[node.inputs[1]]); | 1617 backend.addedDynamicSetter(selector, types[node.inputs[1]]); |
| 1614 } | 1618 } |
| 1615 | 1619 |
| 1616 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 1620 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 1617 use(node.receiver); | 1621 use(node.receiver); |
| 1618 Selector getter = node.selector; | 1622 Selector getter = node.selector; |
| 1619 String name = backend.namer.getterName(getter.library, getter.name); | 1623 String name = backend.namer.getterName(getter.library, getter.name); |
| 1620 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1624 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1621 world.registerDynamicGetter( | 1625 world.registerDynamicGetter( |
| 1622 getter.name, getOptimizedSelectorFor(node, getter)); | 1626 getter.name, getOptimizedSelectorFor(node, getter)); |
| 1627 if (isInterceptorCall(node)) { |
| 1628 backend.addInterceptedSelector(getter); |
| 1629 } |
| 1623 } | 1630 } |
| 1624 | 1631 |
| 1625 visitInvokeClosure(HInvokeClosure node) { | 1632 visitInvokeClosure(HInvokeClosure node) { |
| 1626 use(node.receiver); | 1633 use(node.receiver); |
| 1627 push(jsPropertyCall(pop(), | 1634 push(jsPropertyCall(pop(), |
| 1628 backend.namer.closureInvocationName(node.selector), | 1635 backend.namer.closureInvocationName(node.selector), |
| 1629 visitArguments(node.inputs)), | 1636 visitArguments(node.inputs)), |
| 1630 node); | 1637 node); |
| 1631 Selector call = new Selector.callClosureFrom(node.selector); | 1638 Selector call = new Selector.callClosureFrom(node.selector); |
| 1632 world.registerDynamicInvocation(call.name, call); | 1639 world.registerDynamicInvocation(call.name, call); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1976 HInstruction input = node.inputs[0]; | 1983 HInstruction input = node.inputs[0]; |
| 1977 if (input.isConstantNull()) { | 1984 if (input.isConstantNull()) { |
| 1978 pushStatement(new js.Return(null), node); | 1985 pushStatement(new js.Return(null), node); |
| 1979 } else { | 1986 } else { |
| 1980 use(node.inputs[0]); | 1987 use(node.inputs[0]); |
| 1981 pushStatement(new js.Return(pop()), node); | 1988 pushStatement(new js.Return(pop()), node); |
| 1982 } | 1989 } |
| 1983 } | 1990 } |
| 1984 | 1991 |
| 1985 visitThis(HThis node) { | 1992 visitThis(HThis node) { |
| 1986 if (backend.isInterceptorClass(work.element.getEnclosingClass())){ | 1993 push(new js.This()); |
| 1987 push(new js.VariableUse(variableNames.getName(node)), node); | |
| 1988 } else { | |
| 1989 push(new js.This()); | |
| 1990 } | |
| 1991 } | 1994 } |
| 1992 | 1995 |
| 1993 visitThrow(HThrow node) { | 1996 visitThrow(HThrow node) { |
| 1994 if (node.isRethrow) { | 1997 if (node.isRethrow) { |
| 1995 use(node.inputs[0]); | 1998 use(node.inputs[0]); |
| 1996 pushStatement(new js.Throw(pop()), node); | 1999 pushStatement(new js.Throw(pop()), node); |
| 1997 } else { | 2000 } else { |
| 1998 generateThrowWithHelper(r'$throw', node.inputs[0]); | 2001 generateThrowWithHelper(r'$throw', node.inputs[0]); |
| 1999 } | 2002 } |
| 2000 } | 2003 } |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3101 if (leftType.canBeNull() && rightType.canBeNull()) { | 3104 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3102 if (left.isConstantNull() || right.isConstantNull() || | 3105 if (left.isConstantNull() || right.isConstantNull() || |
| 3103 (leftType.isPrimitive() && leftType == rightType)) { | 3106 (leftType.isPrimitive() && leftType == rightType)) { |
| 3104 return '=='; | 3107 return '=='; |
| 3105 } | 3108 } |
| 3106 return null; | 3109 return null; |
| 3107 } else { | 3110 } else { |
| 3108 return '==='; | 3111 return '==='; |
| 3109 } | 3112 } |
| 3110 } | 3113 } |
| OLD | NEW |