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 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1642 TypeMask receiverType = new TypeMask.nonNullExact(superClass); | 1642 TypeMask receiverType = new TypeMask.nonNullExact(superClass); |
1643 selector = new TypedSelector(receiverType, selector); | 1643 selector = new TypedSelector(receiverType, selector); |
1644 // TODO(floitsch): we know the target. We shouldn't register a | 1644 // TODO(floitsch): we know the target. We shouldn't register a |
1645 // dynamic getter. | 1645 // dynamic getter. |
1646 world.registerDynamicGetter(selector); | 1646 world.registerDynamicGetter(selector); |
1647 world.registerGetterForSuperMethod(node.element); | 1647 world.registerGetterForSuperMethod(node.element); |
1648 methodName = backend.namer.invocationName(selector); | 1648 methodName = backend.namer.invocationName(selector); |
1649 } else { | 1649 } else { |
1650 methodName = backend.namer.getNameOfInstanceMember(superMethod); | 1650 methodName = backend.namer.getNameOfInstanceMember(superMethod); |
1651 } | 1651 } |
1652 js.PropertyAccess method = | 1652 push(js.js('#.prototype.#.call(#)', [ |
floitsch
2014/04/22 16:11:18
can we import with show 'js', so that we don't hav
sra1
2014/04/23 02:33:50
Then we would have to change the current import na
| |
1653 backend.namer.elementAccess(superClass)['prototype'][methodName]; | 1653 backend.namer.elementAccess(superClass), |
1654 push(jsPropertyCall( | 1654 methodName, visitArguments(node.inputs, start: 0)]), |
1655 method, "call", visitArguments(node.inputs, start: 0)), node); | 1655 node); |
1656 } | 1656 } |
1657 } | 1657 } |
1658 | 1658 |
1659 visitFieldGet(HFieldGet node) { | 1659 visitFieldGet(HFieldGet node) { |
1660 use(node.receiver); | 1660 use(node.receiver); |
1661 Element element = node.element; | 1661 Element element = node.element; |
1662 if (node.isNullCheck) { | 1662 if (node.isNullCheck) { |
1663 // We access a JavaScript member we know all objects besides | 1663 // We access a JavaScript member we know all objects besides |
1664 // null and undefined have: V8 does not like accessing a member | 1664 // null and undefined have: V8 does not like accessing a member |
1665 // that does not exist. | 1665 // that does not exist. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1718 nativeBehavior.typesReturned.forEach((type) { | 1718 nativeBehavior.typesReturned.forEach((type) { |
1719 if (type is DartType) { | 1719 if (type is DartType) { |
1720 world.registerInstantiatedType(type, work.resolutionTree); | 1720 world.registerInstantiatedType(type, work.resolutionTree); |
1721 } | 1721 } |
1722 }); | 1722 }); |
1723 } | 1723 } |
1724 | 1724 |
1725 visitForeign(HForeign node) { | 1725 visitForeign(HForeign node) { |
1726 List<HInstruction> inputs = node.inputs; | 1726 List<HInstruction> inputs = node.inputs; |
1727 if (node.isJsStatement()) { | 1727 if (node.isJsStatement()) { |
1728 if (!inputs.isEmpty) { | 1728 //if (!inputs.isEmpty) { |
floitsch
2014/04/22 16:11:18
dead code.
sra1
2014/04/23 02:33:50
Done.
| |
1729 compiler.internalError(node, "Foreign statement with inputs."); | 1729 // compiler.internalError(node, "Foreign statement with inputs."); |
1730 //} | |
1731 //pushStatement(node.codeTemplate.ast, node); | |
1732 List<js.Expression> interpolatedExpressions = <js.Expression>[]; | |
1733 for (int i = 0; i < inputs.length; i++) { | |
1734 use(inputs[i]); | |
1735 interpolatedExpressions.add(pop()); | |
1730 } | 1736 } |
1731 pushStatement(node.codeAst, node); | 1737 pushStatement(node.codeTemplate.instantiate(interpolatedExpressions)); |
1732 } else { | 1738 } else { |
1733 if (!inputs.isEmpty) { | 1739 List<js.Expression> interpolatedExpressions = <js.Expression>[]; |
1734 List<js.Expression> interpolatedExpressions = <js.Expression>[]; | 1740 for (int i = 0; i < inputs.length; i++) { |
1735 for (int i = 0; i < inputs.length; i++) { | 1741 use(inputs[i]); |
1736 use(inputs[i]); | 1742 interpolatedExpressions.add(pop()); |
1737 interpolatedExpressions.add(pop()); | |
1738 } | |
1739 var visitor = new js.UninterpolateJSExpression(interpolatedExpressions); | |
1740 push(visitor.visit(node.codeAst), node); | |
1741 } else { | |
1742 push(node.codeAst, node); | |
1743 } | 1743 } |
1744 push(node.codeTemplate.instantiate(interpolatedExpressions)); | |
1744 } | 1745 } |
1745 | 1746 |
1746 // TODO(sra): Tell world.nativeEnqueuer about the types created here. | 1747 // TODO(sra): Tell world.nativeEnqueuer about the types created here. |
1747 registerForeignTypes(node); | 1748 registerForeignTypes(node); |
1748 } | 1749 } |
1749 | 1750 |
1750 visitForeignNew(HForeignNew node) { | 1751 visitForeignNew(HForeignNew node) { |
1751 String jsClassReference = backend.namer.isolateAccess(node.element); | 1752 String jsClassReference = backend.namer.isolateAccess(node.element); |
1752 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); | 1753 List<js.Expression> arguments = visitArguments(node.inputs, start: 0); |
1753 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it | 1754 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it |
(...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2616 } | 2617 } |
2617 | 2618 |
2618 if (namedParameters.isEmpty) { | 2619 if (namedParameters.isEmpty) { |
2619 var arguments = [returnType]; | 2620 var arguments = [returnType]; |
2620 if (!parameterTypes.isEmpty || !optionalParameterTypes.isEmpty) { | 2621 if (!parameterTypes.isEmpty || !optionalParameterTypes.isEmpty) { |
2621 arguments.add(new js.ArrayInitializer.from(parameterTypes)); | 2622 arguments.add(new js.ArrayInitializer.from(parameterTypes)); |
2622 } | 2623 } |
2623 if (!optionalParameterTypes.isEmpty) { | 2624 if (!optionalParameterTypes.isEmpty) { |
2624 arguments.add(new js.ArrayInitializer.from(optionalParameterTypes)); | 2625 arguments.add(new js.ArrayInitializer.from(optionalParameterTypes)); |
2625 } | 2626 } |
2626 push(accessHelper('buildFunctionType')(arguments)); | 2627 push(js.js('#(#)', [accessHelper('buildFunctionType'), arguments])); |
2627 } else { | 2628 } else { |
2628 var arguments = [ | 2629 var arguments = [ |
2629 returnType, | 2630 returnType, |
2630 new js.ArrayInitializer.from(parameterTypes), | 2631 new js.ArrayInitializer.from(parameterTypes), |
2631 new js.ObjectInitializer(namedParameters)]; | 2632 new js.ObjectInitializer(namedParameters)]; |
2632 push(accessHelper('buildNamedFunctionType')(arguments)); | 2633 push(js.js('#(#)', [accessHelper('buildNamedFunctionType'), arguments])); |
2633 } | 2634 } |
2634 } | 2635 } |
2635 | 2636 |
2636 void visitReadTypeVariable(HReadTypeVariable node) { | 2637 void visitReadTypeVariable(HReadTypeVariable node) { |
2637 TypeVariableElement element = node.dartType.element; | 2638 TypeVariableElement element = node.dartType.element; |
2638 Element helperElement = compiler.findHelper('convertRtiToRuntimeType'); | 2639 Element helperElement = compiler.findHelper('convertRtiToRuntimeType'); |
2639 world.registerStaticUse(helperElement); | 2640 world.registerStaticUse(helperElement); |
2640 | 2641 |
2641 use(node.inputs[0]); | 2642 use(node.inputs[0]); |
2642 if (node.hasReceiver) { | 2643 if (node.hasReceiver) { |
2643 if (backend.isInterceptorClass(element.getEnclosingClass())) { | 2644 if (backend.isInterceptorClass(element.getEnclosingClass())) { |
2644 int index = RuntimeTypes.getTypeVariableIndex(element); | 2645 int index = RuntimeTypes.getTypeVariableIndex(element); |
2645 js.Expression receiver = pop(); | 2646 js.Expression receiver = pop(); |
2646 js.Expression helper = backend.namer.elementAccess(helperElement); | 2647 js.Expression helper = backend.namer.elementAccess(helperElement); |
2647 push(helper(js.js(r'#.$builtinTypeInfo && #.$builtinTypeInfo[#]', | 2648 push(js.js(r'#(#.$builtinTypeInfo && #.$builtinTypeInfo[#])', |
2648 [receiver, receiver, js.js.toExpression(index)]))); | 2649 [helper, receiver, receiver, js.js.number(index)])); |
2649 } else { | 2650 } else { |
2650 backend.emitter.registerReadTypeVariable(element); | 2651 backend.emitter.registerReadTypeVariable(element); |
2651 push( | 2652 push(js.js('#.#()', |
2652 js.js('#.${backend.namer.readTypeVariableName(element)}()', pop())); | 2653 [pop(), backend.namer.readTypeVariableName(element)])); |
2653 } | 2654 } |
2654 } else { | 2655 } else { |
2655 push( | 2656 push(js.js('#(#)', [ |
2656 backend.namer.elementAccess( | 2657 backend.namer.elementAccess( |
2657 compiler.findHelper('convertRtiToRuntimeType'))(pop())); | 2658 compiler.findHelper('convertRtiToRuntimeType')), |
2659 pop()])); | |
2658 } | 2660 } |
2659 } | 2661 } |
2660 | 2662 |
2661 void visitInterfaceType(HInterfaceType node) { | 2663 void visitInterfaceType(HInterfaceType node) { |
2662 List<js.Expression> typeArguments = <js.Expression>[]; | 2664 List<js.Expression> typeArguments = <js.Expression>[]; |
2663 for (HInstruction type in node.inputs) { | 2665 for (HInstruction type in node.inputs) { |
2664 use(type); | 2666 use(type); |
2665 typeArguments.add(pop()); | 2667 typeArguments.add(pop()); |
2666 } | 2668 } |
2667 | 2669 |
2668 ClassElement cls = node.dartType.element; | 2670 ClassElement cls = node.dartType.element; |
2669 var arguments = [ | 2671 var arguments = [ |
2670 backend.namer.elementAccess(backend.getImplementationClass(cls))]; | 2672 backend.namer.elementAccess(backend.getImplementationClass(cls))]; |
2671 if (!typeArguments.isEmpty) { | 2673 if (!typeArguments.isEmpty) { |
2672 arguments.add(new js.ArrayInitializer.from(typeArguments)); | 2674 arguments.add(new js.ArrayInitializer.from(typeArguments)); |
2673 } | 2675 } |
2674 push(accessHelper('buildInterfaceType')(arguments)); | 2676 push(js.js('#(#)', [accessHelper('buildInterfaceType'), arguments])); |
2675 } | 2677 } |
2676 | 2678 |
2677 void visitVoidType(HVoidType node) { | 2679 void visitVoidType(HVoidType node) { |
2678 push(accessHelper('getVoidRuntimeType')()); | 2680 push(js.js('#()', accessHelper('getVoidRuntimeType'))); |
2679 } | 2681 } |
2680 | 2682 |
2681 void visitDynamicType(HDynamicType node) { | 2683 void visitDynamicType(HDynamicType node) { |
2682 push(accessHelper('getDynamicRuntimeType')()); | 2684 push(js.js('#()', accessHelper('getDynamicRuntimeType'))); |
2683 } | 2685 } |
2684 | 2686 |
2685 js.PropertyAccess accessHelper(String name) { | 2687 js.PropertyAccess accessHelper(String name) { |
2686 Element helper = compiler.findHelper(name); | 2688 Element helper = compiler.findHelper(name); |
2687 if (helper == null) { | 2689 if (helper == null) { |
2688 // For mocked-up tests. | 2690 // For mocked-up tests. |
2689 return js.js('(void 0).$name'); | 2691 return js.js('(void 0).$name'); |
2690 } | 2692 } |
2691 world.registerStaticUse(helper); | 2693 world.registerStaticUse(helper); |
2692 return backend.namer.elementAccess(helper); | 2694 return backend.namer.elementAccess(helper); |
2693 } | 2695 } |
2694 } | 2696 } |
OLD | NEW |