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

Unified Diff: pkg/compiler/lib/src/js/rewrite_async.dart

Issue 972063003: Make sure to bind a method to its receiver if it is stored in a temporary. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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
« no previous file with comments | « no previous file | tests/language/async_this_bound_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js/rewrite_async.dart
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 1490ada8cc61d4082c436dbefdf0910dd5e23f9c..6d3e1589ebf2f3328f369b4354de7617c8ff9d79 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -399,11 +399,39 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
// Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not
// [js.Literal]s.
if (result is js.Literal) return result;
+
+ js.Expression tempVar = useTempVar(allocateTempVar());
+ addStatement(js.js.statement('# = #;', [tempVar, result]));
+ return tempVar;
+ }
+
+
+ /// Like [_storeIfNecessary] but binds JavaScript `this` of the function if
+ /// the receiver is a [js.PropertyAccess].
+ /// This is necessary because we cannot translate `a.b()` to:
+ /// temp = a.b;
floitsch 2015/03/06 16:32:15 nit: make sure that this mark-downs right. (maybe
+ /// temp();
+ /// This leaves `this` unbound in the call. Take care to bind a
floitsch 2015/03/06 16:32:15 ditto here.
+ js.Expression _storeAndBindIfNecessary(js.Expression result) {
+ // Note that RegExes, js.ArrayInitializer and js.ObjectInitializer are not
+ // [js.Literal]s.
+ if (result is js.Literal) return result;
+ if (result is js.PropertyAccess) {
+ js.Expression tempVar = useTempVar(allocateTempVar());
+ addStatement(js.js.statement('# = #', [tempVar, result.receiver]));
+ addStatement(js.js.statement('# = #.#.bind(#)', [
+ tempVar, tempVar, result.selector, tempVar
+ ]));
+ return tempVar;
+ }
+
js.Expression tempVar = useTempVar(allocateTempVar());
addStatement(js.js.statement('# = #;', [tempVar, result]));
return tempVar;
}
+ // TODO(sigurdm): This is obsolete - all calls use store: false. Replace with
+ // visitExpression(node);
withExpression(js.Expression node, fn(js.Expression result), {bool store}) {
int oldTempVarIndex = currentTempVarIndex;
js.Expression visited = visitExpression(node);
@@ -415,6 +443,19 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
return result;
}
+ withExpressionBinding(js.Expression node,
+ fn(js.Expression result), {bool store}) {
+ int oldTempVarIndex = currentTempVarIndex;
+ js.Expression visited = visitExpression(node);
+ if (store) {
+ visited = _storeAndBindIfNecessary(visited);
+ }
+ var result = fn(visited);
+ currentTempVarIndex = oldTempVarIndex;
+ return result;
+ }
+
+
/// Calls [fn] with the value of evaluating [node1] and [node2].
///
/// If `shouldTransform(node2)` the first expression is stored in a temporary
@@ -804,7 +845,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
@override
js.Expression visitCall(js.Call node) {
bool storeTarget = node.arguments.any(shouldTransform);
- return withExpression(node.target, (target) {
+ return withExpressionBinding(node.target, (target) {
return withExpressions(node.arguments, (List<js.Expression> arguments) {
return new js.Call(target, arguments);
});
@@ -919,7 +960,8 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
bool oldInsideUntranslatedBreakable = insideUntranslatedBreakable;
insideUntranslatedBreakable = true;
withExpression(node.condition, (js.Expression condition) {
- addStatement(js.js.statement('do {#} while (#)', [node.body, condition]));
+ addStatement(js.js.statement('do {#} while (#)',
+ [node.body, condition]));
}, store: false);
insideUntranslatedBreakable = oldInsideUntranslatedBreakable;
return;
@@ -1147,7 +1189,7 @@ abstract class AsyncRewriterBase extends js.NodeVisitor {
@override
js.Expression visitNew(js.New node) {
bool storeTarget = node.arguments.any(shouldTransform);
- return withExpression(node.target, (target) {
+ return withExpressionBinding(node.target, (target) {
return withExpressions(node.arguments, (List<js.Expression> arguments) {
return new js.New(target, arguments);
});
@@ -1775,7 +1817,8 @@ class SyncStarRewriter extends AsyncRewriterBase {
js.VariableDeclarationList variableDeclarations) {
// Each iterator invocation on the iterable should work on its own copy of
// the parameters.
- // TODO(sigurdm): We only need to do this copying for parameters that are mutated.
+ // TODO(sigurdm): We only need to do this copying for parameters that are
+ // mutated.
List<js.VariableInitialization> declarations =
new List<js.VariableInitialization>();
List<js.Parameter> renamedParameters = new List<js.Parameter>();
« no previous file with comments | « no previous file | tests/language/async_this_bound_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698