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

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

Issue 50313007: Implement dynamic function checks. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r30787 Created 7 years 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 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 HInstruction representations = buildTypeArgumentRepresentations(type); 2071 HInstruction representations = buildTypeArgumentRepresentations(type);
2072 add(representations); 2072 add(representations);
2073 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 2073 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
2074 original, representations); 2074 original, representations);
2075 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 2075 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
2076 TypeMask subtype = original.instructionType; 2076 TypeMask subtype = original.instructionType;
2077 HInstruction typeVariable = addTypeVariableReference(type); 2077 HInstruction typeVariable = addTypeVariableReference(type);
2078 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, 2078 return new HTypeConversion.withTypeRepresentation(type, kind, subtype,
2079 original, typeVariable); 2079 original, typeVariable);
2080 } else if (type.kind == TypeKind.FUNCTION) { 2080 } else if (type.kind == TypeKind.FUNCTION) {
2081 if (backend.rti.isSimpleFunctionType(type)) { 2081 String name = kind == HTypeConversion.CAST_TYPE_CHECK
2082 return original.convertType(compiler, type, kind); 2082 ? '_asCheck' : '_assertCheck';
2083 } 2083
2084 TypeMask subtype = original.instructionType; 2084 List arguments = [buildFunctionType(type), original];
2085 if (type.containsTypeVariables) { 2085 pushInvokeDynamic(
2086 bool contextIsTypeArguments = false; 2086 null,
2087 HInstruction context; 2087 new Selector.call(name, compiler.jsHelperLibrary, 1),
2088 if (!currentElement.enclosingElement.isClosure() 2088 arguments);
2089 && currentElement.isInstanceMember()) { 2089
2090 context = localsHandler.readThis(); 2090 return new HTypeConversion(type, kind, original.instructionType, pop());
2091 } else {
2092 ClassElement contextClass = Types.getClassContext(type);
2093 context = buildTypeVariableList(contextClass);
2094 add(context);
2095 contextIsTypeArguments = true;
2096 }
2097 return new HTypeConversion.withContext(type, kind, subtype,
2098 original, context, contextIsTypeArguments: contextIsTypeArguments);
2099 } else {
2100 return new HTypeConversion(type, kind, subtype, original);
2101 }
2102 } else { 2091 } else {
2103 return original.convertType(compiler, type, kind); 2092 return original.convertType(compiler, type, kind);
2104 } 2093 }
2105 } 2094 }
2106 2095
2107 HInstruction potentiallyCheckType(HInstruction original, DartType type, 2096 HInstruction potentiallyCheckType(HInstruction original, DartType type,
2108 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) { 2097 { int kind: HTypeConversion.CHECKED_MODE_CHECK }) {
2109 if (!compiler.enableTypeAssertions) return original; 2098 if (!compiler.enableTypeAssertions) return original;
2110 HInstruction other = buildTypeConversion(original, type, kind); 2099 HInstruction other = buildTypeConversion(original, type, kind);
2111 if (other != original) add(other); 2100 if (other != original) add(other);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 value, 2154 value,
2166 compiler.boolClass.computeType(compiler), 2155 compiler.boolClass.computeType(compiler),
2167 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); 2156 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
2168 } 2157 }
2169 HInstruction result = new HBoolify(value, backend.boolType); 2158 HInstruction result = new HBoolify(value, backend.boolType);
2170 add(result); 2159 add(result);
2171 return result; 2160 return result;
2172 } 2161 }
2173 2162
2174 HInstruction attachPosition(HInstruction target, Node node) { 2163 HInstruction attachPosition(HInstruction target, Node node) {
2175 target.sourcePosition = sourceFileLocationForBeginToken(node); 2164 if (node != null) {
2165 target.sourcePosition = sourceFileLocationForBeginToken(node);
2166 }
2176 return target; 2167 return target;
2177 } 2168 }
2178 2169
2179 SourceFileLocation sourceFileLocationForBeginToken(Node node) => 2170 SourceFileLocation sourceFileLocationForBeginToken(Node node) =>
2180 sourceFileLocationForToken(node, node.getBeginToken()); 2171 sourceFileLocationForToken(node, node.getBeginToken());
2181 2172
2182 SourceFileLocation sourceFileLocationForEndToken(Node node) => 2173 SourceFileLocation sourceFileLocationForEndToken(Node node) =>
2183 sourceFileLocationForToken(node, node.getEndToken()); 2174 sourceFileLocationForToken(node, node.getEndToken());
2184 2175
2185 SourceFileLocation sourceFileLocationForToken(Node node, Token token) { 2176 SourceFileLocation sourceFileLocationForToken(Node node, Token token) {
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after
3076 !link.isEmpty; 3067 !link.isEmpty;
3077 link = link.tail) { 3068 link = link.tail) {
3078 inputs.add(addTypeVariableReference(link.head)); 3069 inputs.add(addTypeVariableReference(link.head));
3079 } 3070 }
3080 return buildLiteralList(inputs); 3071 return buildLiteralList(inputs);
3081 } 3072 }
3082 3073
3083 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) { 3074 HInstruction buildIsNode(Node node, DartType type, HInstruction expression) {
3084 type = type.unalias(compiler); 3075 type = type.unalias(compiler);
3085 if (type.kind == TypeKind.FUNCTION) { 3076 if (type.kind == TypeKind.FUNCTION) {
3086 if (backend.rti.isSimpleFunctionType(type)) { 3077 List arguments = [buildFunctionType(type), expression];
3087 // TODO(johnniwinther): Avoid interceptor if unneeded. 3078 pushInvokeDynamic(
3088 return new HIs.raw( 3079 node, new Selector.call('_isTest', compiler.jsHelperLibrary, 1),
3089 type, expression, invokeInterceptor(expression), backend.boolType); 3080 arguments);
3090 } 3081 return new HIs.compound(type, expression, pop(), backend.boolType);
3091 Element checkFunctionSubtype = backend.getCheckFunctionSubtype();
3092
3093 HInstruction signatureName = graph.addConstantString(
3094 new DartString.literal(backend.namer.getFunctionTypeName(type)),
3095 compiler);
3096
3097 HInstruction contextName;
3098 HInstruction context;
3099 HInstruction typeArguments;
3100 if (type.containsTypeVariables) {
3101 ClassElement contextClass = Types.getClassContext(type);
3102 contextName = graph.addConstantString(
3103 new DartString.literal(backend.namer.getNameOfClass(contextClass)),
3104 compiler);
3105 if (!currentElement.enclosingElement.isClosure()
3106 && currentElement.isInstanceMember()) {
3107 context = localsHandler.readThis();
3108 typeArguments = graph.addConstantNull(compiler);
3109 } else {
3110 context = graph.addConstantNull(compiler);
3111 typeArguments = buildTypeVariableList(contextClass);
3112 add(typeArguments);
3113 }
3114 } else {
3115 contextName = graph.addConstantNull(compiler);
3116 context = graph.addConstantNull(compiler);
3117 typeArguments = graph.addConstantNull(compiler);
3118 }
3119
3120 List<HInstruction> inputs = <HInstruction>[expression,
3121 signatureName,
3122 contextName,
3123 context,
3124 typeArguments];
3125 pushInvokeStatic(node, checkFunctionSubtype, inputs, backend.boolType);
3126 HInstruction call = pop();
3127 return new HIs.compound(type, expression, call, backend.boolType);
3128 } else if (type.kind == TypeKind.TYPE_VARIABLE) { 3082 } else if (type.kind == TypeKind.TYPE_VARIABLE) {
3129 HInstruction runtimeType = addTypeVariableReference(type); 3083 HInstruction runtimeType = addTypeVariableReference(type);
3130 Element helper = backend.getCheckSubtypeOfRuntimeType(); 3084 Element helper = backend.getCheckSubtypeOfRuntimeType();
3131 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 3085 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
3132 pushInvokeStatic(null, helper, inputs, backend.boolType); 3086 pushInvokeStatic(null, helper, inputs, backend.boolType);
3133 HInstruction call = pop(); 3087 HInstruction call = pop();
3134 return new HIs.variable(type, expression, call, backend.boolType); 3088 return new HIs.variable(type, expression, call, backend.boolType);
3135 } else if (RuntimeTypes.hasTypeArguments(type)) { 3089 } else if (RuntimeTypes.hasTypeArguments(type)) {
3136 ClassElement element = type.element; 3090 ClassElement element = type.element;
3137 Element helper = backend.getCheckSubtype(); 3091 Element helper = backend.getCheckSubtype();
(...skipping 21 matching lines...) Expand all
3159 } else { 3113 } else {
3160 if (backend.hasDirectCheckFor(type)) { 3114 if (backend.hasDirectCheckFor(type)) {
3161 return new HIs.direct(type, expression, backend.boolType); 3115 return new HIs.direct(type, expression, backend.boolType);
3162 } 3116 }
3163 // TODO(johnniwinther): Avoid interceptor if unneeded. 3117 // TODO(johnniwinther): Avoid interceptor if unneeded.
3164 return new HIs.raw( 3118 return new HIs.raw(
3165 type, expression, invokeInterceptor(expression), backend.boolType); 3119 type, expression, invokeInterceptor(expression), backend.boolType);
3166 } 3120 }
3167 } 3121 }
3168 3122
3123 HInstruction buildFunctionType(FunctionType type) {
3124 type.accept(new TypeBuilder(), this);
3125 return pop();
3126 }
3127
3169 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) { 3128 void addDynamicSendArgumentsToList(Send node, List<HInstruction> list) {
3170 Selector selector = elements.getSelector(node); 3129 Selector selector = elements.getSelector(node);
3171 if (selector.namedArgumentCount == 0) { 3130 if (selector.namedArgumentCount == 0) {
3172 addGenericSendArgumentsToList(node.arguments, list); 3131 addGenericSendArgumentsToList(node.arguments, list);
3173 } else { 3132 } else {
3174 // Visit positional arguments and add them to the list. 3133 // Visit positional arguments and add them to the list.
3175 Link<Node> arguments = node.arguments; 3134 Link<Node> arguments = node.arguments;
3176 int positionalArgumentCount = selector.positionalArgumentCount; 3135 int positionalArgumentCount = selector.positionalArgumentCount;
3177 for (int i = 0; 3136 for (int i = 0;
3178 i < positionalArgumentCount; 3137 i < positionalArgumentCount;
(...skipping 2775 matching lines...) Expand 10 before | Expand all | Expand 10 after
5954 new HSubGraphBlockInformation(elseBranch.graph)); 5913 new HSubGraphBlockInformation(elseBranch.graph));
5955 5914
5956 HBasicBlock conditionStartBlock = conditionBranch.block; 5915 HBasicBlock conditionStartBlock = conditionBranch.block;
5957 conditionStartBlock.setBlockFlow(info, joinBlock); 5916 conditionStartBlock.setBlockFlow(info, joinBlock);
5958 SubGraph conditionGraph = conditionBranch.graph; 5917 SubGraph conditionGraph = conditionBranch.graph;
5959 HIf branch = conditionGraph.end.last; 5918 HIf branch = conditionGraph.end.last;
5960 assert(branch is HIf); 5919 assert(branch is HIf);
5961 branch.blockInformation = conditionStartBlock.blockFlow; 5920 branch.blockInformation = conditionStartBlock.blockFlow;
5962 } 5921 }
5963 } 5922 }
5923
5924 class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> {
5925 void visitType(DartType type, _) {
5926 throw 'Internal error $type';
5927 }
5928
5929 void visitVoidType(VoidType type, SsaBuilder builder) {
5930 ClassElement cls = builder.compiler.findHelper('VoidRuntimeType');
5931 builder.push(new HVoidType(type, new TypeMask.exact(cls)));
5932 }
5933
5934 void visitTypeVariableType(TypeVariableType type,
5935 SsaBuilder builder) {
5936 ClassElement cls = builder.compiler.findHelper('RuntimeType');
5937 TypeMask instructionType = new TypeMask.subclass(cls);
5938 if (!builder.currentElement.enclosingElement.isClosure() &&
5939 builder.currentElement.isInstanceMember()) {
5940 HInstruction receiver = builder.localsHandler.readThis();
5941 builder.push(new HReadTypeVariable(type, receiver, instructionType));
5942 } else {
5943 builder.push(
5944 new HReadTypeVariable.noReceiver(
5945 type, builder.addTypeVariableReference(type), instructionType));
5946 }
5947 }
5948
5949 void visitFunctionType(FunctionType type, SsaBuilder builder) {
5950 type.returnType.accept(this, builder);
5951 HInstruction returnType = builder.pop();
5952 List<HInstruction> inputs = <HInstruction>[returnType];
5953
5954 for (DartType parameter in type.parameterTypes) {
5955 parameter.accept(this, builder);
5956 inputs.add(builder.pop());
5957 }
5958
5959 for (DartType parameter in type.optionalParameterTypes) {
5960 parameter.accept(this, builder);
5961 inputs.add(builder.pop());
5962 }
5963
5964 Link<DartType> namedParameterTypes = type.namedParameterTypes;
5965 for (String name in type.namedParameters) {
5966 DartString dartString = new DartString.literal(name);
5967 inputs.add(
5968 builder.graph.addConstantString(dartString, builder.compiler));
5969 namedParameterTypes.head.accept(this, builder);
5970 inputs.add(builder.pop());
5971 namedParameterTypes = namedParameterTypes.tail;
5972 }
5973
5974 ClassElement cls = builder.compiler.findHelper('RuntimeFunctionType');
5975 builder.push(new HFunctionType(inputs, type, new TypeMask.exact(cls)));
5976 }
5977
5978 void visitMalformedType(MalformedType type, SsaBuilder builder) {
5979 visitDynamicType(builder.compiler.types.dynamicType, builder);
5980 }
5981
5982 void visitStatementType(StatementType type, SsaBuilder builder) {
5983 throw 'not implemented visitStatementType($type)';
5984 }
5985
5986 void visitGenericType(GenericType type, SsaBuilder builder) {
5987 throw 'not implemented visitGenericType($type)';
5988 }
5989
5990 void visitInterfaceType(InterfaceType type, SsaBuilder builder) {
5991 List<HInstruction> inputs = <HInstruction>[];
5992 for (DartType typeArgument in type.typeArguments) {
5993 typeArgument.accept(this, builder);
5994 inputs.add(builder.pop());
5995 }
5996 ClassElement cls;
5997 if (type.typeArguments.isEmpty) {
5998 cls = builder.compiler.findHelper('RuntimeTypePlain');
5999 } else {
6000 cls = builder.compiler.findHelper('RuntimeTypeGeneric');
6001 }
6002 builder.push(new HInterfaceType(inputs, type, new TypeMask.exact(cls)));
6003 }
6004
6005 void visitTypedefType(TypedefType type, SsaBuilder builder) {
6006 DartType unaliased = type.unalias(builder.compiler);
6007 if (unaliased is TypedefType) throw 'unable to unalias $type';
6008 unaliased.accept(this, builder);
6009 }
6010
6011 void visitDynamicType(DynamicType type, SsaBuilder builder) {
6012 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType');
6013 builder.push(new HDynamicType(type, new TypeMask.exact(cls)));
6014 }
6015 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698