| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 class TypeTestEmitter extends CodeEmitterHelper { | 7 class TypeTestEmitter extends CodeEmitterHelper { |
| 8 static const int MAX_FUNCTION_TYPE_PREDICATES = 10; | 8 static const int MAX_FUNCTION_TYPE_PREDICATES = 10; |
| 9 | 9 |
| 10 /** | 10 /** |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 /** | 248 /** |
| 249 * Generates function type checks on [method] with type [methodType] against | 249 * Generates function type checks on [method] with type [methodType] against |
| 250 * the function type checks in [functionTypeChecks]. | 250 * the function type checks in [functionTypeChecks]. |
| 251 */ | 251 */ |
| 252 void generateFunctionTypeTests( | 252 void generateFunctionTypeTests( |
| 253 Element method, | 253 Element method, |
| 254 FunctionType methodType, | 254 FunctionType methodType, |
| 255 Map<FunctionType, bool> functionTypeChecks, | 255 Map<FunctionType, bool> functionTypeChecks, |
| 256 FunctionTypeSignatureEmitter emitFunctionTypeSignature, | 256 FunctionTypeSignatureEmitter emitFunctionTypeSignature, |
| 257 FunctionTypeTestEmitter emitIsFunctionTypeTest) { | 257 FunctionTypeTestEmitter emitIsFunctionTypeTest) { |
| 258 bool hasDynamicFunctionTypeCheck = false; | |
| 259 int neededPredicates = 0; | |
| 260 functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) { | 258 functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) { |
| 261 if (!knownSubtype) { | 259 if (!knownSubtype) { |
| 262 registerDynamicFunctionTypeCheck(functionType); | 260 registerDynamicFunctionTypeCheck(functionType); |
| 263 hasDynamicFunctionTypeCheck = true; | |
| 264 } else if (!backend.rti.isSimpleFunctionType(functionType)) { | |
| 265 // Simple function types are always checked using predicates and should | |
| 266 // not provoke generation of signatures. | |
| 267 neededPredicates++; | |
| 268 } | 261 } |
| 269 }); | 262 }); |
| 270 bool alwaysUseSignature = false; | 263 emitFunctionTypeSignature(method, methodType); |
| 271 if (hasDynamicFunctionTypeCheck || | |
| 272 neededPredicates > MAX_FUNCTION_TYPE_PREDICATES) { | |
| 273 emitFunctionTypeSignature(method, methodType); | |
| 274 alwaysUseSignature = true; | |
| 275 } | |
| 276 functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) { | 264 functionTypeChecks.forEach((FunctionType functionType, bool knownSubtype) { |
| 277 if (knownSubtype) { | 265 if (knownSubtype) { |
| 278 if (backend.rti.isSimpleFunctionType(functionType)) { | 266 if (backend.rti.isSimpleFunctionType(functionType)) { |
| 279 // Simple function types are always checked using predicates. | 267 // Simple function types are always checked using predicates. |
| 280 emitIsFunctionTypeTest(functionType); | 268 emitIsFunctionTypeTest(functionType); |
| 281 } else if (alwaysUseSignature) { | 269 } else { |
| 282 registerDynamicFunctionTypeCheck(functionType); | 270 registerDynamicFunctionTypeCheck(functionType); |
| 283 } else { | |
| 284 emitIsFunctionTypeTest(functionType); | |
| 285 } | 271 } |
| 286 } | 272 } |
| 287 }); | 273 }); |
| 288 } | 274 } |
| 289 | 275 |
| 290 void registerDynamicFunctionTypeCheck(FunctionType functionType) { | 276 void registerDynamicFunctionTypeCheck(FunctionType functionType) { |
| 291 ClassElement classElement = Types.getClassContext(functionType); | 277 ClassElement classElement = Types.getClassContext(functionType); |
| 292 if (classElement != null) { | 278 if (classElement != null) { |
| 293 checkedGenericFunctionTypes.putIfAbsent(classElement, | 279 checkedGenericFunctionTypes.putIfAbsent(classElement, |
| 294 () => new Set<FunctionType>()).add(functionType); | 280 () => new Set<FunctionType>()).add(functionType); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 checkedFunctionTypes = new Set<FunctionType>(); | 399 checkedFunctionTypes = new Set<FunctionType>(); |
| 414 compiler.codegenWorld.isChecks.forEach((DartType t) { | 400 compiler.codegenWorld.isChecks.forEach((DartType t) { |
| 415 if (t is InterfaceType) { | 401 if (t is InterfaceType) { |
| 416 checkedClasses.add(t.element); | 402 checkedClasses.add(t.element); |
| 417 } else if (t is FunctionType) { | 403 } else if (t is FunctionType) { |
| 418 checkedFunctionTypes.add(t); | 404 checkedFunctionTypes.add(t); |
| 419 } | 405 } |
| 420 }); | 406 }); |
| 421 } | 407 } |
| 422 } | 408 } |
| OLD | NEW |