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

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

Issue 9351020: Implement try/catch without finally, and without type checks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 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: frog/leg/ssa/builder.dart
===================================================================
--- frog/leg/ssa/builder.dart (revision 3986)
+++ frog/leg/ssa/builder.dart (working copy)
@@ -267,13 +267,15 @@
*/
bool isAccessedDirectly(Element element) {
assert(element !== null);
- return redirectionMapping[element] === null;
+ return redirectionMapping[element] === null
+ && !closureData.usedVariablesInTry.contains(element);
}
bool isStoredInClosureField(Element element) {
assert(element !== null);
if (isAccessedDirectly(element)) return false;
Element redirectElement = redirectionMapping[element];
+ if (redirectElement == null) return false;
if (redirectElement.enclosingElement.kind == ElementKind.CLASS) {
assert(redirectElement is ClosureFieldElement);
return true;
@@ -284,10 +286,13 @@
bool isBoxed(Element element) {
if (isAccessedDirectly(element)) return false;
if (isStoredInClosureField(element)) return false;
- // TODO(floitsch): add some asserts that we really have a boxed element.
- return true;
+ return redirectionMapping[element] !== null;
}
+ bool isUsedInTry(Element element) {
+ return closureData.usedVariablesInTry.contains(element);
+ }
+
/**
* Returns an [HInstruction] for the given element. If the element is
* boxed or stored in a closure then the method generates code to retrieve
@@ -310,8 +315,7 @@
HInstruction fieldGet = new HFieldGet(redirect, receiver);
builder.add(fieldGet);
return fieldGet;
- } else {
- assert(isBoxed(element));
+ } else if (isBoxed(element)) {
Element redirect = redirectionMapping[element];
// In the function that declares the captured variable the box is
// accessed as direct local. Inside the nested closure the box is
@@ -323,6 +327,11 @@
HInstruction lookup = new HFieldGet(redirect, box);
builder.add(lookup);
return lookup;
+ } else {
+ assert(isUsedInTry(element));
+ HInstruction variable = new HFieldGet.fromActivation(element);
+ builder.add(variable);
+ return variable;
}
}
@@ -347,8 +356,7 @@
HInstruction receiver = new HThis();
builder.add(receiver);
builder.add(new HFieldSet(redirect, receiver, value));
- } else {
- assert(isBoxed(element));
+ } else if (isBoxed(element)) {
Element redirect = redirectionMapping[element];
// The box itself could be captured, or be local. A local variable that
// is captured will be boxed, but the box itself will be a local.
@@ -357,6 +365,9 @@
assert(redirect.enclosingElement.kind == ElementKind.VARIABLE);
HInstruction box = readLocal(redirect.enclosingElement);
builder.add(new HFieldSet(redirect, box, value));
+ } else {
+ assert(isUsedInTry(element));
+ builder.add(new HFieldSet.fromActivation(element,value));
}
}
@@ -1703,7 +1714,53 @@
}
visitTryStatement(TryStatement node) {
- compiler.unimplemented('SsaBuilder.visitTryStatement', node: node);
+ HBasicBlock enterBlock = graph.addNewBlock();
+ close(new HGoto()).addSuccessor(enterBlock);
+ open(enterBlock);
+ close(new HTry());
+
+ HBasicBlock tryBody = graph.addNewBlock();
+ enterBlock.addSuccessor(tryBody);
+ open(tryBody);
+ visit(node.tryBlock);
+ HBasicBlock endTryBlock;
+ if (!isAborted()) endTryBlock = close(new HGoto());
floitsch 2012/02/07 17:40:00 We usually just update the variable: tryBlock = cl
ngeoffray 2012/02/08 09:52:23 As discussed, renamed the variable to endTryBody.
+
+ List<HBasicBlock> catchBlocks = <HBasicBlock>[];
+ int catchBlocksCount = 0;
+ for (CatchBlock catchBlock in node.catchBlocks.nodes) {
+ if (++catchBlocksCount != 1) {
+ compiler.unimplemented('SsaBuilder multiple catch blocks', node: node);
+ }
+ HBasicBlock block = graph.addNewBlock();
+ enterBlock.addSuccessor(block);
+ open(block);
+ visit(catchBlock);
+ if (!isAborted()) {
+ close(new HGoto());
+ catchBlocks.add(block);
+ }
+ }
+
+ HBasicBlock exitBlock = graph.addNewBlock();
+
+ if (endTryBlock != null) {
+ endTryBlock.addSuccessor(exitBlock);
+ }
+
+ for (HBasicBlock block in catchBlocks) {
+ block.addSuccessor(exitBlock);
+ }
+
+ if (node.finallyBlock != null) {
+ compiler.unimplemented('SsaBuilder finally block', node: node);
+ }
+
+ HBasicBlock joinBlock = graph.addNewBlock();
floitsch 2012/02/07 17:40:00 now that I think about it, I'm not sure we need th
ngeoffray 2012/02/08 09:52:23 Done.
+ open(exitBlock);
+ close(new HGoto()).addSuccessor(joinBlock);
+
+ open(joinBlock);
}
visitScriptTag(ScriptTag node) {
@@ -1711,7 +1768,12 @@
}
visitCatchBlock(CatchBlock node) {
- compiler.unimplemented('SsaBuilder.visitCatchBlock', node: node);
+ NodeList formals = node.formals;
+ VariableDefinitions exception = formals.nodes.head;
+ if (exception.type != null) {
+ compiler.unimplemented('SsaBuilder catch with type', node: node);
+ }
+ visit(node.block);
}
visitTypedef(Typedef node) {

Powered by Google App Engine
This is Rietveld 408576698