Chromium Code Reviews| 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 |