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

Unified Diff: frog/leg/ssa/builder.dart

Issue 9753005: Change visitLoop to handleLoop that takes closures as arguments. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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-leg.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frog/leg/ssa/builder.dart
diff --git a/frog/leg/ssa/builder.dart b/frog/leg/ssa/builder.dart
index 086bc88312d503b6c231df69ca385656e088d155..49f496e96da7ca9d08105d59ffa71f8791909cae 100644
--- a/frog/leg/ssa/builder.dart
+++ b/frog/leg/ssa/builder.dart
@@ -1096,11 +1096,13 @@ class SsaBuilder implements Visitor {
}
// For while loops, initializer and update are null.
- visitLoop(Node loop,
- Node initializer,
- Expression condition,
- NodeList updates,
- Node body) {
+ // The condition function must return a boolean result.
ngeoffray 2012/03/21 07:58:47 Since they'are all doing, why not making it unifor
Lasse Reichstein Nielsen 2012/03/21 09:00:15 I expect to use this one in switch-with-continue,
+ // None of the functions must leave anything on the stack.
+ handleLoop(Node loop,
+ void initialize(),
+ HInstruction condition(),
+ void update(),
+ void body()) {
// Generate:
// <initializer>
// loop-entry:
@@ -1109,19 +1111,12 @@ class SsaBuilder implements Visitor {
// <updates>
// goto loop-entry;
// loop-exit:
- if (body === null) {
- compiler.unimplemented(
- 'SsaBuilder.visitLoop with empty body',
- node: loop);
- }
localsHandler.startLoop(loop);
// The initializer.
- if (initializer !== null) {
- visit(initializer);
- // We don't care about the value of the initialization.
- if (initializer.asExpression() !== null) pop();
+ if (initialize !== null) {
+ initialize();
}
assert(!isAborted());
@@ -1130,8 +1125,7 @@ class SsaBuilder implements Visitor {
HInstruction conditionInstruction;
if (condition != null) {
- visit(condition);
- conditionInstruction = popBoolified();
+ conditionInstruction = condition();
} else {
// TODO(ngeoffray): Once our loop recognition does not require a
// HLoopBranch, we could just generate a HGoto.
@@ -1148,8 +1142,10 @@ class SsaBuilder implements Visitor {
open(beginBodyBlock);
localsHandler.enterLoopBody(loop);
+ if (body !== null) {
+ hackAroundPossiblyAbortingBody(loop, body);
+ }
- hackAroundPossiblyAbortingBody(body);
SubGraph bodyGraph = new SubGraph(beginBodyBlock, current);
HBasicBlock bodyBlock = close(new HGoto());
@@ -1181,14 +1177,8 @@ class SsaBuilder implements Visitor {
localsHandler.enterLoopUpdates(loop);
- if (updates !== null) {
- for (Expression expression in updates) {
- visit(expression);
- assert(!isAborted());
- // The result of the update instruction isn't used, and can just
- // be dropped.
- HInstruction updateInstruction = pop();
- }
+ if (update !== null) {
+ update();
}
updateBlock = close(new HGoto());
// The back-edge completing the cycle.
@@ -1200,11 +1190,39 @@ class SsaBuilder implements Visitor {
visitFor(For node) {
assert(node.body !== null);
- visitLoop(node, node.initializer, node.condition, node.update, node.body);
+ void buildInitializer() {
+ Node initializer = node.initializer;
+ if (initializer !== null) {
+ visit(initializer);
+ if (initializer.asExpression() !== null) {
+ pop();
+ }
+ }
+ }
+ HInstruction buildCondition() {
+ visit(node.condition);
+ return popBoolified();
+ }
+ void buildUpdate() {
+ for (Expression expression in node.update) {
+ visit(expression);
+ assert(!isAborted());
+ // The result of the update instruction isn't used, and can just
+ // be dropped.
+ HInstruction updateInstruction = pop();
+ }
+ }
+ handleLoop(node,
+ node.initializer === null ? null : buildInitializer,
ngeoffray 2012/03/21 07:58:47 How about (for this one and all others): node.ini
Lasse Reichstein Nielsen 2012/03/21 09:00:15 In this case, I could just put the test into the b
+ node.condition === null ? null : buildCondition,
+ node.update.isEmpty() ? null : buildUpdate,
+ () { visit(node.body); });
}
visitWhile(While node) {
- visitLoop(node, null, node.condition, null, node.body);
+ handleLoop(node, null, HInstruction condition() { visit(node.condition);
ngeoffray 2012/03/21 07:58:47 I'd prefer one argument per line, or write the con
Lasse Reichstein Nielsen 2012/03/21 09:00:15 Done.
+ return popBoolified(); },
+ null, () { visit(node.body); });
}
visitDoWhile(DoWhile node) {
@@ -1213,7 +1231,7 @@ class SsaBuilder implements Visitor {
HBasicBlock loopEntryBlock = current;
localsHandler.enterLoopBody(node);
- hackAroundPossiblyAbortingBody(node.body);
+ hackAroundPossiblyAbortingBody(node, () { visit(node.body); });
// If there are no continues we could avoid the creation of the condition
// block. This could also lead to a block having multiple entries and exits.
@@ -2285,76 +2303,44 @@ class SsaBuilder implements Visitor {
// E <declaredIdentifier> = $iter.next();
// <body>
// }
- localsHandler.startLoop(node);
-
- SourceString iteratorName = const SourceString("iterator");
+ // All the generated calls are to zero-argument functions.
Selector selector = Selector.INVOCATION_0;
- Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0);
- assert(interceptor != null);
- HStatic target = new HStatic(interceptor);
- add(target);
- visit(node.expression);
- List<HInstruction> inputs = <HInstruction>[target, pop()];
- HInstruction iterator = new HInvokeInterceptor(
- selector, iteratorName, false, inputs);
- add(iterator);
-
- JumpHandler jumpHandler = beginLoopHeader(node);
- HBasicBlock conditionBlock = current;
-
- // The condition.
- push(new HInvokeDynamicMethod(
- selector, const SourceString('hasNext'), [iterator]));
- HBasicBlock conditionExitBlock = close(new HLoopBranch(popBoolified()));
-
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-
- // The body.
- HBasicBlock bodyBlock = addNewBlock();
- conditionExitBlock.addSuccessor(bodyBlock);
- open(bodyBlock);
-
- // The call to next is considered to be part of the loop body.
- localsHandler.enterLoopBody(node);
-
- push(new HInvokeDynamicMethod(
- selector, const SourceString('next'), [iterator]));
+ // The iterator is shared between initializer, condition and body.
+ HInstruction iterator;
+ void buildInitialize() {
ngeoffray 2012/03/21 07:58:47 buildInitializer?
Lasse Reichstein Nielsen 2012/03/21 09:00:15 Done.
+ SourceString iteratorName = const SourceString("iterator");
+ Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0);
+ assert(interceptor != null);
+ HStatic target = new HStatic(interceptor);
+ add(target);
+ visit(node.expression);
+ List<HInstruction> inputs = <HInstruction>[target, pop()];
+ iterator = new HInvokeInterceptor(selector, iteratorName, false, inputs);
+ add(iterator);
+ }
+ HInstruction buildCondition() {
+ push(new HInvokeDynamicMethod(
+ selector, const SourceString('hasNext'), [iterator]));
ngeoffray 2012/03/21 07:58:47 <Instruction>[iterator]
Lasse Reichstein Nielsen 2012/03/21 09:00:15 Done.
+ return popBoolified();
+ }
+ void buildBody() {
+ push(new HInvokeDynamicMethod(
+ selector, const SourceString('next'), [iterator]));
+
+ Element variable;
+ if (node.declaredIdentifier.asSend() !== null) {
+ variable = elements[node.declaredIdentifier];
+ } else {
+ assert(node.declaredIdentifier.asVariableDefinitions() !== null);
+ VariableDefinitions variableDefinitions = node.declaredIdentifier;
+ variable = elements[variableDefinitions.definitions.nodes.head];
+ }
+ localsHandler.updateLocal(variable, pop());
- Element variable;
- if (node.declaredIdentifier.asSend() !== null) {
- variable = elements[node.declaredIdentifier];
- } else {
- assert(node.declaredIdentifier.asVariableDefinitions() !== null);
- VariableDefinitions variableDefinitions = node.declaredIdentifier;
- variable = elements[variableDefinitions.definitions.nodes.head];
+ visit(node.body);
}
- localsHandler.updateLocal(variable, pop());
-
- hackAroundPossiblyAbortingBody(node.body);
- bodyBlock = close(new HGoto());
-
- jumpHandler.forEachContinue((x,y) {
- // TODO(lrn): Handle continue in for-in.
- // TODO(lrn): Or, preferably, use an abstraction of visitLoop for for-in.
- compiler.cancel('for-in with continue', node: node);
- });
-
- // Update.
- // We create an update block, even if we are in a for-in loop. The
- // update block is the jump-target for continue statements. We could avoid
- // the creation if there is no continue, but for now we always create it.
- HBasicBlock updateBlock = addNewBlock();
-
- bodyBlock.addSuccessor(updateBlock);
- open(updateBlock);
- updateBlock = close(new HGoto());
- // The back-edge completing the cycle.
- updateBlock.addSuccessor(conditionBlock);
- conditionBlock.postProcessLoopHeader();
-
- endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
- jumpHandler.close();
+ handleLoop(node, buildInitialize, buildCondition, null, buildBody);
}
visitLabeledStatement(LabeledStatement node) {
@@ -2381,7 +2367,7 @@ class SsaBuilder implements Visitor {
HBasicBlock entryBlock = graph.addNewBlock();
goto(current, entryBlock);
open(entryBlock);
- hackAroundPossiblyAbortingBody(body);
+ hackAroundPossiblyAbortingBody(node, () { visit(body); });
SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock);
HBasicBlock joinBlock = graph.addNewBlock();
@@ -2699,13 +2685,13 @@ class SsaBuilder implements Visitor {
}
/** HACK HACK HACK */
- void hackAroundPossiblyAbortingBody(Node body) {
+ void hackAroundPossiblyAbortingBody(Node statement, void body()) {
stack.add(graph.addConstantBool(true));
buildBody() {
// TODO(lrn): Make sure to take continue into account.
- visit(body);
+ body();
if (isAborted()) {
- compiler.reportWarning(body, "aborting loop body");
+ compiler.reportWarning(statement, "aborting loop body");
}
}
handleIf(buildBody, null);
« no previous file with comments | « no previous file | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698