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

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

Issue 50313007: Implement dynamic function checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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 2558 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698