| 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 |