Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 1436833002: dart2js cps: Do not propagate expressions into foreign code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add TODO regarding capture of this Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698