| OLD | NEW |
| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
| 8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
| 9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
| 10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
| (...skipping 6015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6026 /// | 6026 /// |
| 6027 /// Note that to get the right locals behavior, the code visited by [buildTry] | 6027 /// Note that to get the right locals behavior, the code visited by [buildTry] |
| 6028 /// and [buildFinally] must have been analyzed as if inside a try-statement by | 6028 /// and [buildFinally] must have been analyzed as if inside a try-statement by |
| 6029 /// [ClosureTranslator]. | 6029 /// [ClosureTranslator]. |
| 6030 void buildProtectedByFinally(void buildTry(), void buildFinally()) { | 6030 void buildProtectedByFinally(void buildTry(), void buildFinally()) { |
| 6031 // Save the current locals. The finally block must not reuse the existing | 6031 // Save the current locals. The finally block must not reuse the existing |
| 6032 // locals handler. None of the variables that have been defined in the | 6032 // locals handler. None of the variables that have been defined in the |
| 6033 // body-block will be used, but for loops we will add (unnecessary) phis | 6033 // body-block will be used, but for loops we will add (unnecessary) phis |
| 6034 // that will reference the body variables. This makes it look as if the | 6034 // that will reference the body variables. This makes it look as if the |
| 6035 // variables were used in a non-dominated block. | 6035 // variables were used in a non-dominated block. |
| 6036 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 6036 HBasicBlock enterBlock = openNewBlock(); | 6037 HBasicBlock enterBlock = openNewBlock(); |
| 6037 HTry tryInstruction = new HTry(); | 6038 HTry tryInstruction = new HTry(); |
| 6038 close(tryInstruction); | 6039 close(tryInstruction); |
| 6039 bool oldInTryStatement = inTryStatement; | 6040 bool oldInTryStatement = inTryStatement; |
| 6040 inTryStatement = true; | 6041 inTryStatement = true; |
| 6041 | 6042 |
| 6042 HBasicBlock startTryBlock; | 6043 HBasicBlock startTryBlock; |
| 6043 HBasicBlock endTryBlock; | 6044 HBasicBlock endTryBlock; |
| 6044 HBasicBlock startFinallyBlock; | 6045 HBasicBlock startFinallyBlock; |
| 6045 HBasicBlock endFinallyBlock; | 6046 HBasicBlock endFinallyBlock; |
| 6046 | 6047 |
| 6047 startTryBlock = graph.addNewBlock(); | 6048 startTryBlock = graph.addNewBlock(); |
| 6048 open(startTryBlock); | 6049 open(startTryBlock); |
| 6049 buildTry(); | 6050 buildTry(); |
| 6050 // We use a [HExitTry] instead of a [HGoto] for the try block | 6051 // We use a [HExitTry] instead of a [HGoto] for the try block |
| 6051 // because it will have two successors: the join block, and | 6052 // because it will have two successors: the join block, and |
| 6052 // the finally block. | 6053 // the finally block. |
| 6053 if (!isAborted()) endTryBlock = close(new HExitTry()); | 6054 if (!isAborted()) endTryBlock = close(new HExitTry()); |
| 6054 SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock); | 6055 SubGraph bodyGraph = new SubGraph(startTryBlock, lastOpenedBlock); |
| 6055 | 6056 |
| 6056 SubGraph finallyGraph = null; | 6057 SubGraph finallyGraph = null; |
| 6057 | 6058 |
| 6059 localsHandler = new LocalsHandler.from(savedLocals); |
| 6058 startFinallyBlock = graph.addNewBlock(); | 6060 startFinallyBlock = graph.addNewBlock(); |
| 6059 open(startFinallyBlock); | 6061 open(startFinallyBlock); |
| 6060 buildFinally(); | 6062 buildFinally(); |
| 6061 if (!isAborted()) endFinallyBlock = close(new HGoto()); | 6063 if (!isAborted()) endFinallyBlock = close(new HGoto()); |
| 6062 tryInstruction.finallyBlock = startFinallyBlock; | 6064 tryInstruction.finallyBlock = startFinallyBlock; |
| 6063 finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock); | 6065 finallyGraph = new SubGraph(startFinallyBlock, lastOpenedBlock); |
| 6064 | 6066 |
| 6065 HBasicBlock exitBlock = graph.addNewBlock(); | 6067 HBasicBlock exitBlock = graph.addNewBlock(); |
| 6066 | 6068 |
| 6067 void addExitTrySuccessor(HBasicBlock successor) { | 6069 void addExitTrySuccessor(HBasicBlock successor) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 6091 } | 6093 } |
| 6092 | 6094 |
| 6093 // The finally block has the exit block as successor. | 6095 // The finally block has the exit block as successor. |
| 6094 endFinallyBlock.addSuccessor(exitBlock); | 6096 endFinallyBlock.addSuccessor(exitBlock); |
| 6095 | 6097 |
| 6096 // If a block inside try/catch aborts (eg with a return statement), | 6098 // If a block inside try/catch aborts (eg with a return statement), |
| 6097 // we explicitely mark this block a predecessor of the catch | 6099 // we explicitely mark this block a predecessor of the catch |
| 6098 // block and the finally block. | 6100 // block and the finally block. |
| 6099 addExitTrySuccessor(startFinallyBlock); | 6101 addExitTrySuccessor(startFinallyBlock); |
| 6100 | 6102 |
| 6103 // Use the locals handler not altered by the catch and finally |
| 6104 // blocks. |
| 6105 // TODO(sigurdm): We can probably do this, because try-variables are boxed. |
| 6106 // Need to verify. |
| 6107 localsHandler = savedLocals; |
| 6101 open(exitBlock); | 6108 open(exitBlock); |
| 6102 enterBlock.setBlockFlow( | 6109 enterBlock.setBlockFlow( |
| 6103 new HTryBlockInformation( | 6110 new HTryBlockInformation( |
| 6104 wrapStatementGraph(bodyGraph), | 6111 wrapStatementGraph(bodyGraph), |
| 6105 null, // No catch-variable. | 6112 null, // No catch-variable. |
| 6106 null, // No catchGraph. | 6113 null, // No catchGraph. |
| 6107 wrapStatementGraph(finallyGraph)), | 6114 wrapStatementGraph(finallyGraph)), |
| 6108 exitBlock); | 6115 exitBlock); |
| 6109 inTryStatement = oldInTryStatement; | 6116 inTryStatement = oldInTryStatement; |
| 6110 } | 6117 } |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6937 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6944 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 6938 unaliased.accept(this, builder); | 6945 unaliased.accept(this, builder); |
| 6939 } | 6946 } |
| 6940 | 6947 |
| 6941 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6948 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 6942 JavaScriptBackend backend = builder.compiler.backend; | 6949 JavaScriptBackend backend = builder.compiler.backend; |
| 6943 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 6950 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
| 6944 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 6951 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
| 6945 } | 6952 } |
| 6946 } | 6953 } |
| OLD | NEW |