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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1417773008: Revert "dart2js cps: Remove unneeded bailout on captured loop variables." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index fd3695ee1cc3882ffec3af0a59fb7214493eced3..5e224e25438c518d8e2f62451d016941f83e659f 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -2277,11 +2277,16 @@ abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
-/// Determines which local variables should be boxed in a mutable variable
-/// inside a given try block.
-class TryBoxedVariables extends ast.Visitor {
+/// Classifies local variables and local functions as captured, if they
+/// are accessed from within a nested function.
+///
+/// This class is specific to the [DartIrBuilder], in that it gives up if it
+/// sees a feature that is currently unsupport by that builder. In particular,
+/// loop variables captured in a for-loop initializer, condition, or update
+/// expression are unsupported.
+class DartCapturedVariables extends ast.Visitor {
final TreeElements elements;
- TryBoxedVariables(this.elements);
+ DartCapturedVariables(this.elements);
FunctionElement currentFunction;
bool insideInitializer = false;
@@ -2327,6 +2332,25 @@ class TryBoxedVariables extends ast.Visitor {
node.visitChildren(this);
}
+ visitFor(ast.For node) {
+ if (node.initializer != null) visit(node.initializer);
+ if (node.condition != null) visit(node.condition);
+ if (node.update != null) visit(node.update);
+
+ // Give up if a variable was captured outside of the loop body.
+ if (node.initializer is ast.VariableDefinitions) {
+ ast.VariableDefinitions definitions = node.initializer;
+ for (ast.Node node in definitions.definitions.nodes) {
+ LocalElement loopVariable = elements[node];
+ if (capturedVariables.contains(loopVariable)) {
+ return giveup(node, 'For-loop variable captured in loop header');
+ }
+ }
+ }
+
+ if (node.body != null) visit(node.body);
+ }
+
void handleSend(ast.Send node) {
Element element = elements[node];
if (Elements.isLocal(element) &&
@@ -2384,14 +2408,18 @@ class TryBoxedVariables extends ast.Visitor {
if (currentFunction.asyncMarker != AsyncMarker.SYNC &&
currentFunction.asyncMarker != AsyncMarker.SYNC_STAR &&
currentFunction.asyncMarker != AsyncMarker.ASYNC) {
- giveup(node, "cannot handle async* functions");
+ giveup(node, "cannot handle sync*/async* functions");
}
+ bool savedInsideInitializer = insideInitializer;
if (node.initializers != null) {
+ insideInitializer = true;
visit(node.initializers);
}
+ insideInitializer = false;
visit(node.body);
currentFunction = savedFunction;
+ insideInitializer = savedInsideInitializer;
}
visitTryStatement(ast.TryStatement node) {
@@ -3099,8 +3127,8 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
return parameters;
}
- TryBoxedVariables _analyzeTryBoxedVariables(ast.Node node) {
- TryBoxedVariables variables = new TryBoxedVariables(elements);
+ DartCapturedVariables _analyzeCapturedVariables(ast.Node node) {
+ DartCapturedVariables variables = new DartCapturedVariables(elements);
try {
variables.analyze(node);
} catch (e) {
@@ -3130,7 +3158,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
// error-prone.
// TODO(kmillikin): We should combine closure conversion and try/catch
// variable analysis in some way.
- TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+ DartCapturedVariables variables = _analyzeCapturedVariables(node);
tryStatements = variables.tryStatements;
IrBuilder builder = getBuilderFor(body);
@@ -3155,7 +3183,7 @@ class JsIrBuilderVisitor extends IrBuilderVisitor {
element,
node,
elements);
- TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
+ DartCapturedVariables variables = _analyzeCapturedVariables(node);
tryStatements = variables.tryStatements;
IrBuilder builder = getBuilderFor(element);
return withBuilder(builder, () => _makeFunctionBody(element, node));
« no previous file with comments | « no previous file | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698