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 '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
10 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator; | 10 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator; |
11 import '../../js/js.dart' as js; | 11 import '../../js/js.dart' as js; |
12 import '../../elements/elements.dart'; | 12 import '../../elements/elements.dart'; |
13 import '../../io/source_information.dart' show SourceInformation; | 13 import '../../io/source_information.dart' show SourceInformation; |
14 import '../../util/maplet.dart'; | 14 import '../../util/maplet.dart'; |
15 import '../../constants/values.dart'; | 15 import '../../constants/values.dart'; |
16 import '../../dart2jslib.dart'; | 16 import '../../dart2jslib.dart'; |
17 import '../../dart_types.dart'; | 17 import '../../dart_types.dart'; |
| 18 import '../../closure.dart' show ClosureClassElement; |
18 | 19 |
19 class CodegenBailout { | 20 class CodegenBailout { |
20 final tree_ir.Node node; | 21 final tree_ir.Node node; |
21 final String reason; | 22 final String reason; |
22 CodegenBailout(this.node, this.reason); | 23 CodegenBailout(this.node, this.reason); |
23 String get message { | 24 String get message { |
24 return 'bailout${node != null ? " on $node" : ""}: $reason'; | 25 return 'bailout${node != null ? " on $node" : ""}: $reason'; |
25 } | 26 } |
26 } | 27 } |
27 | 28 |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 ? new js.ArrayInitializer(typeArguments) | 379 ? new js.ArrayInitializer(typeArguments) |
379 : new js.LiteralNull(); | 380 : new js.LiteralNull(); |
380 | 381 |
381 js.Expression asT = glue.hasStrictSubtype(clazz) | 382 js.Expression asT = glue.hasStrictSubtype(clazz) |
382 ? js.string(glue.getTypeSubstitutionTag(clazz)) | 383 ? js.string(glue.getTypeSubstitutionTag(clazz)) |
383 : new js.LiteralNull(); | 384 : new js.LiteralNull(); |
384 | 385 |
385 return buildStaticHelperInvocation( | 386 return buildStaticHelperInvocation( |
386 function, | 387 function, |
387 <js.Expression>[value, isT, typeArgumentArray, asT]); | 388 <js.Expression>[value, isT, typeArgumentArray, asT]); |
388 } else if (type is TypeVariableType) { | 389 } else if (type is TypeVariableType || type is FunctionType) { |
389 glue.registerIsCheck(type, registry); | 390 glue.registerIsCheck(type, registry); |
390 | 391 |
391 Element function = node.isTypeTest | 392 Element function = node.isTypeTest |
392 ? glue.getCheckSubtypeOfRuntimeType() | 393 ? glue.getCheckSubtypeOfRuntimeType() |
393 : glue.getSubtypeOfRuntimeTypeCast(); | 394 : glue.getSubtypeOfRuntimeTypeCast(); |
394 | 395 |
395 // The only type argument is the type held in the type variable. | 396 // The only type argument is the type held in the type variable. |
396 js.Expression typeValue = typeArguments.single; | 397 js.Expression typeValue = typeArguments.single; |
397 | 398 |
398 return buildStaticHelperInvocation( | 399 return buildStaticHelperInvocation( |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 accumulator.add(new js.Try(tryBlock, catchPart, null)); | 569 accumulator.add(new js.Try(tryBlock, catchPart, null)); |
569 } | 570 } |
570 | 571 |
571 @override | 572 @override |
572 js.Expression visitCreateBox(tree_ir.CreateBox node) { | 573 js.Expression visitCreateBox(tree_ir.CreateBox node) { |
573 return new js.ObjectInitializer(const <js.Property>[]); | 574 return new js.ObjectInitializer(const <js.Property>[]); |
574 } | 575 } |
575 | 576 |
576 @override | 577 @override |
577 js.Expression visitCreateInstance(tree_ir.CreateInstance node) { | 578 js.Expression visitCreateInstance(tree_ir.CreateInstance node) { |
578 ClassElement cls = node.classElement; | 579 ClassElement classElement = node.classElement; |
579 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must | 580 // TODO(asgerf): To allow inlining of InvokeConstructor, CreateInstance must |
580 // carry a DartType so we can register the instantiated type | 581 // carry a DartType so we can register the instantiated type |
581 // with its type arguments. Otherwise dataflow analysis is | 582 // with its type arguments. Otherwise dataflow analysis is |
582 // needed to reconstruct the instantiated type. | 583 // needed to reconstruct the instantiated type. |
583 registry.registerInstantiatedClass(cls); | 584 registry.registerInstantiatedClass(classElement); |
| 585 if (classElement is ClosureClassElement) { |
| 586 registry.registerInstantiatedClosure(classElement.methodElement); |
| 587 } |
584 js.Expression instance = new js.New( | 588 js.Expression instance = new js.New( |
585 glue.constructorAccess(cls), | 589 glue.constructorAccess(classElement), |
586 visitExpressionList(node.arguments)); | 590 visitExpressionList(node.arguments)); |
587 | 591 |
588 List<tree_ir.Expression> typeInformation = node.typeInformation; | 592 List<tree_ir.Expression> typeInformation = node.typeInformation; |
589 assert(typeInformation.isEmpty || | 593 assert(typeInformation.isEmpty || |
590 typeInformation.length == cls.typeVariables.length); | 594 typeInformation.length == classElement.typeVariables.length); |
591 if (typeInformation.isNotEmpty) { | 595 if (typeInformation.isNotEmpty) { |
592 FunctionElement helper = glue.getAddRuntimeTypeInformation(); | 596 FunctionElement helper = glue.getAddRuntimeTypeInformation(); |
593 js.Expression typeArguments = new js.ArrayInitializer( | 597 js.Expression typeArguments = new js.ArrayInitializer( |
594 visitExpressionList(typeInformation)); | 598 visitExpressionList(typeInformation)); |
595 return buildStaticHelperInvocation(helper, | 599 return buildStaticHelperInvocation(helper, |
596 <js.Expression>[instance, typeArguments]); | 600 <js.Expression>[instance, typeArguments]); |
597 } else { | 601 } else { |
598 return instance; | 602 return instance; |
599 } | 603 } |
600 } | 604 } |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 return new js.Prefix('!', args[0]); | 736 return new js.Prefix('!', args[0]); |
733 } | 737 } |
734 } | 738 } |
735 | 739 |
736 visitFunctionExpression(tree_ir.FunctionExpression node) { | 740 visitFunctionExpression(tree_ir.FunctionExpression node) { |
737 // FunctionExpressions are currently unused. | 741 // FunctionExpressions are currently unused. |
738 // We might need them if we want to emit raw JS nested functions. | 742 // We might need them if we want to emit raw JS nested functions. |
739 throw 'FunctionExpressions should not be used'; | 743 throw 'FunctionExpressions should not be used'; |
740 } | 744 } |
741 } | 745 } |
OLD | NEW |