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 /** | 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 implement [TypedElement.type] because our | 9 * methods. We need to implement [TypedElement.type] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 2182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2193 /// Build a [HTypeConversion] for convertion [original] to type [type]. | 2193 /// Build a [HTypeConversion] for convertion [original] to type [type]. |
2194 /// | 2194 /// |
2195 /// Invariant: [type] must be valid in the context. | 2195 /// Invariant: [type] must be valid in the context. |
2196 /// See [LocalsHandler.substInContext]. | 2196 /// See [LocalsHandler.substInContext]. |
2197 HInstruction buildTypeConversion(HInstruction original, | 2197 HInstruction buildTypeConversion(HInstruction original, |
2198 DartType type, | 2198 DartType type, |
2199 int kind) { | 2199 int kind) { |
2200 if (type == null) return original; | 2200 if (type == null) return original; |
2201 type = type.unalias(compiler); | 2201 type = type.unalias(compiler); |
2202 assert(assertTypeInContext(type, original)); | 2202 assert(assertTypeInContext(type, original)); |
2203 if (type.kind == TypeKind.INTERFACE && !type.treatAsRaw) { | 2203 if (type.isInterfaceType && !type.treatAsRaw) { |
2204 TypeMask subtype = new TypeMask.subtype(type.element); | 2204 TypeMask subtype = new TypeMask.subtype(type.element); |
2205 HInstruction representations = buildTypeArgumentRepresentations(type); | 2205 HInstruction representations = buildTypeArgumentRepresentations(type); |
2206 add(representations); | 2206 add(representations); |
2207 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 2207 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
2208 original, representations); | 2208 original, representations); |
2209 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 2209 } else if (type.isTypeVariable) { |
2210 TypeMask subtype = original.instructionType; | 2210 TypeMask subtype = original.instructionType; |
2211 HInstruction typeVariable = addTypeVariableReference(type); | 2211 HInstruction typeVariable = addTypeVariableReference(type); |
2212 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 2212 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
2213 original, typeVariable); | 2213 original, typeVariable); |
2214 } else if (type.kind == TypeKind.FUNCTION) { | 2214 } else if (type.isFunctionType) { |
2215 String name = kind == HTypeConversion.CAST_TYPE_CHECK | 2215 String name = kind == HTypeConversion.CAST_TYPE_CHECK |
2216 ? '_asCheck' : '_assertCheck'; | 2216 ? '_asCheck' : '_assertCheck'; |
2217 | 2217 |
2218 List arguments = [buildFunctionType(type), original]; | 2218 List arguments = [buildFunctionType(type), original]; |
2219 pushInvokeDynamic( | 2219 pushInvokeDynamic( |
2220 null, | 2220 null, |
2221 new Selector.call(name, compiler.jsHelperLibrary, 1), | 2221 new Selector.call(name, compiler.jsHelperLibrary, 1), |
2222 arguments); | 2222 arguments); |
2223 | 2223 |
2224 return new HTypeConversion(type, kind, original.instructionType, pop()); | 2224 return new HTypeConversion(type, kind, original.instructionType, pop()); |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3135 | 3135 |
3136 HLiteralList buildLiteralList(List<HInstruction> inputs) { | 3136 HLiteralList buildLiteralList(List<HInstruction> inputs) { |
3137 return new HLiteralList(inputs, backend.extendableArrayType); | 3137 return new HLiteralList(inputs, backend.extendableArrayType); |
3138 } | 3138 } |
3139 | 3139 |
3140 // TODO(karlklose): change construction of the representations to be GVN'able | 3140 // TODO(karlklose): change construction of the representations to be GVN'able |
3141 // (dartbug.com/7182). | 3141 // (dartbug.com/7182). |
3142 HInstruction buildTypeArgumentRepresentations(DartType type) { | 3142 HInstruction buildTypeArgumentRepresentations(DartType type) { |
3143 // Compute the representation of the type arguments, including access | 3143 // Compute the representation of the type arguments, including access |
3144 // to the runtime type information for type variables as instructions. | 3144 // to the runtime type information for type variables as instructions. |
3145 if (type.kind == TypeKind.TYPE_VARIABLE) { | 3145 if (type.isTypeVariable) { |
3146 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); | 3146 return buildLiteralList(<HInstruction>[addTypeVariableReference(type)]); |
3147 } else { | 3147 } else { |
3148 assert(type.element.isClass); | 3148 assert(type.element.isClass); |
3149 InterfaceType interface = type; | 3149 InterfaceType interface = type; |
3150 List<HInstruction> inputs = <HInstruction>[]; | 3150 List<HInstruction> inputs = <HInstruction>[]; |
3151 bool first = true; | 3151 bool first = true; |
3152 List<String> templates = <String>[]; | 3152 List<String> templates = <String>[]; |
3153 for (DartType argument in interface.typeArguments) { | 3153 for (DartType argument in interface.typeArguments) { |
3154 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { | 3154 templates.add(rti.getTypeRepresentationWithHashes(argument, (variable) { |
3155 HInstruction runtimeType = addTypeVariableReference(variable); | 3155 HInstruction runtimeType = addTypeVariableReference(variable); |
(...skipping 20 matching lines...) Expand all Loading... |
3176 } else if ("!" == op.source) { | 3176 } else if ("!" == op.source) { |
3177 visitLogicalNot(node); | 3177 visitLogicalNot(node); |
3178 } else if (node.argumentsNode is ast.Prefix) { | 3178 } else if (node.argumentsNode is ast.Prefix) { |
3179 visitUnary(node, op); | 3179 visitUnary(node, op); |
3180 } else if ("is" == op.source) { | 3180 } else if ("is" == op.source) { |
3181 visitIsSend(node); | 3181 visitIsSend(node); |
3182 } else if ("as" == op.source) { | 3182 } else if ("as" == op.source) { |
3183 visit(node.receiver); | 3183 visit(node.receiver); |
3184 HInstruction expression = pop(); | 3184 HInstruction expression = pop(); |
3185 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 3185 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); |
3186 if (type.kind == TypeKind.MALFORMED_TYPE) { | 3186 if (type.isMalformed) { |
3187 ErroneousElement element = type.element; | 3187 ErroneousElement element = type.element; |
3188 generateTypeError(node, element.message); | 3188 generateTypeError(node, element.message); |
3189 } else { | 3189 } else { |
3190 HInstruction converted = buildTypeConversion( | 3190 HInstruction converted = buildTypeConversion( |
3191 expression, | 3191 expression, |
3192 localsHandler.substInContext(type), | 3192 localsHandler.substInContext(type), |
3193 HTypeConversion.CAST_TYPE_CHECK); | 3193 HTypeConversion.CAST_TYPE_CHECK); |
3194 if (converted != expression) add(converted); | 3194 if (converted != expression) add(converted); |
3195 stack.add(converted); | 3195 stack.add(converted); |
3196 } | 3196 } |
(...skipping 16 matching lines...) Expand all Loading... |
3213 add(instruction); | 3213 add(instruction); |
3214 instruction = new HNot(instruction, backend.boolType); | 3214 instruction = new HNot(instruction, backend.boolType); |
3215 } | 3215 } |
3216 push(instruction); | 3216 push(instruction); |
3217 } | 3217 } |
3218 | 3218 |
3219 HInstruction buildIsNode(ast.Node node, | 3219 HInstruction buildIsNode(ast.Node node, |
3220 DartType type, | 3220 DartType type, |
3221 HInstruction expression) { | 3221 HInstruction expression) { |
3222 type = localsHandler.substInContext(type).unalias(compiler); | 3222 type = localsHandler.substInContext(type).unalias(compiler); |
3223 if (type.kind == TypeKind.FUNCTION) { | 3223 if (type.isFunctionType) { |
3224 List arguments = [buildFunctionType(type), expression]; | 3224 List arguments = [buildFunctionType(type), expression]; |
3225 pushInvokeDynamic( | 3225 pushInvokeDynamic( |
3226 node, new Selector.call('_isTest', compiler.jsHelperLibrary, 1), | 3226 node, new Selector.call('_isTest', compiler.jsHelperLibrary, 1), |
3227 arguments); | 3227 arguments); |
3228 return new HIs.compound(type, expression, pop(), backend.boolType); | 3228 return new HIs.compound(type, expression, pop(), backend.boolType); |
3229 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 3229 } else if (type.isTypeVariable) { |
3230 HInstruction runtimeType = addTypeVariableReference(type); | 3230 HInstruction runtimeType = addTypeVariableReference(type); |
3231 Element helper = backend.getCheckSubtypeOfRuntimeType(); | 3231 Element helper = backend.getCheckSubtypeOfRuntimeType(); |
3232 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 3232 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
3233 pushInvokeStatic(null, helper, inputs, backend.boolType); | 3233 pushInvokeStatic(null, helper, inputs, backend.boolType); |
3234 HInstruction call = pop(); | 3234 HInstruction call = pop(); |
3235 return new HIs.variable(type, expression, call, backend.boolType); | 3235 return new HIs.variable(type, expression, call, backend.boolType); |
3236 } else if (RuntimeTypes.hasTypeArguments(type)) { | 3236 } else if (RuntimeTypes.hasTypeArguments(type)) { |
3237 ClassElement element = type.element; | 3237 ClassElement element = type.element; |
3238 Element helper = backend.getCheckSubtype(); | 3238 Element helper = backend.getCheckSubtype(); |
3239 HInstruction representations = | 3239 HInstruction representations = |
3240 buildTypeArgumentRepresentations(type); | 3240 buildTypeArgumentRepresentations(type); |
3241 add(representations); | 3241 add(representations); |
3242 String operator = backend.namer.operatorIs(element); | 3242 String operator = backend.namer.operatorIs(element); |
3243 HInstruction isFieldName = addConstantString(operator); | 3243 HInstruction isFieldName = addConstantString(operator); |
3244 HInstruction asFieldName = compiler.world.hasAnySubtype(element) | 3244 HInstruction asFieldName = compiler.world.hasAnySubtype(element) |
3245 ? addConstantString(backend.namer.substitutionName(element)) | 3245 ? addConstantString(backend.namer.substitutionName(element)) |
3246 : graph.addConstantNull(compiler); | 3246 : graph.addConstantNull(compiler); |
3247 List<HInstruction> inputs = <HInstruction>[expression, | 3247 List<HInstruction> inputs = <HInstruction>[expression, |
3248 isFieldName, | 3248 isFieldName, |
3249 representations, | 3249 representations, |
3250 asFieldName]; | 3250 asFieldName]; |
3251 pushInvokeStatic(node, helper, inputs, backend.boolType); | 3251 pushInvokeStatic(node, helper, inputs, backend.boolType); |
3252 HInstruction call = pop(); | 3252 HInstruction call = pop(); |
3253 return new HIs.compound(type, expression, call, backend.boolType); | 3253 return new HIs.compound(type, expression, call, backend.boolType); |
3254 } else if (type.kind == TypeKind.MALFORMED_TYPE) { | 3254 } else if (type.isMalformed) { |
3255 ErroneousElement element = type.element; | 3255 ErroneousElement element = type.element; |
3256 generateTypeError(node, element.message); | 3256 generateTypeError(node, element.message); |
3257 HInstruction call = pop(); | 3257 HInstruction call = pop(); |
3258 return new HIs.compound(type, expression, call, backend.boolType); | 3258 return new HIs.compound(type, expression, call, backend.boolType); |
3259 } else { | 3259 } else { |
3260 if (backend.hasDirectCheckFor(type)) { | 3260 if (backend.hasDirectCheckFor(type)) { |
3261 return new HIs.direct(type, expression, backend.boolType); | 3261 return new HIs.direct(type, expression, backend.boolType); |
3262 } | 3262 } |
3263 // TODO(johnniwinther): Avoid interceptor if unneeded. | 3263 // TODO(johnniwinther): Avoid interceptor if unneeded. |
3264 return new HIs.raw( | 3264 return new HIs.raw( |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3922 } | 3922 } |
3923 } | 3923 } |
3924 | 3924 |
3925 HInstruction analyzeTypeArgument(DartType argument) { | 3925 HInstruction analyzeTypeArgument(DartType argument) { |
3926 assert(assertTypeInContext(argument)); | 3926 assert(assertTypeInContext(argument)); |
3927 if (argument.treatAsDynamic) { | 3927 if (argument.treatAsDynamic) { |
3928 // Represent [dynamic] as [null]. | 3928 // Represent [dynamic] as [null]. |
3929 return graph.addConstantNull(compiler); | 3929 return graph.addConstantNull(compiler); |
3930 } | 3930 } |
3931 | 3931 |
3932 if (argument.kind == TypeKind.TYPE_VARIABLE) { | 3932 if (argument.isTypeVariable) { |
3933 return addTypeVariableReference(argument); | 3933 return addTypeVariableReference(argument); |
3934 } | 3934 } |
3935 | 3935 |
3936 List<HInstruction> inputs = <HInstruction>[]; | 3936 List<HInstruction> inputs = <HInstruction>[]; |
3937 | 3937 |
3938 String template = rti.getTypeRepresentationWithHashes(argument, (variable) { | 3938 String template = rti.getTypeRepresentationWithHashes(argument, (variable) { |
3939 inputs.add(addTypeVariableReference(variable)); | 3939 inputs.add(addTypeVariableReference(variable)); |
3940 }); | 3940 }); |
3941 | 3941 |
3942 js.Template code = js.js.uncachedExpressionTemplate(template); | 3942 js.Template code = js.js.uncachedExpressionTemplate(template); |
(...skipping 2375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6318 namedParameterTypes.head.accept(this, builder); | 6318 namedParameterTypes.head.accept(this, builder); |
6319 inputs.add(builder.pop()); | 6319 inputs.add(builder.pop()); |
6320 namedParameterTypes = namedParameterTypes.tail; | 6320 namedParameterTypes = namedParameterTypes.tail; |
6321 } | 6321 } |
6322 | 6322 |
6323 ClassElement cls = builder.compiler.findHelper('RuntimeFunctionType'); | 6323 ClassElement cls = builder.compiler.findHelper('RuntimeFunctionType'); |
6324 builder.push(new HFunctionType(inputs, type, new TypeMask.exact(cls))); | 6324 builder.push(new HFunctionType(inputs, type, new TypeMask.exact(cls))); |
6325 } | 6325 } |
6326 | 6326 |
6327 void visitMalformedType(MalformedType type, SsaBuilder builder) { | 6327 void visitMalformedType(MalformedType type, SsaBuilder builder) { |
6328 visitDynamicType(builder.compiler.types.dynamicType, builder); | 6328 visitDynamicType(const DynamicType(), builder); |
6329 } | 6329 } |
6330 | 6330 |
6331 void visitStatementType(StatementType type, SsaBuilder builder) { | 6331 void visitStatementType(StatementType type, SsaBuilder builder) { |
6332 throw 'not implemented visitStatementType($type)'; | 6332 throw 'not implemented visitStatementType($type)'; |
6333 } | 6333 } |
6334 | 6334 |
6335 void visitGenericType(GenericType type, SsaBuilder builder) { | 6335 void visitGenericType(GenericType type, SsaBuilder builder) { |
6336 throw 'not implemented visitGenericType($type)'; | 6336 throw 'not implemented visitGenericType($type)'; |
6337 } | 6337 } |
6338 | 6338 |
(...skipping 16 matching lines...) Expand all Loading... |
6355 DartType unaliased = type.unalias(builder.compiler); | 6355 DartType unaliased = type.unalias(builder.compiler); |
6356 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6356 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
6357 unaliased.accept(this, builder); | 6357 unaliased.accept(this, builder); |
6358 } | 6358 } |
6359 | 6359 |
6360 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6360 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
6361 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); | 6361 ClassElement cls = builder.compiler.findHelper('DynamicRuntimeType'); |
6362 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); | 6362 builder.push(new HDynamicType(type, new TypeMask.exact(cls))); |
6363 } | 6363 } |
6364 } | 6364 } |
OLD | NEW |