OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 import '../common.dart'; | 5 import '../common.dart'; |
6 import '../core_types.dart'; | 6 import '../core_types.dart'; |
7 import '../elements/elements.dart' show ErroneousElement; | 7 import '../elements/elements.dart' show ErroneousElement; |
8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
9 import '../elements/resolution_types.dart' show MalformedType; | 9 import '../elements/resolution_types.dart' show MalformedType; |
10 import '../elements/types.dart'; | 10 import '../elements/types.dart'; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 CallStructure get callStructure => CallStructure.TWO_ARGS; | 82 CallStructure get callStructure => CallStructure.TWO_ARGS; |
83 | 83 |
84 void generateAdditionalArguments(SsaCodeGenerator codegen, | 84 void generateAdditionalArguments(SsaCodeGenerator codegen, |
85 HTypeConversion node, List<jsAst.Expression> arguments) { | 85 HTypeConversion node, List<jsAst.Expression> arguments) { |
86 assert(node.typeExpression.isTypeVariable); | 86 assert(node.typeExpression.isTypeVariable); |
87 codegen.use(node.typeRepresentation); | 87 codegen.use(node.typeRepresentation); |
88 arguments.add(codegen.pop()); | 88 arguments.add(codegen.pop()); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
| 92 class FunctionTypeRepresentationCheckedModeHelper extends CheckedModeHelper { |
| 93 const FunctionTypeRepresentationCheckedModeHelper(String name) : super(name); |
| 94 |
| 95 CallStructure get callStructure => CallStructure.TWO_ARGS; |
| 96 |
| 97 void generateAdditionalArguments(SsaCodeGenerator codegen, |
| 98 HTypeConversion node, List<jsAst.Expression> arguments) { |
| 99 assert(node.typeExpression.isFunctionType); |
| 100 codegen.use(node.typeRepresentation); |
| 101 arguments.add(codegen.pop()); |
| 102 } |
| 103 } |
| 104 |
92 class SubtypeCheckedModeHelper extends CheckedModeHelper { | 105 class SubtypeCheckedModeHelper extends CheckedModeHelper { |
93 const SubtypeCheckedModeHelper(String name) : super(name); | 106 const SubtypeCheckedModeHelper(String name) : super(name); |
94 | 107 |
95 CallStructure get callStructure => const CallStructure.unnamed(4); | 108 CallStructure get callStructure => const CallStructure.unnamed(4); |
96 | 109 |
97 void generateAdditionalArguments(SsaCodeGenerator codegen, | 110 void generateAdditionalArguments(SsaCodeGenerator codegen, |
98 HTypeConversion node, List<jsAst.Expression> arguments) { | 111 HTypeConversion node, List<jsAst.Expression> arguments) { |
| 112 // TODO(sra): Move these calls into the SSA graph so that the arguments can |
| 113 // be optimized, e,g, GVNed. |
99 InterfaceType type = node.typeExpression; | 114 InterfaceType type = node.typeExpression; |
100 ClassEntity element = type.element; | 115 ClassEntity element = type.element; |
101 jsAst.Name isField = codegen.backend.namer.operatorIs(element); | 116 jsAst.Name isField = codegen.backend.namer.operatorIs(element); |
102 arguments.add(js.quoteName(isField)); | 117 arguments.add(js.quoteName(isField)); |
103 codegen.use(node.typeRepresentation); | 118 codegen.use(node.typeRepresentation); |
104 arguments.add(codegen.pop()); | 119 arguments.add(codegen.pop()); |
105 jsAst.Name asField = codegen.backend.namer.substitutionName(element); | 120 jsAst.Name asField = codegen.backend.namer.substitutionName(element); |
106 arguments.add(js.quoteName(asField)); | 121 arguments.add(js.quoteName(asField)); |
107 } | 122 } |
108 } | 123 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 const PropertyCheckedModeHelper('listSuperTypeCast'), | 157 const PropertyCheckedModeHelper('listSuperTypeCast'), |
143 const PropertyCheckedModeHelper('listSuperTypeCheck'), | 158 const PropertyCheckedModeHelper('listSuperTypeCheck'), |
144 const PropertyCheckedModeHelper('interceptedTypeCast'), | 159 const PropertyCheckedModeHelper('interceptedTypeCast'), |
145 const PropertyCheckedModeHelper('interceptedTypeCheck'), | 160 const PropertyCheckedModeHelper('interceptedTypeCheck'), |
146 const SubtypeCheckedModeHelper('subtypeCast'), | 161 const SubtypeCheckedModeHelper('subtypeCast'), |
147 const SubtypeCheckedModeHelper('assertSubtype'), | 162 const SubtypeCheckedModeHelper('assertSubtype'), |
148 const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'), | 163 const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'), |
149 const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'), | 164 const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'), |
150 const PropertyCheckedModeHelper('propertyTypeCast'), | 165 const PropertyCheckedModeHelper('propertyTypeCast'), |
151 const PropertyCheckedModeHelper('propertyTypeCheck'), | 166 const PropertyCheckedModeHelper('propertyTypeCheck'), |
| 167 const FunctionTypeRepresentationCheckedModeHelper('functionTypeCast'), |
| 168 const FunctionTypeRepresentationCheckedModeHelper('functionTypeCheck'), |
152 ]; | 169 ]; |
153 | 170 |
154 // Checked mode helpers indexed by name. | 171 // Checked mode helpers indexed by name. |
155 static final Map<String, CheckedModeHelper> checkedModeHelperByName = | 172 static final Map<String, CheckedModeHelper> checkedModeHelperByName = |
156 new Map<String, CheckedModeHelper>.fromIterable(helpers, | 173 new Map<String, CheckedModeHelper>.fromIterable(helpers, |
157 key: (helper) => helper.name); | 174 key: (helper) => helper.name); |
158 | 175 |
159 /** | 176 /** |
160 * Returns the checked mode helper that will be needed to do a type check/type | 177 * Returns the checked mode helper that will be needed to do a type check/type |
161 * cast on [type] at runtime. Note that this method is being called both by | 178 * cast on [type] at runtime. Note that this method is being called both by |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 if (nativeCheckOnly) return null; | 222 if (nativeCheckOnly) return null; |
206 return 'voidTypeCheck'; | 223 return 'voidTypeCheck'; |
207 } | 224 } |
208 | 225 |
209 if (type.isTypeVariable) { | 226 if (type.isTypeVariable) { |
210 return typeCast | 227 return typeCast |
211 ? 'subtypeOfRuntimeTypeCast' | 228 ? 'subtypeOfRuntimeTypeCast' |
212 : 'assertSubtypeOfRuntimeType'; | 229 : 'assertSubtypeOfRuntimeType'; |
213 } | 230 } |
214 | 231 |
215 if (type.isFunctionType) return null; | 232 if (type.isFunctionType) { |
| 233 return typeCast ? 'functionTypeCast' : 'functionTypeCheck'; |
| 234 } |
216 | 235 |
217 assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, | 236 assert(invariant(NO_LOCATION_SPANNABLE, type.isInterfaceType, |
218 message: "Unexpected type: $type")); | 237 message: "Unexpected type: $type")); |
219 InterfaceType interfaceType = type; | 238 InterfaceType interfaceType = type; |
220 ClassEntity element = interfaceType.element; | 239 ClassEntity element = interfaceType.element; |
221 bool nativeCheck = true; | 240 bool nativeCheck = true; |
222 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 241 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
223 // interceptor. The interceptor should be an argument to HTypeConversion so | 242 // interceptor. The interceptor should be an argument to HTypeConversion so |
224 // that it can be optimized by standard interceptor optimizations. | 243 // that it can be optimized by standard interceptor optimizations. |
225 // nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); | 244 // nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 304 |
286 if (nativeCheck) { | 305 if (nativeCheck) { |
287 // TODO(karlklose): can we get rid of this branch when we use | 306 // TODO(karlklose): can we get rid of this branch when we use |
288 // interceptors? | 307 // interceptors? |
289 return 'intercepted$suffix'; | 308 return 'intercepted$suffix'; |
290 } else { | 309 } else { |
291 return 'property$suffix'; | 310 return 'property$suffix'; |
292 } | 311 } |
293 } | 312 } |
294 } | 313 } |
OLD | NEW |