| 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; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 | 184 |
| 185 @override | 185 @override |
| 186 js.Expression visitConstant(tree_ir.Constant node) { | 186 js.Expression visitConstant(tree_ir.Constant node) { |
| 187 return buildConstant(node.value); | 187 return buildConstant(node.value); |
| 188 } | 188 } |
| 189 | 189 |
| 190 js.Expression compileConstant(ParameterElement parameter) { | 190 js.Expression compileConstant(ParameterElement parameter) { |
| 191 return buildConstant(glue.getConstantValueForVariable(parameter)); | 191 return buildConstant(glue.getConstantValueForVariable(parameter)); |
| 192 } | 192 } |
| 193 | 193 |
| 194 // TODO(karlklose): get rid of the selector argument. | 194 js.Expression buildStaticInvoke(Element target, |
| 195 js.Expression buildStaticInvoke(Selector selector, | |
| 196 Element target, | |
| 197 List<js.Expression> arguments, | 195 List<js.Expression> arguments, |
| 198 {SourceInformation sourceInformation}) { | 196 {SourceInformation sourceInformation}) { |
| 199 registry.registerStaticInvocation(target.declaration); | 197 registry.registerStaticInvocation(target.declaration); |
| 200 if (target == glue.getInterceptorMethod) { | 198 js.Expression elementAccess = glue.staticFunctionAccess(target); |
| 201 // This generates a call to the specialized interceptor function, which | 199 return new js.Call(elementAccess, arguments, |
| 202 // does not have a specialized element yet, but is emitted as a stub from | 200 sourceInformation: sourceInformation); |
| 203 // the emitter in [InterceptorStubGenerator]. | |
| 204 // TODO(karlklose): Either change [InvokeStatic] to take an [Entity] | |
| 205 // instead of an [Element] and model the getInterceptor functions as | |
| 206 // [Entity]s or add a specialized Tree-IR node for interceptor calls. | |
| 207 registry.registerUseInterceptor(); | |
| 208 js.VariableUse interceptorLibrary = glue.getInterceptorLibrary(); | |
| 209 return js.propertyCall(interceptorLibrary, js.string(selector.name), | |
| 210 arguments); | |
| 211 } else { | |
| 212 js.Expression elementAccess = glue.staticFunctionAccess(target); | |
| 213 return new js.Call(elementAccess, arguments, | |
| 214 sourceInformation: sourceInformation); | |
| 215 } | |
| 216 } | 201 } |
| 217 | 202 |
| 218 @override | 203 @override |
| 219 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { | 204 js.Expression visitInvokeConstructor(tree_ir.InvokeConstructor node) { |
| 220 if (node.constant != null) return giveup(node); | 205 if (node.constant != null) return giveup(node); |
| 221 | 206 |
| 222 registry.registerInstantiatedType(node.type); | 207 registry.registerInstantiatedType(node.type); |
| 223 Selector selector = node.selector; | 208 Selector selector = node.selector; |
| 224 FunctionElement target = node.target; | 209 FunctionElement target = node.target; |
| 225 List<js.Expression> arguments = visitExpressionList(node.arguments); | 210 List<js.Expression> arguments = visitExpressionList(node.arguments); |
| 226 return buildStaticInvoke(selector, target, arguments); | 211 return buildStaticInvoke(target, arguments); |
| 227 } | 212 } |
| 228 | 213 |
| 229 void registerMethodInvoke(tree_ir.InvokeMethod node) { | 214 void registerMethodInvoke(tree_ir.InvokeMethod node) { |
| 230 Selector selector = node.selector; | 215 Selector selector = node.selector; |
| 231 TypeMask mask = node.mask; | 216 TypeMask mask = node.mask; |
| 232 if (selector.isGetter) { | 217 if (selector.isGetter) { |
| 233 registry.registerDynamicGetter(new UniverseSelector(selector, mask)); | 218 registry.registerDynamicGetter(new UniverseSelector(selector, mask)); |
| 234 } else if (selector.isSetter) { | 219 } else if (selector.isSetter) { |
| 235 registry.registerDynamicSetter(new UniverseSelector(selector, mask)); | 220 registry.registerDynamicSetter(new UniverseSelector(selector, mask)); |
| 236 } else { | 221 } else { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 248 @override | 233 @override |
| 249 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { | 234 js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) { |
| 250 registerMethodInvoke(node); | 235 registerMethodInvoke(node); |
| 251 return js.propertyCall(visitExpression(node.receiver), | 236 return js.propertyCall(visitExpression(node.receiver), |
| 252 glue.invocationName(node.selector), | 237 glue.invocationName(node.selector), |
| 253 visitExpressionList(node.arguments)); | 238 visitExpressionList(node.arguments)); |
| 254 } | 239 } |
| 255 | 240 |
| 256 @override | 241 @override |
| 257 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { | 242 js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) { |
| 258 Selector selector = node.selector; | |
| 259 assert(selector.isGetter || selector.isSetter || selector.isCall); | |
| 260 FunctionElement target = node.target; | 243 FunctionElement target = node.target; |
| 261 List<js.Expression> arguments = visitExpressionList(node.arguments); | 244 List<js.Expression> arguments = visitExpressionList(node.arguments); |
| 262 return buildStaticInvoke(selector, target, arguments, | 245 return buildStaticInvoke(target, arguments, |
| 263 sourceInformation: node.sourceInformation); | 246 sourceInformation: node.sourceInformation); |
| 264 } | 247 } |
| 265 | 248 |
| 266 @override | 249 @override |
| 267 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { | 250 js.Expression visitInvokeMethodDirectly(tree_ir.InvokeMethodDirectly node) { |
| 268 registry.registerDirectInvocation(node.target.declaration); | 251 registry.registerDirectInvocation(node.target.declaration); |
| 269 if (node.target is ConstructorBodyElement) { | 252 if (node.target is ConstructorBodyElement) { |
| 270 // A constructor body cannot be overriden or intercepted, so we can | 253 // A constructor body cannot be overriden or intercepted, so we can |
| 271 // use the short form for this invocation. | 254 // use the short form for this invocation. |
| 272 return js.js('#.#(#)', | 255 return js.js('#.#(#)', |
| 273 [visitExpression(node.receiver), | 256 [visitExpression(node.receiver), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 298 } | 281 } |
| 299 List<js.Expression> entries = | 282 List<js.Expression> entries = |
| 300 new List<js.Expression>(2 * node.entries.length); | 283 new List<js.Expression>(2 * node.entries.length); |
| 301 for (int i = 0; i < node.entries.length; i++) { | 284 for (int i = 0; i < node.entries.length; i++) { |
| 302 entries[2 * i] = visitExpression(node.entries[i].key); | 285 entries[2 * i] = visitExpression(node.entries[i].key); |
| 303 entries[2 * i + 1] = visitExpression(node.entries[i].value); | 286 entries[2 * i + 1] = visitExpression(node.entries[i].value); |
| 304 } | 287 } |
| 305 List<js.Expression> args = entries.isEmpty | 288 List<js.Expression> args = entries.isEmpty |
| 306 ? <js.Expression>[] | 289 ? <js.Expression>[] |
| 307 : <js.Expression>[new js.ArrayInitializer(entries)]; | 290 : <js.Expression>[new js.ArrayInitializer(entries)]; |
| 308 return buildStaticInvoke( | 291 return buildStaticInvoke(constructor, args); |
| 309 new Selector.call(constructor.name, constructor.library, 2), | |
| 310 constructor, | |
| 311 args); | |
| 312 } | 292 } |
| 313 | 293 |
| 314 @override | 294 @override |
| 315 js.Expression visitLogicalOperator(tree_ir.LogicalOperator node) { | 295 js.Expression visitLogicalOperator(tree_ir.LogicalOperator node) { |
| 316 return new js.Binary( | 296 return new js.Binary( |
| 317 node.operator, | 297 node.operator, |
| 318 visitExpression(node.left), | 298 visitExpression(node.left), |
| 319 visitExpression(node.right)); | 299 visitExpression(node.right)); |
| 320 } | 300 } |
| 321 | 301 |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 assert(node.element is FieldElement); | 656 assert(node.element is FieldElement); |
| 677 registry.registerStaticUse(node.element.declaration); | 657 registry.registerStaticUse(node.element.declaration); |
| 678 js.Expression field = glue.staticFieldAccess(node.element); | 658 js.Expression field = glue.staticFieldAccess(node.element); |
| 679 js.Expression value = visitExpression(node.value); | 659 js.Expression value = visitExpression(node.value); |
| 680 return new js.Assignment(field, value); | 660 return new js.Assignment(field, value); |
| 681 } | 661 } |
| 682 | 662 |
| 683 js.Expression buildStaticHelperInvocation(FunctionElement helper, | 663 js.Expression buildStaticHelperInvocation(FunctionElement helper, |
| 684 List<js.Expression> arguments) { | 664 List<js.Expression> arguments) { |
| 685 registry.registerStaticUse(helper); | 665 registry.registerStaticUse(helper); |
| 686 return buildStaticInvoke(new Selector.fromElement(helper), helper, | 666 return buildStaticInvoke(helper, arguments); |
| 687 arguments); | |
| 688 } | 667 } |
| 689 | 668 |
| 690 @override | 669 @override |
| 691 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { | 670 js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) { |
| 692 FunctionElement createType = glue.getCreateRuntimeType(); | 671 FunctionElement createType = glue.getCreateRuntimeType(); |
| 693 FunctionElement typeToString = glue.getRuntimeTypeToString(); | 672 FunctionElement typeToString = glue.getRuntimeTypeToString(); |
| 694 return buildStaticHelperInvocation(createType, | 673 return buildStaticHelperInvocation(createType, |
| 695 [buildStaticHelperInvocation(typeToString, | 674 [buildStaticHelperInvocation(typeToString, |
| 696 [visitExpression(node.value)])]); | 675 [visitExpression(node.value)])]); |
| 697 } | 676 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 return js.js("typeof # === 'number' && Math.floor(#) === #", args); | 762 return js.js("typeof # === 'number' && Math.floor(#) === #", args); |
| 784 } | 763 } |
| 785 } | 764 } |
| 786 | 765 |
| 787 visitFunctionExpression(tree_ir.FunctionExpression node) { | 766 visitFunctionExpression(tree_ir.FunctionExpression node) { |
| 788 // FunctionExpressions are currently unused. | 767 // FunctionExpressions are currently unused. |
| 789 // We might need them if we want to emit raw JS nested functions. | 768 // We might need them if we want to emit raw JS nested functions. |
| 790 throw 'FunctionExpressions should not be used'; | 769 throw 'FunctionExpressions should not be used'; |
| 791 } | 770 } |
| 792 } | 771 } |
| OLD | NEW |