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

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

Issue 12334070: Support runtime check of function types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: New check encoding Created 7 years, 9 months 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 /** 7 /**
8 * A special element for the extra parameter taken by intercepted 8 * A special element for the extra parameter taken by intercepted
9 * methods. We need to override [Element.computeType] because our 9 * methods. We need to override [Element.computeType] because our
10 * optimizers may look at its declared type. 10 * optimizers may look at its declared type.
(...skipping 1609 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 HParameterValue param = addParameter(typeVariable.element); 1620 HParameterValue param = addParameter(typeVariable.element);
1621 localsHandler.directLocals[typeVariable.element] = param; 1621 localsHandler.directLocals[typeVariable.element] = param;
1622 }); 1622 });
1623 } 1623 }
1624 } 1624 }
1625 1625
1626 HInstruction potentiallyCheckType( 1626 HInstruction potentiallyCheckType(
1627 HInstruction original, DartType type, 1627 HInstruction original, DartType type,
1628 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 1628 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
1629 if (!compiler.enableTypeAssertions) return original; 1629 if (!compiler.enableTypeAssertions) return original;
1630 type = type.unalias(compiler);
1630 HInstruction other = original.convertType(compiler, type, kind); 1631 HInstruction other = original.convertType(compiler, type, kind);
1631 if (other != original) add(other); 1632 if (other != original) add(other);
1633 compiler.enqueuer.codegen.registerIsCheck(type, work.resolutionTree);
1632 return other; 1634 return other;
1633 } 1635 }
1634 1636
1635 HGraph closeFunction() { 1637 HGraph closeFunction() {
1636 // TODO(kasperl): Make this goto an implicit return. 1638 // TODO(kasperl): Make this goto an implicit return.
1637 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit); 1639 if (!isAborted()) close(new HGoto()).addSuccessor(graph.exit);
1638 graph.finalize(); 1640 graph.finalize();
1639 return graph; 1641 return graph;
1640 } 1642 }
1641 1643
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
2224 Element capturedLocal = nestedClosureData.capturedFieldMapping[member]; 2226 Element capturedLocal = nestedClosureData.capturedFieldMapping[member];
2225 assert(capturedLocal != null); 2227 assert(capturedLocal != null);
2226 capturedVariables.add(localsHandler.readLocal(capturedLocal)); 2228 capturedVariables.add(localsHandler.readLocal(capturedLocal));
2227 } 2229 }
2228 }); 2230 });
2229 2231
2230 HType type = new HType.nonNullExact( 2232 HType type = new HType.nonNullExact(
2231 compiler.functionClass.computeType(compiler), 2233 compiler.functionClass.computeType(compiler),
2232 compiler); 2234 compiler);
2233 push(new HForeignNew(closureClassElement, type, capturedVariables)); 2235 push(new HForeignNew(closureClassElement, type, capturedVariables));
2236
2237 Element methodElement = nestedClosureData.closureElement;
2238 if (compiler.backend.methodNeedsRti(methodElement)) {
2239 compiler.backend.registerGenericClosure(
2240 methodElement, compiler.enqueuer.codegen, work.resolutionTree);
2241 }
2234 } 2242 }
2235 2243
2236 visitFunctionDeclaration(FunctionDeclaration node) { 2244 visitFunctionDeclaration(FunctionDeclaration node) {
2237 visit(node.function); 2245 visit(node.function);
2238 localsHandler.updateLocal(elements[node], pop()); 2246 localsHandler.updateLocal(elements[node], pop());
2239 } 2247 }
2240 2248
2241 visitIdentifier(Identifier node) { 2249 visitIdentifier(Identifier node) {
2242 if (node.isThis()) { 2250 if (node.isThis()) {
2243 stack.add(localsHandler.readThis()); 2251 stack.add(localsHandler.readThis());
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2602 inputs.add(runtimeType); 2610 inputs.add(runtimeType);
2603 })); 2611 }));
2604 } 2612 }
2605 String template = '[${templates.join(', ')}]'; 2613 String template = '[${templates.join(', ')}]';
2606 HInstruction representation = 2614 HInstruction representation =
2607 createForeign(template, HType.READABLE_ARRAY, inputs); 2615 createForeign(template, HType.READABLE_ARRAY, inputs);
2608 return representation; 2616 return representation;
2609 } 2617 }
2610 } 2618 }
2611 2619
2612 visitOperatorSend(node) { 2620 visitOperatorSend(Send node) {
2613 Operator op = node.selector; 2621 Operator op = node.selector;
2614 if (const SourceString("[]") == op.source) { 2622 if (const SourceString("[]") == op.source) {
2615 visitDynamicSend(node); 2623 visitDynamicSend(node);
2616 } else if (const SourceString("&&") == op.source || 2624 } else if (const SourceString("&&") == op.source ||
2617 const SourceString("||") == op.source) { 2625 const SourceString("||") == op.source) {
2618 visitLogicalAndOr(node, op); 2626 visitLogicalAndOr(node, op);
2619 } else if (const SourceString("!") == op.source) { 2627 } else if (const SourceString("!") == op.source) {
2620 visitLogicalNot(node); 2628 visitLogicalNot(node);
2621 } else if (node.argumentsNode is Prefix) { 2629 } else if (node.argumentsNode is Prefix) {
2622 visitUnary(node, op); 2630 visitUnary(node, op);
(...skipping 24 matching lines...) Expand all
2647 HInstruction expression = pop(); 2655 HInstruction expression = pop();
2648 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); 2656 TypeAnnotation typeAnnotation = argument.asTypeAnnotation();
2649 bool isNot = false; 2657 bool isNot = false;
2650 // TODO(ngeoffray): Duplicating pattern in resolver. We should 2658 // TODO(ngeoffray): Duplicating pattern in resolver. We should
2651 // add a new kind of node. 2659 // add a new kind of node.
2652 if (typeAnnotation == null) { 2660 if (typeAnnotation == null) {
2653 typeAnnotation = argument.asSend().receiver; 2661 typeAnnotation = argument.asSend().receiver;
2654 isNot = true; 2662 isNot = true;
2655 } 2663 }
2656 DartType type = elements.getType(typeAnnotation); 2664 DartType type = elements.getType(typeAnnotation);
2665 type = type.unalias(compiler);
2657 if (type.isMalformed) { 2666 if (type.isMalformed) {
2658 String reasons = Types.fetchReasonsFromMalformedType(type); 2667 String reasons = Types.fetchReasonsFromMalformedType(type);
2659 if (compiler.enableTypeAssertions) { 2668 if (compiler.enableTypeAssertions) {
2660 generateMalformedSubtypeError(node, expression, type, reasons); 2669 generateMalformedSubtypeError(node, expression, type, reasons);
2661 } else { 2670 } else {
2662 generateRuntimeError(node, '$type is malformed: $reasons'); 2671 generateRuntimeError(node, '$type is malformed: $reasons');
2663 } 2672 }
2664 return; 2673 return;
2665 } 2674 }
2666 2675
2667 HInstruction instruction; 2676 HInstruction instruction;
2668 if (type.kind == TypeKind.TYPE_VARIABLE) { 2677 if (type.kind == TypeKind.FUNCTION) {
2678 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
2679 HInstruction isFuncSubtypeCall = new HStatic(checkFunctionSubtype);
2680 add(isFuncSubtypeCall);
2681
2682 HInstruction signatureName = graph.addConstantString(
2683 new DartString.literal(backend.namer.getFunctionTypeName(type)),
2684 node, constantSystem);
2685
2686 HInstruction context;
2687 HInstruction contextName;
2688 if (type.containsTypeVariables) {
2689 context = localsHandler.readThis();
2690
2691 ClassElement contextClass = Types.getClassContext(type);
2692 contextName = graph.addConstantString(
2693 new DartString.literal(backend.namer.getName(contextClass)),
2694 node, constantSystem);
2695 } else {
2696 context = graph.addConstantNull(constantSystem);
2697 contextName = graph.addConstantNull(constantSystem);
2698 }
2699
2700 List<HInstruction> inputs = <HInstruction>[isFuncSubtypeCall,
2701 expression,
2702 signatureName,
2703 context,
2704 contextName];
2705 HInstruction call = new HInvokeStatic(inputs, HType.UNKNOWN);
2706 add(call);
2707 instruction = new HIs(type, <HInstruction>[expression, call],
2708 HIs.COMPOUND_CHECK);
2709 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2669 HInstruction runtimeType = addTypeVariableReference(type); 2710 HInstruction runtimeType = addTypeVariableReference(type);
2670 Element helper = backend.getGetObjectIsSubtype(); 2711 Element helper = backend.getGetObjectIsSubtype();
2671 HInstruction helperCall = new HStatic(helper); 2712 HInstruction helperCall = new HStatic(helper);
2672 add(helperCall); 2713 add(helperCall);
2673 List<HInstruction> inputs = <HInstruction>[helperCall, expression, 2714 List<HInstruction> inputs = <HInstruction>[helperCall, expression,
2674 runtimeType]; 2715 runtimeType];
2675 HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN); 2716 HInstruction call = new HInvokeStatic(inputs, HType.BOOLEAN);
2676 add(call); 2717 add(call);
2677 instruction = new HIs(type, <HInstruction>[expression, call], 2718 instruction = new HIs(type, <HInstruction>[expression, call],
2678 HIs.VARIABLE_CHECK); 2719 HIs.VARIABLE_CHECK);
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
3034 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) { 3075 } else if (name == const SourceString('RAW_DART_FUNCTION_REF')) {
3035 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF'); 3076 handleForeignRawFunctionRef(node, 'RAW_DART_FUNCTION_REF');
3036 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) { 3077 } else if (name == const SourceString('JS_SET_CURRENT_ISOLATE')) {
3037 handleForeignSetCurrentIsolate(node); 3078 handleForeignSetCurrentIsolate(node);
3038 } else if (name == const SourceString('JS_CREATE_ISOLATE')) { 3079 } else if (name == const SourceString('JS_CREATE_ISOLATE')) {
3039 handleForeignCreateIsolate(node); 3080 handleForeignCreateIsolate(node);
3040 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) { 3081 } else if (name == const SourceString('JS_OPERATOR_IS_PREFIX')) {
3041 stack.add(addConstantString(node, backend.namer.operatorIsPrefix())); 3082 stack.add(addConstantString(node, backend.namer.operatorIsPrefix()));
3042 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) { 3083 } else if (name == const SourceString('JS_OPERATOR_AS_PREFIX')) {
3043 stack.add(addConstantString(node, backend.namer.operatorAsPrefix())); 3084 stack.add(addConstantString(node, backend.namer.operatorAsPrefix()));
3085 } else if (name == const SourceString('JS_SIGNATURE_NAME')) {
3086 stack.add(addConstantString(node, backend.namer.operatorSignature()));
3087 } else if (name == const SourceString('JS_FUNCTION_TYPE_TAG')) {
3088 stack.add(addConstantString(node, backend.namer.functionTypeTag()));
3089 } else if (name == const SourceString('JS_FUNCTION_TYPE_VOID_RETURN_TAG')) {
3090 stack.add(addConstantString(node,
3091 backend.namer.functionTypeVoidReturnTag()));
3092 } else if (name == const SourceString('JS_FUNCTION_TYPE_RETURN_TYPE_TAG')) {
3093 stack.add(addConstantString(node,
3094 backend.namer.functionTypeReturnTypeTag()));
3095 } else if (name ==
3096 const SourceString('JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG')) {
3097 stack.add(addConstantString(node,
3098 backend.namer.functionTypeRequiredParametersTag()));
3099 } else if (name ==
3100 const SourceString('JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG')) {
3101 stack.add(addConstantString(node,
3102 backend.namer.functionTypeOptionalParametersTag()));
3103 } else if (name ==
3104 const SourceString('JS_FUNCTION_TYPE_NAMED_PARAMETERS_TAG')) {
3105 stack.add(addConstantString(node,
3106 backend.namer.functionTypeNamedParametersTag()));
3044 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) { 3107 } else if (name == const SourceString('JS_DART_OBJECT_CONSTRUCTOR')) {
3045 handleForeignDartObjectJsConstructorFunction(node); 3108 handleForeignDartObjectJsConstructorFunction(node);
3046 } else { 3109 } else {
3047 throw "Unknown foreign: ${selector}"; 3110 throw "Unknown foreign: ${selector}";
3048 } 3111 }
3049 } 3112 }
3050 3113
3051 generateSuperNoSuchMethodSend(Send node, 3114 generateSuperNoSuchMethodSend(Send node,
3052 Selector selector, 3115 Selector selector,
3053 List<HInstruction> arguments) { 3116 List<HInstruction> arguments) {
(...skipping 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after
5110 new HSubGraphBlockInformation(elseBranch.graph)); 5173 new HSubGraphBlockInformation(elseBranch.graph));
5111 5174
5112 HBasicBlock conditionStartBlock = conditionBranch.block; 5175 HBasicBlock conditionStartBlock = conditionBranch.block;
5113 conditionStartBlock.setBlockFlow(info, joinBlock); 5176 conditionStartBlock.setBlockFlow(info, joinBlock);
5114 SubGraph conditionGraph = conditionBranch.graph; 5177 SubGraph conditionGraph = conditionBranch.graph;
5115 HIf branch = conditionGraph.end.last; 5178 HIf branch = conditionGraph.end.last;
5116 assert(branch is HIf); 5179 assert(branch is HIf);
5117 branch.blockInformation = conditionStartBlock.blockFlow; 5180 branch.blockInformation = conditionStartBlock.blockFlow;
5118 } 5181 }
5119 } 5182 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698