| 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'; |
| 8 |
| 7 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; | 9 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir; |
| 8 import '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
| 9 import '../../elements/elements.dart'; | 11 import '../../elements/elements.dart'; |
| 10 import '../../util/maplet.dart'; | 12 import '../../util/maplet.dart'; |
| 13 import '../../constants/values.dart'; |
| 14 import '../../dart2jslib.dart'; |
| 11 | 15 |
| 12 class CodegenBailout { | 16 class CodegenBailout { |
| 13 final tree_ir.Node node; | 17 final tree_ir.Node node; |
| 14 final String reason; | 18 final String reason; |
| 15 CodegenBailout(this.node, this.reason); | 19 CodegenBailout(this.node, this.reason); |
| 16 String get message { | 20 String get message { |
| 17 return 'bailout${node != null ? " on $node" : ""}: $reason'; | 21 return 'bailout${node != null ? " on $node" : ""}: $reason'; |
| 18 } | 22 } |
| 19 } | 23 } |
| 20 | 24 |
| 21 class CodeGenerator extends tree_ir.Visitor<dynamic, js.Expression> { | 25 class CodeGenerator extends tree_ir.Visitor<dynamic, js.Expression> { |
| 26 final CodegenRegistry registry; |
| 27 |
| 28 final Glue glue; |
| 29 |
| 22 /// Variables to be hoisted at the top of the current function. | 30 /// Variables to be hoisted at the top of the current function. |
| 23 List<js.VariableDeclaration> variables = <js.VariableDeclaration>[]; | 31 List<js.VariableDeclaration> variables = <js.VariableDeclaration>[]; |
| 24 | 32 |
| 25 /// Maps variables to their name. | 33 /// Maps variables to their name. |
| 26 Map<tree_ir.Variable, String> variableNames = <tree_ir.Variable, String>{}; | 34 Map<tree_ir.Variable, String> variableNames = <tree_ir.Variable, String>{}; |
| 27 | 35 |
| 28 /// Maps local constants to their name. | 36 /// Maps local constants to their name. |
| 29 Maplet<VariableElement, String> constantNames = | 37 Maplet<VariableElement, String> constantNames = |
| 30 new Maplet<VariableElement, String>(); | 38 new Maplet<VariableElement, String>(); |
| 31 | 39 |
| 32 /// Variables that have had their declaration created. | 40 /// Variables that have had their declaration created. |
| 33 Set<tree_ir.Variable> declaredVariables = new Set<tree_ir.Variable>(); | 41 Set<tree_ir.Variable> declaredVariables = new Set<tree_ir.Variable>(); |
| 34 | 42 |
| 35 /// Variable names that have already been used. Used to avoid name clashes. | 43 /// Variable names that have already been used. Used to avoid name clashes. |
| 36 Set<String> usedVariableNames; | 44 Set<String> usedVariableNames; |
| 37 | 45 |
| 38 List<js.Parameter> parameters; | 46 List<js.Parameter> parameters = new List<js.Parameter>(); |
| 39 List<js.Statement> accumulator = new List<js.Statement>(); | 47 List<js.Statement> accumulator = new List<js.Statement>(); |
| 40 | 48 |
| 41 js.Block body; | 49 js.Block body; |
| 42 | 50 |
| 43 /// Generates JavaScript code for the body of [function]. | 51 /// Generates JavaScript code for the body of [function]. |
| 44 /// The code will be in [body] and the parameters will be in [parameters]. | 52 /// The code will be in [body] and the parameters will be in [parameters]. |
| 53 CodeGenerator(this.glue, this.registry); |
| 54 |
| 45 void buildFunction(tree_ir.FunctionDefinition function) { | 55 void buildFunction(tree_ir.FunctionDefinition function) { |
| 46 visitStatement(function.body); | 56 visitStatement(function.body); |
| 47 for (tree_ir.Variable parameter in function.parameters) { | 57 for (tree_ir.Variable parameter in function.parameters) { |
| 48 parameters.add(new js.Parameter(variableNames[parameter])); | 58 parameters.add(new js.Parameter(variableNames[parameter])); |
| 49 } | 59 } |
| 50 body = new js.Block(accumulator); | 60 body = new js.Block(accumulator); |
| 51 } | 61 } |
| 52 | 62 |
| 53 List<js.Expression> visitArguments(List<tree_ir.Expression> arguments) { | 63 List<js.Expression> visitArguments(List<tree_ir.Expression> arguments) { |
| 54 return arguments.map(visitExpression).toList(); | 64 return arguments.map(visitExpression).toList(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 66 } | 76 } |
| 67 | 77 |
| 68 @override | 78 @override |
| 69 js.Expression visitConditional(tree_ir.Conditional node) { | 79 js.Expression visitConditional(tree_ir.Conditional node) { |
| 70 return giveup(node); | 80 return giveup(node); |
| 71 // TODO: implement visitConditional | 81 // TODO: implement visitConditional |
| 72 } | 82 } |
| 73 | 83 |
| 74 @override | 84 @override |
| 75 js.Expression visitConstant(tree_ir.Constant node) { | 85 js.Expression visitConstant(tree_ir.Constant node) { |
| 76 return giveup(node); | 86 ConstantValue constant = node.expression.value; |
| 77 // TODO: implement visitConstant | 87 registry.registerCompileTimeConstant(constant); |
| 88 return glue.constantReference(constant); |
| 78 } | 89 } |
| 79 | 90 |
| 80 @override | 91 @override |
| 81 js.Expression visitFunctionExpression(tree_ir.FunctionExpression node) { | 92 js.Expression visitFunctionExpression(tree_ir.FunctionExpression node) { |
| 82 return giveup(node); | 93 return giveup(node); |
| 83 // TODO: implement visitFunctionExpression | 94 // TODO: implement visitFunctionExpression |
| 84 } | 95 } |
| 85 | 96 |
| 86 @override | 97 @override |
| 87 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { | 98 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 // TODO: implement visitWhileTrue | 221 // TODO: implement visitWhileTrue |
| 211 } | 222 } |
| 212 | 223 |
| 213 @override | 224 @override |
| 214 void visitReturn(tree_ir.Return node) { | 225 void visitReturn(tree_ir.Return node) { |
| 215 if (node.value != null) { | 226 if (node.value != null) { |
| 216 accumulator.add(new js.Return(visitExpression(node.value))); | 227 accumulator.add(new js.Return(visitExpression(node.value))); |
| 217 } | 228 } |
| 218 } | 229 } |
| 219 } | 230 } |
| OLD | NEW |