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 |