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