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 ClosureClassElement; | 9 import '../../closure.dart' show ClosureClassElement; |
10 import '../../common/codegen.dart' show CodegenRegistry; | 10 import '../../common/codegen.dart' show CodegenRegistry; |
11 import '../../constants/values.dart'; | 11 import '../../constants/values.dart'; |
12 import '../../dart_types.dart'; | 12 import '../../dart_types.dart'; |
13 import '../../diagnostics/invariant.dart' show invariant; | 13 import '../../diagnostics/invariant.dart' show invariant; |
14 import '../../diagnostics/spannable.dart' show CURRENT_ELEMENT_SPANNABLE; | 14 import '../../diagnostics/spannable.dart' show CURRENT_ELEMENT_SPANNABLE; |
15 import '../../elements/elements.dart'; | 15 import '../../elements/elements.dart'; |
16 import '../../io/source_information.dart' show SourceInformation; | 16 import '../../io/source_information.dart' show SourceInformation; |
17 import '../../js/js.dart' as js; | 17 import '../../js/js.dart' as js; |
18 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 18 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
19 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator, BuiltinMethod; | 19 import '../../tree_ir/tree_ir_nodes.dart' show BuiltinOperator, BuiltinMethod; |
20 import '../../types/types.dart' show TypeMask; | 20 import '../../types/types.dart' show TypeMask; |
| 21 import '../../universe/selector.dart' show |
| 22 Selector; |
21 import '../../universe/universe.dart' show | 23 import '../../universe/universe.dart' show |
22 Selector, | |
23 UniverseSelector; | 24 UniverseSelector; |
24 import '../../util/maplet.dart'; | 25 import '../../util/maplet.dart'; |
25 | 26 |
26 class CodegenBailout { | 27 class CodegenBailout { |
27 final tree_ir.Node node; | 28 final tree_ir.Node node; |
28 final String reason; | 29 final String reason; |
29 CodegenBailout(this.node, this.reason); | 30 CodegenBailout(this.node, this.reason); |
30 String get message { | 31 String get message { |
31 return 'bailout${node != null ? " on $node" : ""}: $reason'; | 32 return 'bailout${node != null ? " on $node" : ""}: $reason'; |
32 } | 33 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 123 |
123 // We cannot declare a variable more than once. | 124 // We cannot declare a variable more than once. |
124 if (!declaredVariables.add(use.name)) break pullFromForLoop; | 125 if (!declaredVariables.add(use.name)) break pullFromForLoop; |
125 | 126 |
126 js.VariableInitialization jsVariable = new js.VariableInitialization( | 127 js.VariableInitialization jsVariable = new js.VariableInitialization( |
127 new js.VariableDeclaration(use.name), | 128 new js.VariableDeclaration(use.name), |
128 assign.value); | 129 assign.value); |
129 jsVariables.add(jsVariable); | 130 jsVariables.add(jsVariable); |
130 | 131 |
131 // Remove the initializer from the for loop. | 132 // Remove the initializer from the for loop. |
132 accumulator[accumulatorIndex] = | 133 accumulator[accumulatorIndex] = |
133 new js.For(null, forLoop.condition, forLoop.update, forLoop.body); | 134 new js.For(null, forLoop.condition, forLoop.update, forLoop.body); |
134 } | 135 } |
135 | 136 |
136 // Discard the statements that were pulled in the initializer. | 137 // Discard the statements that were pulled in the initializer. |
137 if (accumulatorIndex > 0) { | 138 if (accumulatorIndex > 0) { |
138 accumulator = accumulator.sublist(accumulatorIndex); | 139 accumulator = accumulator.sublist(accumulatorIndex); |
139 } | 140 } |
140 | 141 |
141 // Declare remaining variables. | 142 // Declare remaining variables. |
142 for (tree_ir.Variable variable in variableNames.keys) { | 143 for (tree_ir.Variable variable in variableNames.keys) { |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 fallthrough.push(node); | 566 fallthrough.push(node); |
566 js.Statement body = buildBodyStatement(node.body); | 567 js.Statement body = buildBodyStatement(node.body); |
567 fallthrough.pop(); | 568 fallthrough.pop(); |
568 shortContinue.pop(); | 569 shortContinue.pop(); |
569 shortBreak.pop(); | 570 shortBreak.pop(); |
570 js.Statement loopNode; | 571 js.Statement loopNode; |
571 if (node.updates.isEmpty) { | 572 if (node.updates.isEmpty) { |
572 loopNode = new js.While(condition, body); | 573 loopNode = new js.While(condition, body); |
573 } else { // Compile as a for loop. | 574 } else { // Compile as a for loop. |
574 js.Expression init; | 575 js.Expression init; |
575 if (accumulator.isNotEmpty && | 576 if (accumulator.isNotEmpty && |
576 accumulator.last is js.ExpressionStatement) { | 577 accumulator.last is js.ExpressionStatement) { |
577 // Take the preceding expression from the accumulator and use | 578 // Take the preceding expression from the accumulator and use |
578 // it as the initializer expression. | 579 // it as the initializer expression. |
579 js.ExpressionStatement initStmt = accumulator.removeLast(); | 580 js.ExpressionStatement initStmt = accumulator.removeLast(); |
580 init = initStmt.expression; | 581 init = initStmt.expression; |
581 } | 582 } |
582 js.Expression update = makeSequence(node.updates); | 583 js.Expression update = makeSequence(node.updates); |
583 loopNode = new js.For(init, condition, update, body); | 584 loopNode = new js.For(init, condition, update, body); |
584 } | 585 } |
585 accumulator.add(insertLabel(node.label, loopNode)); | 586 accumulator.add(insertLabel(node.label, loopNode)); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 case BuiltinOperator.IsNotNumber: | 884 case BuiltinOperator.IsNotNumber: |
884 return js.js('typeof # !== "number"', args); | 885 return js.js('typeof # !== "number"', args); |
885 case BuiltinOperator.IsFloor: | 886 case BuiltinOperator.IsFloor: |
886 return js.js('Math.floor(#) === #', args); | 887 return js.js('Math.floor(#) === #', args); |
887 case BuiltinOperator.IsNumberAndFloor: | 888 case BuiltinOperator.IsNumberAndFloor: |
888 return js.js('typeof # === "number" && Math.floor(#) === #', args); | 889 return js.js('typeof # === "number" && Math.floor(#) === #', args); |
889 } | 890 } |
890 } | 891 } |
891 | 892 |
892 /// The JS name of a built-in method. | 893 /// The JS name of a built-in method. |
893 static final Map<BuiltinMethod, String> builtinMethodName = | 894 static final Map<BuiltinMethod, String> builtinMethodName = |
894 const <BuiltinMethod, String>{ | 895 const <BuiltinMethod, String>{ |
895 BuiltinMethod.Push: 'push', | 896 BuiltinMethod.Push: 'push', |
896 BuiltinMethod.Pop: 'pop', | 897 BuiltinMethod.Pop: 'pop', |
897 }; | 898 }; |
898 | 899 |
899 @override | 900 @override |
900 js.Expression visitApplyBuiltinMethod(tree_ir.ApplyBuiltinMethod node) { | 901 js.Expression visitApplyBuiltinMethod(tree_ir.ApplyBuiltinMethod node) { |
901 String name = builtinMethodName[node.method]; | 902 String name = builtinMethodName[node.method]; |
902 js.Expression receiver = visitExpression(node.receiver); | 903 js.Expression receiver = visitExpression(node.receiver); |
903 List<js.Expression> args = visitExpressionList(node.arguments); | 904 List<js.Expression> args = visitExpressionList(node.arguments); |
904 return js.js('#.#(#)', [receiver, name, args]); | 905 return js.js('#.#(#)', [receiver, name, args]); |
905 } | 906 } |
906 | 907 |
907 @override | 908 @override |
908 js.Expression visitAwait(tree_ir.Await node) { | 909 js.Expression visitAwait(tree_ir.Await node) { |
909 return new js.Await(visitExpression(node.input)); | 910 return new js.Await(visitExpression(node.input)); |
910 } | 911 } |
911 | 912 |
912 visitFunctionExpression(tree_ir.FunctionExpression node) { | 913 visitFunctionExpression(tree_ir.FunctionExpression node) { |
913 // FunctionExpressions are currently unused. | 914 // FunctionExpressions are currently unused. |
914 // We might need them if we want to emit raw JS nested functions. | 915 // We might need them if we want to emit raw JS nested functions. |
915 throw 'FunctionExpressions should not be used'; | 916 throw 'FunctionExpressions should not be used'; |
916 } | 917 } |
917 } | 918 } |
OLD | NEW |