| 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 |