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

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

Issue 1686973002: Dart2js CPS: Implement 'await for'. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Not all for-in local variables are declared in the for-in. Created 4 years, 10 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
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 3ae2c1bd8b306e4d385366a8cd3a4fd3465aa8bd..4d5b2940b22065f10c7280d193df7819993301f1 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
@@ -1111,8 +1111,105 @@ class IrBuilderVisitor extends ast.Visitor<ir.Primitive>
}
visitAsyncForIn(ast.AsyncForIn node) {
- // await for is not yet implemented.
- return giveup(node, 'await for');
+ // Translate await for into a loop over a StreamIterator. The source
+ // statement:
+ //
+ // await for (<decl> in <stream>) <body>
+ //
+ // is translated as if it were:
+ //
+ // var iterator = new StreamIterator(<stream>);
+ // try {
+ // while (await iterator.hasNext()) {
+ // <decl> = await iterator.current;
+ // <body>
+ // }
+ // } finally {
+ // await iterator.cancel();
+ // }
+ ir.Primitive stream = visit(node.expression);
+ ir.Primitive dummyTypeArgument = irBuilder.buildNullConstant();
+ ConstructorElement constructor = helpers.streamIteratorConstructor;
+ ir.Primitive iterator = irBuilder.addPrimitive(new ir.InvokeConstructor(
+ constructor.enclosingClass.thisType,
+ constructor,
+ new Selector.callConstructor(constructor.memberName, 1),
+ <ir.Primitive>[stream, dummyTypeArgument],
+ sourceInformationBuilder.buildGeneric(node)));
+
+ ir.Node buildTryBody(IrBuilder builder) {
+ ir.Node buildLoopCondition(IrBuilder builder) {
+ ir.Primitive moveNext = builder.buildDynamicInvocation(
+ iterator,
+ Selectors.moveNext,
+ elements.getMoveNextTypeMask(node),
+ <ir.Primitive>[]);
+ return builder.addPrimitive(new ir.Await(moveNext));
+ }
+
+ ir.Node buildLoopBody(IrBuilder builder) {
+ return withBuilder(builder, () {
+ ir.Primitive current = irBuilder.buildDynamicInvocation(
+ iterator,
+ Selectors.current,
+ elements.getCurrentTypeMask(node),
+ <ir.Primitive>[]);
+ Element variable = elements.getForInVariable(node);
+ if (Elements.isLocal(variable)) {
+ if (node.declaredIdentifier.asVariableDefinitions() != null) {
+ irBuilder.declareLocalVariable(variable);
+ }
+ irBuilder.buildLocalVariableSet(variable, current);
+ } else if (Elements.isError(variable) ||
+ Elements.isMalformed(variable)) {
+ Selector selector =
+ new Selector.setter(new Name(variable.name, variable.library));
+ List<ir.Primitive> args = <ir.Primitive>[current];
+ // Note the comparison below. It can be the case that an element
+ // isError and isMalformed.
+ if (Elements.isError(variable)) {
+ irBuilder.buildStaticNoSuchMethod(selector, args);
+ } else {
+ irBuilder.buildErroneousInvocation(variable, selector, args);
+ }
+ } else if (Elements.isStaticOrTopLevel(variable)) {
+ if (variable.isField) {
+ irBuilder.addPrimitive(new ir.SetStatic(variable, current));
+ } else {
+ irBuilder.buildStaticSetterSet(variable, current);
+ }
+ } else {
+ ir.Primitive receiver = irBuilder.buildThis();
+ ast.Node identifier = node.declaredIdentifier;
+ irBuilder.buildDynamicSet(
+ receiver,
+ elements.getSelector(identifier),
+ elements.getTypeMask(identifier),
+ current);
+ }
+ visit(node.body);
+ });
+ }
+
+ builder.buildWhile(
+ buildCondition: buildLoopCondition,
+ buildBody: buildLoopBody,
+ target: elements.getTargetDefinition(node),
+ closureScope: getClosureScopeForNode(node));
+ }
+
+ ir.Node buildFinallyBody(IrBuilder builder) {
+ ir.Primitive cancellation = builder.buildDynamicInvocation(
+ iterator,
+ Selectors.cancel,
+ backend.dynamicType,
+ <ir.Primitive>[],
+ sourceInformation: sourceInformationBuilder.buildGeneric(node));
+ return builder.addPrimitive(new ir.Await(cancellation));
+ }
+
+ irBuilder.buildTryFinally(new TryStatementInfo(), buildTryBody,
+ buildFinallyBody);
}
visitAwait(ast.Await node) {
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698