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

Side by Side Diff: lib/compiler/implementation/ssa/builder.dart

Issue 10987073: Fix issue 5517 by setting the successors the right way in a try/catch. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class Interceptors { 5 class Interceptors {
6 Compiler compiler; 6 Compiler compiler;
7 Interceptors(Compiler this.compiler); 7 Interceptors(Compiler this.compiler);
8 8
9 SourceString mapOperatorToMethodName(Operator op) { 9 SourceString mapOperatorToMethodName(Operator op) {
10 String name = op.source.stringValue; 10 String name = op.source.stringValue;
(...skipping 3793 matching lines...) Expand 10 before | Expand all | Expand 10 after
3804 work.allowSpeculativeOptimization = false; 3804 work.allowSpeculativeOptimization = false;
3805 // Save the current locals. The catch block and the finally block 3805 // Save the current locals. The catch block and the finally block
3806 // must not reuse the existing locals handler. None of the variables 3806 // must not reuse the existing locals handler. None of the variables
3807 // that have been defined in the body-block will be used, but for 3807 // that have been defined in the body-block will be used, but for
3808 // loops we will add (unnecessary) phis that will reference the body 3808 // loops we will add (unnecessary) phis that will reference the body
3809 // variables. This makes it look as if the variables were used 3809 // variables. This makes it look as if the variables were used
3810 // in a non-dominated block. 3810 // in a non-dominated block.
3811 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 3811 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
3812 HBasicBlock enterBlock = openNewBlock(); 3812 HBasicBlock enterBlock = openNewBlock();
3813 HTry tryInstruction = new HTry(); 3813 HTry tryInstruction = new HTry();
3814 List<HBasicBlock> blocks = <HBasicBlock>[]; 3814 close(tryInstruction);
3815 blocks.add(close(tryInstruction));
3816 3815
3817 HBasicBlock tryBody = graph.addNewBlock(); 3816 HBasicBlock startBodyBlock;
kasperl 2012/09/28 06:20:06 startTryBlock? endTryBlock?
ngeoffray 2012/09/28 08:20:51 Done.
3818 enterBlock.addSuccessor(tryBody); 3817 HBasicBlock endBodyBlock;
3819 open(tryBody); 3818 HBasicBlock startCatchBlock;
3819 HBasicBlock endCatchBlock;
3820 HBasicBlock startFinallyBlock;
3821 HBasicBlock endFinallyBlock;
3822
3823 startBodyBlock = graph.addNewBlock();
3824 open(startBodyBlock);
3820 visit(node.tryBlock); 3825 visit(node.tryBlock);
3821 if (!isAborted()) blocks.add(close(new HGoto())); 3826 if (!isAborted()) endBodyBlock = close(new HGoto());
3822 SubGraph bodyGraph = new SubGraph(tryBody, lastOpenedBlock); 3827 SubGraph bodyGraph = new SubGraph(startBodyBlock, lastOpenedBlock);
3823 SubGraph catchGraph = null; 3828 SubGraph catchGraph = null;
3824 HParameterValue exception = null; 3829 HParameterValue exception = null;
3830
3825 if (!node.catchBlocks.isEmpty()) { 3831 if (!node.catchBlocks.isEmpty()) {
3826 localsHandler = new LocalsHandler.from(savedLocals); 3832 localsHandler = new LocalsHandler.from(savedLocals);
3827 HBasicBlock block = graph.addNewBlock(); 3833 startCatchBlock = graph.addNewBlock();
3828 enterBlock.addSuccessor(block); 3834 open(startCatchBlock);
3829 open(block);
3830 // Note that the name of this element is irrelevant. 3835 // Note that the name of this element is irrelevant.
3831 Element element = new Element( 3836 Element element = new Element(
3832 const SourceString('exception'), ElementKind.PARAMETER, work.element); 3837 const SourceString('exception'), ElementKind.PARAMETER, work.element);
3833 exception = new HParameterValue(element); 3838 exception = new HParameterValue(element);
3834 add(exception); 3839 add(exception);
3835 HInstruction oldRethrowableException = rethrowableException; 3840 HInstruction oldRethrowableException = rethrowableException;
3836 rethrowableException = exception; 3841 rethrowableException = exception;
3837 3842
3838 pushInvokeHelper1(interceptors.getExceptionUnwrapper(), exception); 3843 pushInvokeHelper1(interceptors.getExceptionUnwrapper(), exception);
3839 HInvokeStatic unwrappedException = pop(); 3844 HInvokeStatic unwrappedException = pop();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3893 } else { 3898 } else {
3894 CatchBlock newBlock = link.head; 3899 CatchBlock newBlock = link.head;
3895 handleIf(node, 3900 handleIf(node,
3896 () { pushCondition(newBlock); }, 3901 () { pushCondition(newBlock); },
3897 visitThen, visitElse); 3902 visitThen, visitElse);
3898 } 3903 }
3899 } 3904 }
3900 3905
3901 CatchBlock firstBlock = link.head; 3906 CatchBlock firstBlock = link.head;
3902 handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse); 3907 handleIf(node, () { pushCondition(firstBlock); }, visitThen, visitElse);
3903 if (!isAborted()) blocks.add(close(new HGoto())); 3908 if (!isAborted()) endCatchBlock = close(new HGoto());
3904 3909
3905 rethrowableException = oldRethrowableException; 3910 rethrowableException = oldRethrowableException;
3906 tryInstruction.catchBlock = block; 3911 tryInstruction.catchBlock = startCatchBlock;
3907 catchGraph = new SubGraph(block, lastOpenedBlock); 3912 catchGraph = new SubGraph(startCatchBlock, lastOpenedBlock);
3908 } 3913 }
3909 3914
3910 SubGraph finallyGraph = null; 3915 SubGraph finallyGraph = null;
3911 if (node.finallyBlock != null) { 3916 if (node.finallyBlock != null) {
3912 localsHandler = new LocalsHandler.from(savedLocals); 3917 localsHandler = new LocalsHandler.from(savedLocals);
3913 HBasicBlock finallyBlock = graph.addNewBlock(); 3918 startFinallyBlock = graph.addNewBlock();
3914 enterBlock.addSuccessor(finallyBlock); 3919 open(startFinallyBlock);
3915 open(finallyBlock);
3916 visit(node.finallyBlock); 3920 visit(node.finallyBlock);
3917 if (!isAborted()) blocks.add(close(new HGoto())); 3921 if (!isAborted()) endFinallyBlock = close(new HGoto());
3918 tryInstruction.finallyBlock = finallyBlock; 3922 tryInstruction.finallyBlock = startFinallyBlock;
3919 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); 3923 finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock);
3920 } 3924 }
3921 3925
3922 HBasicBlock exitBlock = graph.addNewBlock(); 3926 HBasicBlock exitBlock = graph.addNewBlock();
3923 3927
3924 for (HBasicBlock block in blocks) { 3928 // Setup all successors. The entry block that contains the [HTry]
3925 block.addSuccessor(exitBlock); 3929 // has 1) the body, 2) the catch, 3) the finally, and 4) the exit
3930 // blocks as successors.
3931 enterBlock.addSuccessor(startBodyBlock);
3932 if (startCatchBlock != null) {
3933 enterBlock.addSuccessor(startCatchBlock);
kasperl 2012/09/28 06:20:06 Maybe add a helper for adding an optional successo
ngeoffray 2012/09/28 08:20:51 Done.
3934 }
3935 if (startFinallyBlock != null) {
3936 enterBlock.addSuccessor(startFinallyBlock);
3937 }
3938 enterBlock.addSuccessor(exitBlock);
3939
3940 // The body has either the catch, the finally, or the exit block
3941 // as successor.
3942 if (endBodyBlock != null) {
3943 if (startCatchBlock != null) {
kasperl 2012/09/28 06:20:06 If you let the addOptionalSuccessor helper return
ngeoffray 2012/09/28 08:20:51 Soren made a good point that I actually did not ne
3944 endBodyBlock.addSuccessor(startCatchBlock);
3945 } else if (startFinallyBlock != null) {
3946 endBodyBlock.addSuccessor(startFinallyBlock);
3947 } else {
Søren Gjesse 2012/09/27 15:35:28 Do you ever get here? You will always have at leas
ngeoffray 2012/09/28 08:20:51 Good catch. Done.
3948 endBodyBlock.addSuccessor(exitBlock);
3949 }
3950 }
3951
3952 // The catch block has either the finally or the exit block as
3953 // successor.
3954 if (endCatchBlock != null) {
3955 if (startFinallyBlock != null) {
3956 endCatchBlock.addSuccessor(startFinallyBlock);
3957 } else {
3958 endCatchBlock.addSuccessor(exitBlock);
3959 }
3960 }
3961
3962 // The finally block has the exit block as successor.
3963 if (endFinallyBlock != null) {
3964 endFinallyBlock.addSuccessor(exitBlock);
3926 } 3965 }
3927 3966
3928 // Use the locals handler not altered by the catch and finally 3967 // Use the locals handler not altered by the catch and finally
3929 // blocks. 3968 // blocks.
3930 localsHandler = savedLocals; 3969 localsHandler = savedLocals;
3931 open(exitBlock); 3970 open(exitBlock);
3932 enterBlock.setBlockFlow( 3971 enterBlock.setBlockFlow(
3933 new HTryBlockInformation( 3972 new HTryBlockInformation(
3934 wrapStatementGraph(bodyGraph), 3973 wrapStatementGraph(bodyGraph),
3935 exception, 3974 exception,
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
4349 new HSubGraphBlockInformation(elseBranch.graph)); 4388 new HSubGraphBlockInformation(elseBranch.graph));
4350 4389
4351 HBasicBlock conditionStartBlock = conditionBranch.block; 4390 HBasicBlock conditionStartBlock = conditionBranch.block;
4352 conditionStartBlock.setBlockFlow(info, joinBlock); 4391 conditionStartBlock.setBlockFlow(info, joinBlock);
4353 SubGraph conditionGraph = conditionBranch.graph; 4392 SubGraph conditionGraph = conditionBranch.graph;
4354 HIf branch = conditionGraph.end.last; 4393 HIf branch = conditionGraph.end.last;
4355 assert(branch is HIf); 4394 assert(branch is HIf);
4356 branch.blockInformation = conditionStartBlock.blockFlow; 4395 branch.blockInformation = conditionStartBlock.blockFlow;
4357 } 4396 }
4358 } 4397 }
OLDNEW
« no previous file with comments | « no previous file | lib/compiler/implementation/ssa/nodes.dart » ('j') | lib/compiler/implementation/ssa/nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698