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 '../../js/js.dart' as js; | 10 import '../../js/js.dart' as js; |
11 import '../../elements/elements.dart'; | 11 import '../../elements/elements.dart'; |
| 12 import '../../io/source_information.dart' show SourceInformation; |
12 import '../../util/maplet.dart'; | 13 import '../../util/maplet.dart'; |
13 import '../../constants/values.dart'; | 14 import '../../constants/values.dart'; |
14 import '../../dart2jslib.dart'; | 15 import '../../dart2jslib.dart'; |
15 | 16 |
16 class CodegenBailout { | 17 class CodegenBailout { |
17 final tree_ir.Node node; | 18 final tree_ir.Node node; |
18 final String reason; | 19 final String reason; |
19 CodegenBailout(this.node, this.reason); | 20 CodegenBailout(this.node, this.reason); |
20 String get message { | 21 String get message { |
21 return 'bailout${node != null ? " on $node" : ""}: $reason'; | 22 return 'bailout${node != null ? " on $node" : ""}: $reason'; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 return buildConstant(node.expression.value); | 176 return buildConstant(node.expression.value); |
176 } | 177 } |
177 | 178 |
178 js.Expression compileConstant(ParameterElement parameter) { | 179 js.Expression compileConstant(ParameterElement parameter) { |
179 return buildConstant(glue.getConstantForVariable(parameter).value); | 180 return buildConstant(glue.getConstantForVariable(parameter).value); |
180 } | 181 } |
181 | 182 |
182 // TODO(karlklose): get rid of the selector argument. | 183 // TODO(karlklose): get rid of the selector argument. |
183 js.Expression buildStaticInvoke(Selector selector, | 184 js.Expression buildStaticInvoke(Selector selector, |
184 Element target, | 185 Element target, |
185 List<js.Expression> arguments) { | 186 List<js.Expression> arguments, |
| 187 {SourceInformation sourceInformation}) { |
186 registry.registerStaticInvocation(target.declaration); | 188 registry.registerStaticInvocation(target.declaration); |
187 if (target == glue.getInterceptorMethod) { | 189 if (target == glue.getInterceptorMethod) { |
188 // This generates a call to the specialized interceptor function, which | 190 // This generates a call to the specialized interceptor function, which |
189 // does not have a specialized element yet, but is emitted as a stub from | 191 // does not have a specialized element yet, but is emitted as a stub from |
190 // the emitter in [InterceptorStubGenerator]. | 192 // the emitter in [InterceptorStubGenerator]. |
191 // TODO(karlklose): Either change [InvokeStatic] to take an [Entity] | 193 // TODO(karlklose): Either change [InvokeStatic] to take an [Entity] |
192 // instead of an [Element] and model the getInterceptor functions as | 194 // instead of an [Element] and model the getInterceptor functions as |
193 // [Entity]s or add a specialized Tree-IR node for interceptor calls. | 195 // [Entity]s or add a specialized Tree-IR node for interceptor calls. |
194 registry.registerUseInterceptor(); | 196 registry.registerUseInterceptor(); |
195 js.VariableUse interceptorLibrary = glue.getInterceptorLibrary(); | 197 js.VariableUse interceptorLibrary = glue.getInterceptorLibrary(); |
196 return js.propertyCall(interceptorLibrary, selector.name, arguments); | 198 return js.propertyCall(interceptorLibrary, selector.name, arguments); |
197 } else { | 199 } else { |
198 js.Expression elementAccess = glue.staticFunctionAccess(target); | 200 js.Expression elementAccess = glue.staticFunctionAccess(target); |
199 return new js.Call(elementAccess, arguments); | 201 return new js.Call(elementAccess, arguments, |
| 202 sourceInformation: sourceInformation); |
200 } | 203 } |
201 } | 204 } |
202 | 205 |
203 @override | 206 @override |
204 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { | 207 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { |
205 checkStaticTargetIsValid(node, node.target); | 208 checkStaticTargetIsValid(node, node.target); |
206 | 209 |
207 if (node.constant != null) return giveup(node); | 210 if (node.constant != null) return giveup(node); |
208 registry.registerInstantiatedClass(node.target.enclosingClass); | 211 registry.registerInstantiatedClass(node.target.enclosingClass); |
209 Selector selector = node.selector; | 212 Selector selector = node.selector; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 @override | 257 @override |
255 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { | 258 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { |
256 checkStaticTargetIsValid(node, node.target); | 259 checkStaticTargetIsValid(node, node.target); |
257 | 260 |
258 if (node.target is! FunctionElement) { | 261 if (node.target is! FunctionElement) { |
259 giveup(node, 'static getters and setters are not supported.'); | 262 giveup(node, 'static getters and setters are not supported.'); |
260 } | 263 } |
261 Selector selector = node.selector; | 264 Selector selector = node.selector; |
262 FunctionElement target = node.target; | 265 FunctionElement target = node.target; |
263 List<js.Expression> arguments = visitArguments(node.arguments); | 266 List<js.Expression> arguments = visitArguments(node.arguments); |
264 return buildStaticInvoke(selector, target, arguments); | 267 return buildStaticInvoke(selector, target, arguments, |
| 268 sourceInformation: node.sourceInformation); |
265 } | 269 } |
266 | 270 |
267 @override | 271 @override |
268 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { | 272 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { |
269 registry.registerDirectInvocation(node.target.declaration); | 273 registry.registerDirectInvocation(node.target.declaration); |
270 if (node.target is ConstructorBodyElement) { | 274 if (node.target is ConstructorBodyElement) { |
271 // A constructor body cannot be overriden or intercepted, so we can | 275 // A constructor body cannot be overriden or intercepted, so we can |
272 // use the short form for this invocation. | 276 // use the short form for this invocation. |
273 // TODO(asgerf): prevent name clash between constructor bodies. | 277 // TODO(asgerf): prevent name clash between constructor bodies. |
274 return js.js('#.#(#)', | 278 return js.js('#.#(#)', |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 | 527 |
524 @override | 528 @override |
525 visitSuperInitializer(tree_ir.SuperInitializer node) { | 529 visitSuperInitializer(tree_ir.SuperInitializer node) { |
526 return errorUnsupportedNode(node); | 530 return errorUnsupportedNode(node); |
527 } | 531 } |
528 | 532 |
529 dynamic errorUnsupportedNode(tree_ir.DartSpecificNode node) { | 533 dynamic errorUnsupportedNode(tree_ir.DartSpecificNode node) { |
530 throw "Unsupported node in JS backend: $node"; | 534 throw "Unsupported node in JS backend: $node"; |
531 } | 535 } |
532 } | 536 } |
OLD | NEW |