Chromium Code Reviews| Index: pkg/compiler/lib/src/closure.dart |
| diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart |
| index 93e7bb2c2b87e60d99bc6d8ac0dcad80f3a7c8c9..d42fdcb24c0c2cce7fa3154095a83c170d6f0d02 100644 |
| --- a/pkg/compiler/lib/src/closure.dart |
| +++ b/pkg/compiler/lib/src/closure.dart |
| @@ -272,6 +272,7 @@ class SynthesizedCallMethodElementX extends BaseFunctionElementX { |
| ClosureClassElement enclosing) |
| : expression = other, |
| super(name, other.kind, other.modifiers, enclosing, false) { |
| + asyncMarker = other.asyncMarker; |
| functionSignatureCache = other.functionSignature; |
| } |
| @@ -347,7 +348,12 @@ class ClosureClassMap { |
| // contain any nested closure. |
| final Map<Node, ClosureScope> capturingScopes = new Map<Node, ClosureScope>(); |
| - final Set<Local> usedVariablesInTry = new Set<Local>(); |
| + // Variables that are used in a try must be treated as boxed because the |
|
floitsch
2015/02/04 12:31:28
Make dartcomment.
Add new line before "Also param
sigurdm
2015/02/05 14:06:03
Done.
|
| + // control flow can be non-linear. |
| + // Also parameters to a `sync*` generator must be boxed, because of the way we |
| + // rewrite sync* functions. See also comments in [useLocal]. |
| + // TODO(johnniwinter): Add variables to this only if the variable is mutated. |
| + final Set<Local> variablesUsedInTryOrGenerator = new Set<Local>(); |
| ClosureClassMap(this.closureElement, |
| this.closureClassElement, |
| @@ -427,6 +433,7 @@ class ClosureTranslator extends Visitor { |
| int closureFieldCounter = 0; |
| int boxedFieldCounter = 0; |
| bool inTryStatement = false; |
| + |
| final Map<Node, ClosureClassMap> closureMappingCache; |
| // Map of captured variables. Initially they will map to `null`. If |
| @@ -588,9 +595,13 @@ class ClosureTranslator extends Visitor { |
| // Note that nested (named) functions are immutable. |
| if (variable != closureData.thisLocal && |
| variable != closureData.closureElement) { |
| - // TODO(ngeoffray): only do this if the variable is mutated. |
| - closureData.usedVariablesInTry.add(variable); |
| + closureData.variablesUsedInTryOrGenerator.add(variable); |
| } |
| + } else if (variable is LocalParameterElement && |
| + variable.functionDeclaration.asyncMarker == AsyncMarker.SYNC_STAR) { |
| + // Parameters in a sync* function are shared between each Iterator created |
| + // by the Iterable returned by the function, therefore they must be boxed. |
| + closureData.variablesUsedInTryOrGenerator.add(variable); |
| } |
| } |