Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library code_generator; | 5 library code_generator; |
| 6 | 6 |
| 7 import 'glue.dart'; | 7 import 'glue.dart'; |
| 8 | 8 |
| 9 import '../../closure.dart' show | 9 import '../../closure.dart' show |
| 10 ClosureClassElement; | 10 ClosureClassElement; |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 | 398 |
| 399 @override | 399 @override |
| 400 js.Expression visitThis(tree_ir.This node) { | 400 js.Expression visitThis(tree_ir.This node) { |
| 401 return new js.This(); | 401 return new js.This(); |
| 402 } | 402 } |
| 403 | 403 |
| 404 /// Ensure that 'instanceof' checks may be performed against [class_]. | 404 /// Ensure that 'instanceof' checks may be performed against [class_]. |
| 405 /// | 405 /// |
| 406 /// Even if the class is never instantiated, a JS constructor must be emitted | 406 /// Even if the class is never instantiated, a JS constructor must be emitted |
| 407 /// so the 'instanceof' expression does not throw an exception at runtime. | 407 /// so the 'instanceof' expression does not throw an exception at runtime. |
| 408 /// | 408 bool tryRegisterInstanceofCheck(ClassElement class_) { |
| 409 /// It does not help to ask the class world if the class is instantiated, | 409 if (glue.classWorld.isInstantiated(class_)) { |
| 410 /// because it could still get tree-shaken if it is unused after optimization. | 410 // Ensure the class remains instantiated during backend tree-shaking. |
| 411 void registerInstanceofCheck(ClassElement class_) { | 411 // TODO(asgerf): We could have a more precise hook to inform the emitter |
| 412 // TODO(asgerf): This is the only hook we have to ensure the JS constructor | 412 // that the JS constructor function is needed, without the class being |
| 413 // gets emitted, but it is very imprecise. We should do better. | 413 // instantiated. |
| 414 registry.registerInstantiatedClass(class_); | 414 registry.registerInstantiatedClass(class_); |
| 415 return true; | |
| 416 } | |
| 417 // Will throw if the JS constructor is not emitted, so do not allow the | |
| 418 // instanceof check. This should only happen when certain optimization | |
| 419 // passes are disabled, as the type check itself is trivial. | |
| 420 return false; | |
| 415 } | 421 } |
| 416 | 422 |
| 417 @override | 423 @override |
| 418 js.Expression visitTypeOperator(tree_ir.TypeOperator node) { | 424 js.Expression visitTypeOperator(tree_ir.TypeOperator node) { |
| 419 js.Expression value = visitExpression(node.value); | 425 js.Expression value = visitExpression(node.value); |
| 420 List<js.Expression> typeArguments = visitExpressionList(node.typeArguments); | 426 List<js.Expression> typeArguments = visitExpressionList(node.typeArguments); |
| 421 DartType type = node.type; | 427 DartType type = node.type; |
| 422 if (type is InterfaceType) { | 428 if (type is InterfaceType) { |
| 423 registry.registerTypeUse(new TypeUse.isCheck(type)); | 429 registry.registerTypeUse(new TypeUse.isCheck(type)); |
| 424 ClassElement clazz = type.element; | 430 ClassElement clazz = type.element; |
| 425 | 431 |
| 426 if (glue.isStringClass(clazz)) { | 432 if (glue.isStringClass(clazz)) { |
| 427 if (node.isTypeTest) { | 433 if (node.isTypeTest) { |
| 428 return js.js(r'typeof # === "string"', <js.Expression>[value]); | 434 return js.js(r'typeof # === "string"', <js.Expression>[value]); |
| 429 } | 435 } |
| 430 // TODO(sra): Implement fast cast via calling 'stringTypeCast'. | 436 // TODO(sra): Implement fast cast via calling 'stringTypeCast'. |
| 431 } else if (glue.isBoolClass(clazz)) { | 437 } else if (glue.isBoolClass(clazz)) { |
| 432 if (node.isTypeTest) { | 438 if (node.isTypeTest) { |
| 433 return js.js(r'typeof # === "boolean"', <js.Expression>[value]); | 439 return js.js(r'typeof # === "boolean"', <js.Expression>[value]); |
| 434 } | 440 } |
| 435 // TODO(sra): Implement fast cast via calling 'boolTypeCast'. | 441 // TODO(sra): Implement fast cast via calling 'boolTypeCast'. |
| 436 } else if (node.isTypeTest && | 442 } else if (node.isTypeTest && |
| 437 node.typeArguments.isEmpty && | 443 node.typeArguments.isEmpty && |
| 438 glue.mayGenerateInstanceofCheck(type)) { | 444 glue.mayGenerateInstanceofCheck(type) && |
| 439 registerInstanceofCheck(clazz); | 445 tryRegisterInstanceofCheck(clazz)) { |
|
Siggi Cherem (dart-lang)
2016/01/16 00:50:40
what would the code below generate when this is fa
asgerf
2016/01/16 01:05:13
A call to a static checkSubtype method. That metho
| |
| 440 return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]); | 446 return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]); |
| 441 } | 447 } |
| 442 | 448 |
| 443 // The helper we use needs the JSArray class to exist, but for some | 449 // The helper we use needs the JSArray class to exist, but for some |
| 444 // reason the helper does not cause this dependency to be registered. | 450 // reason the helper does not cause this dependency to be registered. |
| 445 // TODO(asgerf): Most programs need List anyway, but we should fix this. | 451 // TODO(asgerf): Most programs need List anyway, but we should fix this. |
| 446 registry.registerInstantiatedClass(glue.listClass); | 452 registry.registerInstantiatedClass(glue.listClass); |
| 447 | 453 |
| 448 // We use one of the two helpers: | 454 // We use one of the two helpers: |
| 449 // | 455 // |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1225 void registerDefaultParameterValues(ExecutableElement element) { | 1231 void registerDefaultParameterValues(ExecutableElement element) { |
| 1226 if (element is! FunctionElement) return; | 1232 if (element is! FunctionElement) return; |
| 1227 FunctionElement function = element; | 1233 FunctionElement function = element; |
| 1228 if (function.isStatic) return; // Defaults are inlined at call sites. | 1234 if (function.isStatic) return; // Defaults are inlined at call sites. |
| 1229 function.functionSignature.forEachOptionalParameter((param) { | 1235 function.functionSignature.forEachOptionalParameter((param) { |
| 1230 ConstantValue constant = glue.getDefaultParameterValue(param); | 1236 ConstantValue constant = glue.getDefaultParameterValue(param); |
| 1231 registry.registerCompileTimeConstant(constant); | 1237 registry.registerCompileTimeConstant(constant); |
| 1232 }); | 1238 }); |
| 1233 } | 1239 } |
| 1234 } | 1240 } |
| OLD | NEW |