Chromium Code Reviews| 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 tree_ir_builder; | 5 library tree_ir_builder; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../constants/values.dart'; | 8 import '../constants/values.dart'; |
| 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| 10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
| 11 import 'package:js_ast/js_ast.dart' as js; | |
| 11 | 12 |
| 12 import 'tree_ir_nodes.dart'; | 13 import 'tree_ir_nodes.dart'; |
| 13 | 14 |
| 14 typedef Statement NodeCallback(Statement next); | 15 typedef Statement NodeCallback(Statement next); |
| 15 | 16 |
| 16 /** | 17 /** |
| 17 * Builder translates from CPS-based IR to direct-style Tree. | 18 * Builder translates from CPS-based IR to direct-style Tree. |
| 18 * | 19 * |
| 19 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced | 20 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced |
| 20 * non-exit continuation `Cont(v, body)` is translated into a direct-style call | 21 * non-exit continuation `Cont(v, body)` is translated into a direct-style call |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 Expression invoke = new InvokeConstructor( | 400 Expression invoke = new InvokeConstructor( |
| 400 node.dartType, | 401 node.dartType, |
| 401 node.target, | 402 node.target, |
| 402 node.selector, | 403 node.selector, |
| 403 arguments, | 404 arguments, |
| 404 node.sourceInformation); | 405 node.sourceInformation); |
| 405 return makeCallExpression(node, invoke); | 406 return makeCallExpression(node, invoke); |
| 406 } | 407 } |
| 407 | 408 |
| 408 NodeCallback visitForeignCode(cps_ir.ForeignCode node) { | 409 NodeCallback visitForeignCode(cps_ir.ForeignCode node) { |
| 410 List<Expression> arguments = | |
| 411 node.arguments.map(getVariableUse).toList(growable: false); | |
| 412 if (HasCapturedArguments.check(node.codeTemplate.ast)) { | |
| 413 for (Expression arg in arguments) { | |
| 414 if (arg is VariableUse) { | |
| 415 arg.variable.isCaptured = true; | |
| 416 } else { | |
| 417 // TODO(asgerf): Avoid capture of 'this'. | |
| 418 } | |
| 419 } | |
| 420 } | |
| 409 if (node.codeTemplate.isExpression) { | 421 if (node.codeTemplate.isExpression) { |
| 410 Expression foreignCode = new ForeignExpression( | 422 Expression foreignCode = new ForeignExpression( |
| 411 node.codeTemplate, | 423 node.codeTemplate, |
| 412 node.type, | 424 node.type, |
| 413 node.arguments.map(getVariableUse).toList(growable: false), | 425 arguments, |
| 414 node.nativeBehavior, | 426 node.nativeBehavior, |
| 415 node.dependency); | 427 node.dependency); |
| 416 return makeCallExpression(node, foreignCode); | 428 return makeCallExpression(node, foreignCode); |
| 417 } else { | 429 } else { |
| 418 return (Statement next) { | 430 return (Statement next) { |
| 419 assert(next is Unreachable); // We are not using the `next` statement. | 431 assert(next is Unreachable); // We are not using the `next` statement. |
| 420 return new ForeignStatement( | 432 return new ForeignStatement( |
| 421 node.codeTemplate, | 433 node.codeTemplate, |
| 422 node.type, | 434 node.type, |
| 423 node.arguments.map(getVariableUse).toList(growable: false), | 435 arguments, |
| 424 node.nativeBehavior, | 436 node.nativeBehavior, |
| 425 node.dependency); | 437 node.dependency); |
| 426 }; | 438 }; |
| 427 } | 439 } |
| 428 } | 440 } |
| 429 | 441 |
| 430 NodeCallback visitGetLazyStatic(cps_ir.GetLazyStatic node) { | 442 NodeCallback visitGetLazyStatic(cps_ir.GetLazyStatic node) { |
| 431 // In the tree IR, GetStatic handles lazy fields because we do not need | 443 // In the tree IR, GetStatic handles lazy fields because we do not need |
| 432 // as fine-grained control over side effects. | 444 // as fine-grained control over side effects. |
| 433 GetStatic value = new GetStatic(node.element, node.sourceInformation); | 445 GetStatic value = new GetStatic(node.element, node.sourceInformation); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); | 709 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node'); |
| 698 } | 710 } |
| 699 | 711 |
| 700 visitFunctionDefinition(cps_ir.FunctionDefinition node) { | 712 visitFunctionDefinition(cps_ir.FunctionDefinition node) { |
| 701 unexpectedNode(node); | 713 unexpectedNode(node); |
| 702 } | 714 } |
| 703 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); | 715 visitParameter(cps_ir.Parameter node) => unexpectedNode(node); |
| 704 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); | 716 visitContinuation(cps_ir.Continuation node) => unexpectedNode(node); |
| 705 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); | 717 visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node); |
| 706 } | 718 } |
| 719 | |
| 720 class HasCapturedArguments extends js.BaseVisitor { | |
| 721 static bool check(js.Node node) { | |
| 722 HasCapturedArguments visitor = new HasCapturedArguments(); | |
| 723 node.accept(visitor); | |
| 724 return visitor.found; | |
| 725 } | |
| 726 | |
| 727 int enclosingFunctions = 0; | |
| 728 bool found = false; | |
| 729 | |
| 730 @override | |
| 731 visitFun(js.Fun node) { | |
| 732 ++enclosingFunctions; | |
| 733 node.visitChildren(this); | |
| 734 --enclosingFunctions; | |
| 735 } | |
| 736 | |
| 737 @override | |
| 738 visitInterpolatedNode(js.InterpolatedNode node) { | |
| 739 if (enclosingFunctions > 0) { | |
| 740 found = true; | |
|
sra1
2015/11/12 02:30:09
The documentation for JS says 'never use `#` in a
asgerf
2015/11/12 12:09:46
FWIW, this change was made to fix the issue with r
| |
| 741 } | |
| 742 } | |
| 743 } | |
| OLD | NEW |