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 '../common_elements.dart'; | 6 import '../common_elements.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'; |
11 import '../js/js.dart' as jsAst; | 11 import '../js/js.dart' as jsAst; |
12 import '../js/js.dart' show js; | 12 import '../js/js.dart' show js; |
13 import '../ssa/codegen.dart' show SsaCodeGenerator; | 13 import '../ssa/codegen.dart' show SsaCodeGenerator; |
14 import '../ssa/nodes.dart' show HTypeConversion; | 14 import '../ssa/nodes.dart' show HTypeConversion; |
15 import '../universe/call_structure.dart' show CallStructure; | 15 import '../universe/call_structure.dart' show CallStructure; |
16 import '../universe/use.dart' show StaticUse; | 16 import '../universe/use.dart' show StaticUse; |
17 import 'backend_helpers.dart'; | |
18 import 'namer.dart' show Namer; | 17 import 'namer.dart' show Namer; |
19 | 18 |
20 class CheckedModeHelper { | 19 class CheckedModeHelper { |
21 final String name; | 20 final String name; |
22 | 21 |
23 const CheckedModeHelper(String this.name); | 22 const CheckedModeHelper(String this.name); |
24 | 23 |
25 StaticUse getStaticUse(BackendHelpers helpers) { | 24 StaticUse getStaticUse(CommonElements commonElements) { |
26 // TODO(johnniwinther): Refactor this to avoid looking up directly in the | 25 // TODO(johnniwinther): Refactor this to avoid looking up directly in the |
27 // js helper library but instead access helpers directly on backend helpers. | 26 // js helper library but instead access commonElements. |
28 return new StaticUse.staticInvoke( | 27 return new StaticUse.staticInvoke( |
29 helpers.findHelperFunction(name), callStructure); | 28 commonElements.findHelperFunction(name), callStructure); |
30 } | 29 } |
31 | 30 |
32 CallStructure get callStructure => CallStructure.ONE_ARG; | 31 CallStructure get callStructure => CallStructure.ONE_ARG; |
33 | 32 |
34 void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer, | 33 void generateAdditionalArguments(SsaCodeGenerator codegen, Namer namer, |
35 HTypeConversion node, List<jsAst.Expression> arguments) { | 34 HTypeConversion node, List<jsAst.Expression> arguments) { |
36 // No additional arguments needed. | 35 // No additional arguments needed. |
37 } | 36 } |
38 } | 37 } |
39 | 38 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 arguments.add(js.quoteName(isField)); | 104 arguments.add(js.quoteName(isField)); |
106 codegen.use(node.typeRepresentation); | 105 codegen.use(node.typeRepresentation); |
107 arguments.add(codegen.pop()); | 106 arguments.add(codegen.pop()); |
108 jsAst.Name asField = namer.substitutionName(element); | 107 jsAst.Name asField = namer.substitutionName(element); |
109 arguments.add(js.quoteName(asField)); | 108 arguments.add(js.quoteName(asField)); |
110 } | 109 } |
111 } | 110 } |
112 | 111 |
113 class CheckedModeHelpers { | 112 class CheckedModeHelpers { |
114 final CommonElements _commonElements; | 113 final CommonElements _commonElements; |
115 final BackendHelpers _helpers; | |
116 | 114 |
117 CheckedModeHelpers(this._commonElements, this._helpers); | 115 CheckedModeHelpers(this._commonElements); |
118 | 116 |
119 /// All the checked mode helpers. | 117 /// All the checked mode helpers. |
120 static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[ | 118 static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[ |
121 const MalformedCheckedModeHelper('checkMalformedType'), | 119 const MalformedCheckedModeHelper('checkMalformedType'), |
122 const CheckedModeHelper('voidTypeCheck'), | 120 const CheckedModeHelper('voidTypeCheck'), |
123 const CheckedModeHelper('stringTypeCast'), | 121 const CheckedModeHelper('stringTypeCast'), |
124 const CheckedModeHelper('stringTypeCheck'), | 122 const CheckedModeHelper('stringTypeCheck'), |
125 const CheckedModeHelper('doubleTypeCast'), | 123 const CheckedModeHelper('doubleTypeCast'), |
126 const CheckedModeHelper('doubleTypeCheck'), | 124 const CheckedModeHelper('doubleTypeCheck'), |
127 const CheckedModeHelper('numTypeCast'), | 125 const CheckedModeHelper('numTypeCast'), |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 message: "Unexpected type: $type")); | 223 message: "Unexpected type: $type")); |
226 InterfaceType interfaceType = type; | 224 InterfaceType interfaceType = type; |
227 ClassEntity element = interfaceType.element; | 225 ClassEntity element = interfaceType.element; |
228 bool nativeCheck = true; | 226 bool nativeCheck = true; |
229 // TODO(13955), TODO(9731). The test for non-primitive types should use an | 227 // TODO(13955), TODO(9731). The test for non-primitive types should use an |
230 // interceptor. The interceptor should be an argument to HTypeConversion so | 228 // interceptor. The interceptor should be an argument to HTypeConversion so |
231 // that it can be optimized by standard interceptor optimizations. | 229 // that it can be optimized by standard interceptor optimizations. |
232 // nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); | 230 // nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element); |
233 | 231 |
234 var suffix = typeCast ? 'TypeCast' : 'TypeCheck'; | 232 var suffix = typeCast ? 'TypeCast' : 'TypeCheck'; |
235 if (element == _helpers.jsStringClass || | 233 if (element == _commonElements.jsStringClass || |
236 element == _commonElements.stringClass) { | 234 element == _commonElements.stringClass) { |
237 if (nativeCheckOnly) return null; | 235 if (nativeCheckOnly) return null; |
238 return 'string$suffix'; | 236 return 'string$suffix'; |
239 } | 237 } |
240 | 238 |
241 if (element == _helpers.jsDoubleClass || | 239 if (element == _commonElements.jsDoubleClass || |
242 element == _commonElements.doubleClass) { | 240 element == _commonElements.doubleClass) { |
243 if (nativeCheckOnly) return null; | 241 if (nativeCheckOnly) return null; |
244 return 'double$suffix'; | 242 return 'double$suffix'; |
245 } | 243 } |
246 | 244 |
247 if (element == _helpers.jsNumberClass || | 245 if (element == _commonElements.jsNumberClass || |
248 element == _commonElements.numClass) { | 246 element == _commonElements.numClass) { |
249 if (nativeCheckOnly) return null; | 247 if (nativeCheckOnly) return null; |
250 return 'num$suffix'; | 248 return 'num$suffix'; |
251 } | 249 } |
252 | 250 |
253 if (element == _helpers.jsBoolClass || | 251 if (element == _commonElements.jsBoolClass || |
254 element == _commonElements.boolClass) { | 252 element == _commonElements.boolClass) { |
255 if (nativeCheckOnly) return null; | 253 if (nativeCheckOnly) return null; |
256 return 'bool$suffix'; | 254 return 'bool$suffix'; |
257 } | 255 } |
258 | 256 |
259 if (element == _helpers.jsIntClass || | 257 if (element == _commonElements.jsIntClass || |
260 element == _commonElements.intClass || | 258 element == _commonElements.intClass || |
261 element == _helpers.jsUInt32Class || | 259 element == _commonElements.jsUInt32Class || |
262 element == _helpers.jsUInt31Class || | 260 element == _commonElements.jsUInt31Class || |
263 element == _helpers.jsPositiveIntClass) { | 261 element == _commonElements.jsPositiveIntClass) { |
264 if (nativeCheckOnly) return null; | 262 if (nativeCheckOnly) return null; |
265 return 'int$suffix'; | 263 return 'int$suffix'; |
266 } | 264 } |
267 | 265 |
268 if (_commonElements.isNumberOrStringSupertype(element)) { | 266 if (_commonElements.isNumberOrStringSupertype(element)) { |
269 return nativeCheck | 267 return nativeCheck |
270 ? 'numberOrStringSuperNative$suffix' | 268 ? 'numberOrStringSuperNative$suffix' |
271 : 'numberOrStringSuper$suffix'; | 269 : 'numberOrStringSuper$suffix'; |
272 } | 270 } |
273 | 271 |
274 if (_commonElements.isStringOnlySupertype(element)) { | 272 if (_commonElements.isStringOnlySupertype(element)) { |
275 return nativeCheck ? 'stringSuperNative$suffix' : 'stringSuper$suffix'; | 273 return nativeCheck ? 'stringSuperNative$suffix' : 'stringSuper$suffix'; |
276 } | 274 } |
277 | 275 |
278 if ((element == _commonElements.listClass || | 276 if ((element == _commonElements.listClass || |
279 element == _helpers.jsArrayClass) && | 277 element == _commonElements.jsArrayClass) && |
280 type.treatAsRaw) { | 278 type.treatAsRaw) { |
281 if (nativeCheckOnly) return null; | 279 if (nativeCheckOnly) return null; |
282 return 'list$suffix'; | 280 return 'list$suffix'; |
283 } | 281 } |
284 | 282 |
285 if (_commonElements.isListSupertype(element)) { | 283 if (_commonElements.isListSupertype(element)) { |
286 return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix'; | 284 return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix'; |
287 } | 285 } |
288 | 286 |
289 if (type.isInterfaceType && !type.treatAsRaw) { | 287 if (type.isInterfaceType && !type.treatAsRaw) { |
290 return typeCast ? 'subtypeCast' : 'assertSubtype'; | 288 return typeCast ? 'subtypeCast' : 'assertSubtype'; |
291 } | 289 } |
292 | 290 |
293 if (nativeCheck) { | 291 if (nativeCheck) { |
294 // TODO(karlklose): can we get rid of this branch when we use | 292 // TODO(karlklose): can we get rid of this branch when we use |
295 // interceptors? | 293 // interceptors? |
296 return 'intercepted$suffix'; | 294 return 'intercepted$suffix'; |
297 } else { | 295 } else { |
298 return 'property$suffix'; | 296 return 'property$suffix'; |
299 } | 297 } |
300 } | 298 } |
301 } | 299 } |
OLD | NEW |