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 2558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2569 helper = | 2569 helper = |
2570 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); | 2570 backend.getCheckedModeHelper(type, typeCast: node.isCastTypeCheck); |
2571 } | 2571 } |
2572 | 2572 |
2573 push(helper.generateCall(this, node)); | 2573 push(helper.generateCall(this, node)); |
2574 } | 2574 } |
2575 | 2575 |
2576 void visitTypeKnown(HTypeKnown node) { | 2576 void visitTypeKnown(HTypeKnown node) { |
2577 use(node.checkedInput); | 2577 use(node.checkedInput); |
2578 } | 2578 } |
2579 | |
2580 void visitFunctionType(HFunctionType node) { | |
2581 node.dartType.accept(new TypeBuilder(node.inputs), this); | |
2582 } | |
2583 | |
2584 void visitReadTypeVariable(HReadTypeVariable node) { | |
2585 TypeVariableElement element = node.dartType.element; | |
2586 world.registerStaticUse(compiler.findHelper('convertRtiToRuntimeType')); | |
2587 | |
2588 use(node.inputs[0]); | |
2589 if (node.hasReceiver) { | |
2590 backend.emitter.registerReadTypeVariable(element); | |
2591 push(js.js('#.${backend.namer.readTypeVariableName(element)}()', pop())); | |
2592 } else { | |
2593 push( | |
2594 backend.namer.elementAccess( | |
2595 compiler.findHelper('convertRtiToRuntimeType'))(pop())); | |
2596 } | |
2597 } | |
2598 } | |
2599 | |
2600 class TypeBuilder implements DartTypeVisitor<dynamic, SsaCodeGenerator> { | |
ngeoffray
2013/11/01 13:54:02
Doing this at codegen time prevents doing all pote
ahe
2013/11/04 17:23:45
That is a good point. We talked about this earlier
| |
2601 final List<HInstruction> typeVariables; | |
2602 int lastUsedTypeVariable = -1; | |
2603 | |
2604 TypeBuilder(this.typeVariables); | |
2605 | |
2606 HReadTypeVariable nextTypeVariable(TypeVariableType type) { | |
2607 HReadTypeVariable instruction = typeVariables[++lastUsedTypeVariable]; | |
2608 assert(instruction.dartType == type); | |
2609 return instruction; | |
2610 } | |
2611 | |
2612 void visitType(DartType type, A argument) { | |
Johnni Winther
2013/10/30 12:02:19
'A argument' -> '_'.
| |
2613 throw 'Internal error $type'; | |
2614 } | |
2615 | |
2616 void visitVoidType(VoidType type, SsaCodeGenerator generator) { | |
2617 generator.push(accessHelper('getVoidRuntimeType', generator)()); | |
2618 } | |
2619 | |
2620 void visitTypeVariableType(TypeVariableType type, | |
2621 SsaCodeGenerator generator) { | |
2622 generator.use(nextTypeVariable(type)); | |
2623 } | |
2624 | |
2625 void visitFunctionType(FunctionType type, SsaCodeGenerator generator) { | |
2626 type.returnType.accept(this, generator); | |
2627 js.Node returnType = generator.pop(); | |
2628 | |
2629 List<js.Expression> parameterTypes = <js.Expression>[]; | |
2630 for (DartType parameter in type.parameterTypes) { | |
2631 parameter.accept(this, generator); | |
2632 parameterTypes.add(generator.pop()); | |
2633 } | |
2634 | |
2635 List<js.Expression> optionalParameterTypes = <js.Expression>[]; | |
2636 for (DartType parameter in type.optionalParameterTypes) { | |
2637 parameter.accept(this, generator); | |
2638 optionalParameterTypes.add(generator.pop()); | |
2639 } | |
2640 | |
2641 Link<DartType> namedParameterTypes = type.namedParameterTypes; | |
2642 List<js.Property> namedParameters = <js.Property>[]; | |
2643 for (String name in type.namedParameters) { | |
2644 namedParameterTypes.head.accept(this, generator); | |
2645 namedParameters.add(new js.Property(js.string(name), generator.pop())); | |
2646 namedParameterTypes = namedParameterTypes.tail; | |
2647 } | |
2648 | |
2649 if (namedParameters.isEmpty) { | |
2650 var arguments = [ | |
2651 returnType, | |
2652 new js.ArrayInitializer.from(parameterTypes)]; | |
2653 if (!optionalParameterTypes.isEmpty) { | |
2654 arguments.add(optionalParameterTypes); | |
2655 } | |
2656 generator.push(accessHelper('buildFunctionType', generator)(arguments)); | |
2657 } else { | |
2658 var arguments = [ | |
2659 returnType, | |
2660 new js.ArrayInitializer.from(parameterTypes), | |
2661 new js.ObjectInitializer(namedParameters)]; | |
2662 generator.push( | |
2663 accessHelper('buildNamedFunctionType', generator)(arguments)); | |
2664 } | |
2665 } | |
2666 | |
2667 void visitMalformedType(MalformedType type, SsaCodeGenerator generator) { | |
2668 // TODO(ahe): Discard type variables. | |
2669 generator.push(accessHelper('getDynamicRuntimeType', generator)()); | |
2670 } | |
2671 | |
2672 void visitStatementType(StatementType type, SsaCodeGenerator generator) { | |
2673 throw 'not implemented visitStatementType($type)'; | |
2674 } | |
2675 | |
2676 void visitGenericType(GenericType type, SsaCodeGenerator generator) { | |
2677 throw 'not implemented visitGenericType($type)'; | |
2678 } | |
2679 | |
2680 void visitInterfaceType(InterfaceType type, SsaCodeGenerator generator) { | |
2681 List<js.Expression> typeArguments = <js.Expression>[]; | |
2682 for (DartType typeArgument in type.typeArguments) { | |
2683 typeArgument.accept(this, generator); | |
2684 typeArguments.add(generator.pop()); | |
2685 } | |
2686 | |
2687 final JavaScriptBackend backend = generator.backend; | |
2688 final Namer namer = backend.namer; | |
2689 | |
2690 var arguments = [ | |
2691 namer.elementAccess(backend.getImplementationClass(type.element)), | |
2692 new js.ArrayInitializer.from(typeArguments)]; | |
2693 generator.push(accessHelper('buildInterfaceType', generator)(arguments)); | |
2694 } | |
2695 | |
2696 void visitTypedefType(TypedefType type, SsaCodeGenerator generator) { | |
2697 // TODO(ahe): This doesn't work for type variables. | |
2698 DartType unaliased = type.unalias(generator.compiler); | |
2699 if (unaliased is TypedefType) throw 'unable to unalias $type'; | |
2700 unaliased.accept(this, generator); | |
2701 } | |
2702 | |
2703 void visitDynamicType(DynamicType type, SsaCodeGenerator generator) { | |
2704 generator.push(accessHelper('getDynamicRuntimeType', generator)()); | |
2705 } | |
2706 | |
2707 js.PropertyAccess accessHelper(String name, SsaCodeGenerator generator) { | |
2708 Element helper = generator.compiler.findHelper(name); | |
2709 generator.world.registerStaticUse(helper); | |
2710 return generator.backend.namer.elementAccess(helper); | |
2711 } | |
2579 } | 2712 } |
2580 | 2713 |
2581 String singleIdentityComparison(HInstruction left, | 2714 String singleIdentityComparison(HInstruction left, |
2582 HInstruction right, | 2715 HInstruction right, |
2583 Compiler compiler) { | 2716 Compiler compiler) { |
2584 // Returns the single identity comparison (== or ===) or null if a more | 2717 // Returns the single identity comparison (== or ===) or null if a more |
2585 // complex expression is required. | 2718 // complex expression is required. |
2586 if ((left.isConstant() && left.isConstantSentinel()) || | 2719 if ((left.isConstant() && left.isConstantSentinel()) || |
2587 (right.isConstant() && right.isConstantSentinel())) return '==='; | 2720 (right.isConstant() && right.isConstantSentinel())) return '==='; |
2588 HType leftType = left.instructionType; | 2721 HType leftType = left.instructionType; |
2589 HType rightType = right.instructionType; | 2722 HType rightType = right.instructionType; |
2590 if (leftType.canBeNull() && rightType.canBeNull()) { | 2723 if (leftType.canBeNull() && rightType.canBeNull()) { |
2591 if (left.isConstantNull() || right.isConstantNull() || | 2724 if (left.isConstantNull() || right.isConstantNull() || |
2592 (leftType.isPrimitive(compiler) && leftType == rightType)) { | 2725 (leftType.isPrimitive(compiler) && leftType == rightType)) { |
2593 return '=='; | 2726 return '=='; |
2594 } | 2727 } |
2595 return null; | 2728 return null; |
2596 } else { | 2729 } else { |
2597 return '==='; | 2730 return '==='; |
2598 } | 2731 } |
2599 } | 2732 } |
OLD | NEW |