Chromium Code Reviews| 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 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 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1082 close(new HLoopBranch(conditionInstruction)); | 1082 close(new HLoopBranch(conditionInstruction)); |
| 1083 | 1083 |
| 1084 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | 1084 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); |
| 1085 | 1085 |
| 1086 // The body. | 1086 // The body. |
| 1087 HBasicBlock bodyBlock = addNewBlock(); | 1087 HBasicBlock bodyBlock = addNewBlock(); |
| 1088 conditionExitBlock.addSuccessor(bodyBlock); | 1088 conditionExitBlock.addSuccessor(bodyBlock); |
| 1089 open(bodyBlock); | 1089 open(bodyBlock); |
| 1090 | 1090 |
| 1091 localsHandler.enterLoopBody(loop); | 1091 localsHandler.enterLoopBody(loop); |
| 1092 visit(body); | 1092 hackAroundPossiblyAbortingBody(body); |
| 1093 if (isAborted()) { | |
| 1094 compiler.unimplemented("SsaBuilder for loop with aborting body", | |
| 1095 node: body); | |
| 1096 } | |
| 1097 bodyBlock = close(new HGoto()); | 1093 bodyBlock = close(new HGoto()); |
| 1098 | 1094 |
| 1099 // Update. | 1095 // Update. |
| 1100 // We create an update block, even when we are in a while loop. There the | 1096 // We create an update block, even when we are in a while loop. There the |
| 1101 // update block is the jump-target for continue statements. We could avoid | 1097 // update block is the jump-target for continue statements. We could avoid |
| 1102 // the creation if there is no continue, but for now we always create it. | 1098 // the creation if there is no continue, but for now we always create it. |
| 1103 HBasicBlock updateBlock = addNewBlock(); | 1099 HBasicBlock updateBlock = addNewBlock(); |
| 1104 bodyBlock.addSuccessor(updateBlock); | 1100 bodyBlock.addSuccessor(updateBlock); |
| 1105 open(updateBlock); | 1101 open(updateBlock); |
| 1106 | 1102 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1131 visitWhile(While node) { | 1127 visitWhile(While node) { |
| 1132 visitLoop(node, null, node.condition, null, node.body); | 1128 visitLoop(node, null, node.condition, null, node.body); |
| 1133 } | 1129 } |
| 1134 | 1130 |
| 1135 visitDoWhile(DoWhile node) { | 1131 visitDoWhile(DoWhile node) { |
| 1136 localsHandler.startLoop(node); | 1132 localsHandler.startLoop(node); |
| 1137 BreakHandler breakHandler = beginLoopHeader(node); | 1133 BreakHandler breakHandler = beginLoopHeader(node); |
| 1138 HBasicBlock loopEntryBlock = current; | 1134 HBasicBlock loopEntryBlock = current; |
| 1139 | 1135 |
| 1140 localsHandler.enterLoopBody(node); | 1136 localsHandler.enterLoopBody(node); |
| 1141 visit(node.body); | 1137 hackAroundPossiblyAbortingBody(node.body); |
| 1142 if (isAborted()) { | |
| 1143 compiler.unimplemented("SsaBuilder for loop with aborting body"); | |
| 1144 } | |
| 1145 | 1138 |
| 1146 // If there are no continues we could avoid the creation of the condition | 1139 // If there are no continues we could avoid the creation of the condition |
| 1147 // block. This could also lead to a block having multiple entries and exits. | 1140 // block. This could also lead to a block having multiple entries and exits. |
| 1148 HBasicBlock bodyExitBlock = close(new HGoto()); | 1141 HBasicBlock bodyExitBlock = close(new HGoto()); |
| 1149 HBasicBlock conditionBlock = addNewBlock(); | 1142 HBasicBlock conditionBlock = addNewBlock(); |
| 1150 bodyExitBlock.addSuccessor(conditionBlock); | 1143 bodyExitBlock.addSuccessor(conditionBlock); |
| 1151 open(conditionBlock); | 1144 open(conditionBlock); |
| 1152 visit(node.condition); | 1145 visit(node.condition); |
| 1153 assert(!isAborted()); | 1146 assert(!isAborted()); |
| 1154 conditionBlock = close(new HLoopBranch(popBoolified(), | 1147 conditionBlock = close(new HLoopBranch(popBoolified(), |
| (...skipping 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2194 Element variable; | 2187 Element variable; |
| 2195 if (node.declaredIdentifier.asSend() !== null) { | 2188 if (node.declaredIdentifier.asSend() !== null) { |
| 2196 variable = elements[node.declaredIdentifier]; | 2189 variable = elements[node.declaredIdentifier]; |
| 2197 } else { | 2190 } else { |
| 2198 assert(node.declaredIdentifier.asVariableDefinitions() !== null); | 2191 assert(node.declaredIdentifier.asVariableDefinitions() !== null); |
| 2199 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 2192 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
| 2200 variable = elements[variableDefinitions.definitions.nodes.head]; | 2193 variable = elements[variableDefinitions.definitions.nodes.head]; |
| 2201 } | 2194 } |
| 2202 localsHandler.updateLocal(variable, pop()); | 2195 localsHandler.updateLocal(variable, pop()); |
| 2203 | 2196 |
| 2204 visit(node.body); | 2197 hackAroundPossiblyAbortingBody(node.body); |
| 2205 if (isAborted()) { | |
| 2206 compiler.unimplemented("SsaBuilder for loop with aborting body", | |
| 2207 node: node); | |
| 2208 } | |
| 2209 bodyBlock = close(new HGoto()); | 2198 bodyBlock = close(new HGoto()); |
| 2210 | 2199 |
| 2211 // Update. | 2200 // Update. |
| 2212 // We create an update block, even if we are in a for-in loop. The | 2201 // We create an update block, even if we are in a for-in loop. The |
| 2213 // update block is the jump-target for continue statements. We could avoid | 2202 // update block is the jump-target for continue statements. We could avoid |
| 2214 // the creation if there is no continue, but for now we always create it. | 2203 // the creation if there is no continue, but for now we always create it. |
| 2215 HBasicBlock updateBlock = addNewBlock(); | 2204 HBasicBlock updateBlock = addNewBlock(); |
| 2216 bodyBlock.addSuccessor(updateBlock); | 2205 bodyBlock.addSuccessor(updateBlock); |
| 2217 open(updateBlock); | 2206 open(updateBlock); |
| 2218 updateBlock = close(new HGoto()); | 2207 updateBlock = close(new HGoto()); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2242 visit(body); | 2231 visit(body); |
| 2243 return; | 2232 return; |
| 2244 } | 2233 } |
| 2245 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler); | 2234 LocalsHandler beforeLocals = new LocalsHandler.from(localsHandler); |
| 2246 assert(targetElement.isBreakTarget); | 2235 assert(targetElement.isBreakTarget); |
| 2247 BreakHandler handler = new BreakHandler(this, targetElement); | 2236 BreakHandler handler = new BreakHandler(this, targetElement); |
| 2248 // Introduce a new basic block. | 2237 // Introduce a new basic block. |
| 2249 HBasicBlock entryBlock = graph.addNewBlock(); | 2238 HBasicBlock entryBlock = graph.addNewBlock(); |
| 2250 goto(current, entryBlock); | 2239 goto(current, entryBlock); |
| 2251 open(entryBlock); | 2240 open(entryBlock); |
| 2252 visit(body); | 2241 hackAroundPossiblyAbortingBody(body); |
| 2253 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock); | 2242 SubGraph bodyGraph = new SubGraph(entryBlock, lastOpenedBlock); |
| 2254 if (isAborted()) { | |
| 2255 compiler.unimplemented( | |
| 2256 "SsaBuilder for labeled statement with aborting body", node: node); | |
| 2257 } | |
| 2258 | 2243 |
| 2259 HBasicBlock joinBlock = graph.addNewBlock(); | 2244 HBasicBlock joinBlock = graph.addNewBlock(); |
| 2260 List<LocalsHandler> breakLocals = <LocalsHandler>[]; | 2245 List<LocalsHandler> breakLocals = <LocalsHandler>[]; |
| 2261 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { | 2246 handler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) { |
| 2262 breakInstruction.block.addSuccessor(joinBlock); | 2247 breakInstruction.block.addSuccessor(joinBlock); |
| 2263 breakLocals.add(locals); | 2248 breakLocals.add(locals); |
| 2264 }); | 2249 }); |
| 2265 bool hasBreak = breakLocals.length > 0; | 2250 bool hasBreak = breakLocals.length > 0; |
| 2266 if (!isAborted()) { | 2251 if (!isAborted()) { |
| 2267 goto(current, joinBlock); | 2252 goto(current, joinBlock); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2485 | 2470 |
| 2486 // Normally, we would call [close] here. However, then we hit | 2471 // Normally, we would call [close] here. However, then we hit |
| 2487 // another unimplemented feature: aborting loop body. Simply | 2472 // another unimplemented feature: aborting loop body. Simply |
| 2488 // calling [add] does not work as it asserts that the instruction | 2473 // calling [add] does not work as it asserts that the instruction |
| 2489 // isn't a control flow instruction. So we inline parts of [add]. | 2474 // isn't a control flow instruction. So we inline parts of [add]. |
| 2490 current.addAfter(current.last, new HThrow(message)); | 2475 current.addAfter(current.last, new HThrow(message)); |
| 2491 if (isExpression) { | 2476 if (isExpression) { |
| 2492 stack.add(graph.addConstantNull()); | 2477 stack.add(graph.addConstantNull()); |
| 2493 } | 2478 } |
| 2494 } | 2479 } |
| 2480 | |
| 2481 /** HACK HACK HACK */ | |
| 2482 void hackAroundPossiblyAbortingBody(Node body) { | |
| 2483 stack.add(graph.addConstantBool(true)); | |
| 2484 buildBody() { | |
| 2485 visit(body); | |
| 2486 if (isAborted()) { | |
|
floitsch
2012/03/12 15:48:24
Add TODO that this will need to take into account
ahe
2012/03/12 16:55:34
Done.
| |
| 2487 compiler.reportWarning(body, "aborting loop body"); | |
| 2488 } | |
| 2489 } | |
| 2490 handleIf(buildBody, (){}); | |
|
floitsch
2012/03/12 15:48:24
you should be able to pass 'null' for the else bra
ahe
2012/03/12 16:55:34
Done.
| |
| 2491 } | |
| 2495 } | 2492 } |
| OLD | NEW |