| 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 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 return compiler.findHelper(const SourceString('index')); | 82 return compiler.findHelper(const SourceString('index')); |
| 83 } | 83 } |
| 84 | 84 |
| 85 Element getIndexAssignmentInterceptor() { | 85 Element getIndexAssignmentInterceptor() { |
| 86 return compiler.findHelper(const SourceString('indexSet')); | 86 return compiler.findHelper(const SourceString('indexSet')); |
| 87 } | 87 } |
| 88 | 88 |
| 89 Element getEqualsNullInterceptor() { | 89 Element getEqualsNullInterceptor() { |
| 90 return compiler.findHelper(const SourceString('eqNull')); | 90 return compiler.findHelper(const SourceString('eqNull')); |
| 91 } | 91 } |
| 92 |
| 93 Element getExceptionUnwrapper() { |
| 94 return compiler.findHelper(const SourceString('unwrapException')); |
| 95 } |
| 92 } | 96 } |
| 93 | 97 |
| 94 class SsaBuilderTask extends CompilerTask { | 98 class SsaBuilderTask extends CompilerTask { |
| 95 SsaBuilderTask(Compiler compiler) | 99 SsaBuilderTask(Compiler compiler) |
| 96 : super(compiler), interceptors = new Interceptors(compiler); | 100 : super(compiler), interceptors = new Interceptors(compiler); |
| 97 String get name() => 'SSA builder'; | 101 String get name() => 'SSA builder'; |
| 98 Interceptors interceptors; | 102 Interceptors interceptors; |
| 99 | 103 |
| 100 HGraph build(WorkItem work) { | 104 HGraph build(WorkItem work) { |
| 101 return measure(() { | 105 return measure(() { |
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 } | 625 } |
| 622 | 626 |
| 623 class SsaBuilder implements Visitor { | 627 class SsaBuilder implements Visitor { |
| 624 final Compiler compiler; | 628 final Compiler compiler; |
| 625 TreeElements elements; | 629 TreeElements elements; |
| 626 final Interceptors interceptors; | 630 final Interceptors interceptors; |
| 627 final WorkItem work; | 631 final WorkItem work; |
| 628 bool methodInterceptionEnabled; | 632 bool methodInterceptionEnabled; |
| 629 HGraph graph; | 633 HGraph graph; |
| 630 LocalsHandler localsHandler; | 634 LocalsHandler localsHandler; |
| 635 HInstruction rethrowableException; |
| 631 | 636 |
| 632 Map<StatementElement, BreakHandler> breakTargets; | 637 Map<StatementElement, BreakHandler> breakTargets; |
| 633 | 638 |
| 634 // We build the Ssa graph by simulating a stack machine. | 639 // We build the Ssa graph by simulating a stack machine. |
| 635 List<HInstruction> stack; | 640 List<HInstruction> stack; |
| 636 | 641 |
| 637 // The current block to add instructions to. Might be null, if we are | 642 // The current block to add instructions to. Might be null, if we are |
| 638 // visiting dead code. | 643 // visiting dead code. |
| 639 HBasicBlock current; | 644 HBasicBlock current; |
| 640 | 645 |
| (...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 value = graph.addNewLiteralNull(); | 1893 value = graph.addNewLiteralNull(); |
| 1889 } else { | 1894 } else { |
| 1890 visit(node.expression); | 1895 visit(node.expression); |
| 1891 value = pop(); | 1896 value = pop(); |
| 1892 } | 1897 } |
| 1893 close(new HReturn(value)).addSuccessor(graph.exit); | 1898 close(new HReturn(value)).addSuccessor(graph.exit); |
| 1894 } | 1899 } |
| 1895 | 1900 |
| 1896 visitThrow(Throw node) { | 1901 visitThrow(Throw node) { |
| 1897 if (node.expression === null) { | 1902 if (node.expression === null) { |
| 1898 compiler.unimplemented("SsaBuilder: throw without expression"); | 1903 HInstruction exception = rethrowableException; |
| 1904 if (exception === null) { |
| 1905 exception = graph.addNewLiteralNull(); |
| 1906 compiler.reportError(node, |
| 1907 'throw without expression outside catch block'); |
| 1908 } |
| 1909 close(new HThrow(exception, isRethrow: true)); |
| 1910 } else { |
| 1911 visit(node.expression); |
| 1912 close(new HThrow(pop())); |
| 1899 } | 1913 } |
| 1900 visit(node.expression); | |
| 1901 close(new HThrow(pop())); | |
| 1902 } | 1914 } |
| 1903 | 1915 |
| 1904 visitTypeAnnotation(TypeAnnotation node) { | 1916 visitTypeAnnotation(TypeAnnotation node) { |
| 1905 compiler.internalError('visiting type annotation in SSA builder', | 1917 compiler.internalError('visiting type annotation in SSA builder', |
| 1906 node: node); | 1918 node: node); |
| 1907 } | 1919 } |
| 1908 | 1920 |
| 1909 visitVariableDefinitions(VariableDefinitions node) { | 1921 visitVariableDefinitions(VariableDefinitions node) { |
| 1910 for (Link<Node> link = node.definitions.nodes; | 1922 for (Link<Node> link = node.definitions.nodes; |
| 1911 !link.isEmpty(); | 1923 !link.isEmpty(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2006 if (node.target === null) { | 2018 if (node.target === null) { |
| 2007 breakInstruction = new HBreak(); | 2019 breakInstruction = new HBreak(); |
| 2008 } else { | 2020 } else { |
| 2009 breakInstruction = new HBreak(node.target.source); | 2021 breakInstruction = new HBreak(node.target.source); |
| 2010 } | 2022 } |
| 2011 close(breakInstruction); | 2023 close(breakInstruction); |
| 2012 handler.addBreak(breakInstruction, savedLocals); | 2024 handler.addBreak(breakInstruction, savedLocals); |
| 2013 } | 2025 } |
| 2014 | 2026 |
| 2015 visitContinueStatement(ContinueStatement node) { | 2027 visitContinueStatement(ContinueStatement node) { |
| 2016 compiler.unimplemented('SsaBuilder.visitContinueStatement', node: node); | 2028 // TODO(lrn): Replace this with a real implementation of continue. |
| 2029 compiler.reportWarning(node, 'continue not implemented'); |
| 2030 DartString string = new DartString.literal('continue not implemented'); |
| 2031 HInstruction message = graph.addNewLiteralString(string); |
| 2032 close(new HThrow(message)); |
| 2017 } | 2033 } |
| 2018 | 2034 |
| 2019 BreakHandler getLoopBreakHandler(Loop node) { | 2035 BreakHandler getLoopBreakHandler(Loop node) { |
| 2020 StatementElement element = elements[node]; | 2036 StatementElement element = elements[node]; |
| 2021 BreakHandler handler; | 2037 BreakHandler handler; |
| 2022 if (loopBreakHandler === null) { | 2038 if (loopBreakHandler === null) { |
| 2023 if (element === null) return const NullBreakHandler(); | 2039 if (element === null) return const NullBreakHandler(); |
| 2024 handler = new BreakHandler(this); | 2040 handler = new BreakHandler(this); |
| 2025 } else { | 2041 } else { |
| 2026 handler = loopBreakHandler; | 2042 handler = loopBreakHandler; |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2200 | 2216 |
| 2201 if (!node.catchBlocks.isEmpty()) { | 2217 if (!node.catchBlocks.isEmpty()) { |
| 2202 HBasicBlock block = graph.addNewBlock(); | 2218 HBasicBlock block = graph.addNewBlock(); |
| 2203 enterBlock.addSuccessor(block); | 2219 enterBlock.addSuccessor(block); |
| 2204 open(block); | 2220 open(block); |
| 2205 // Note that the name of this element is irrelevant. | 2221 // Note that the name of this element is irrelevant. |
| 2206 Element element = new Element( | 2222 Element element = new Element( |
| 2207 const SourceString('exception'), ElementKind.PARAMETER, work.element); | 2223 const SourceString('exception'), ElementKind.PARAMETER, work.element); |
| 2208 HParameterValue exception = new HParameterValue(element); | 2224 HParameterValue exception = new HParameterValue(element); |
| 2209 add(exception); | 2225 add(exception); |
| 2226 HInstruction oldRethrowableException = rethrowableException; |
| 2227 rethrowableException = exception; |
| 2228 push(new HStatic(interceptors.getExceptionUnwrapper())); |
| 2229 List<HInstruction> inputs = <HInstruction>[pop(), exception]; |
| 2230 HInvokeStatic unwrappedException = |
| 2231 new HInvokeStatic(Selector.INVOCATION_1, inputs); |
| 2232 add(unwrappedException); |
| 2233 |
| 2210 tryInstruction.exception = exception; | 2234 tryInstruction.exception = exception; |
| 2211 Link<Node> link = node.catchBlocks.nodes; | 2235 Link<Node> link = node.catchBlocks.nodes; |
| 2212 | 2236 |
| 2213 void pushCondition(CatchBlock catchBlock) { | 2237 void pushCondition(CatchBlock catchBlock) { |
| 2214 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 2238 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 2215 HInstruction condition = null; | 2239 HInstruction condition = null; |
| 2216 if (declaration.type == null) { | 2240 if (declaration.type == null) { |
| 2217 condition = graph.addNewLiteralTrue(); | 2241 condition = graph.addNewLiteralTrue(); |
| 2218 stack.add(condition); | 2242 stack.add(condition); |
| 2219 } else { | 2243 } else { |
| 2220 Element typeElement = elements[declaration.type]; | 2244 Element typeElement = elements[declaration.type]; |
| 2221 if (typeElement == null) { | 2245 if (typeElement == null) { |
| 2222 compiler.cancel('Catch with unresolved type', node: catchBlock); | 2246 compiler.cancel('Catch with unresolved type', node: catchBlock); |
| 2223 } | 2247 } |
| 2224 condition = new HIs(typeElement, exception); | 2248 condition = new HIs(typeElement, unwrappedException); |
| 2225 push(condition); | 2249 push(condition); |
| 2226 } | 2250 } |
| 2227 } | 2251 } |
| 2228 | 2252 |
| 2229 void visitThen() { | 2253 void visitThen() { |
| 2230 CatchBlock catchBlock = link.head; | 2254 CatchBlock catchBlock = link.head; |
| 2231 link = link.tail; | 2255 link = link.tail; |
| 2232 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 2256 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
| 2233 localsHandler.updateLocal(elements[declaration.definitions.nodes.head], | 2257 localsHandler.updateLocal(elements[declaration.definitions.nodes.head], |
| 2234 exception); | 2258 unwrappedException); |
| 2235 visit(catchBlock); | 2259 visit(catchBlock); |
| 2236 } | 2260 } |
| 2237 | 2261 |
| 2238 void visitElse() { | 2262 void visitElse() { |
| 2239 if (link.isEmpty()) { | 2263 if (link.isEmpty()) { |
| 2240 close(new HThrow(exception)); | 2264 close(new HThrow(exception, isRethrow: true)); |
| 2241 } else { | 2265 } else { |
| 2242 CatchBlock newBlock = link.head; | 2266 CatchBlock newBlock = link.head; |
| 2243 pushCondition(newBlock); | 2267 pushCondition(newBlock); |
| 2244 handleIf(visitThen, visitElse); | 2268 handleIf(visitThen, visitElse); |
| 2245 } | 2269 } |
| 2246 } | 2270 } |
| 2247 | 2271 |
| 2248 CatchBlock firstBlock = link.head; | 2272 CatchBlock firstBlock = link.head; |
| 2249 pushCondition(firstBlock); | 2273 pushCondition(firstBlock); |
| 2250 handleIf(visitThen, visitElse); | 2274 handleIf(visitThen, visitElse); |
| 2251 if (!isAborted()) blocks.add(close(new HGoto())); | 2275 if (!isAborted()) blocks.add(close(new HGoto())); |
| 2276 rethrowableException = oldRethrowableException; |
| 2252 } | 2277 } |
| 2253 | 2278 |
| 2254 if (node.finallyBlock != null) { | 2279 if (node.finallyBlock != null) { |
| 2255 HBasicBlock finallyBlock = graph.addNewBlock(); | 2280 HBasicBlock finallyBlock = graph.addNewBlock(); |
| 2256 enterBlock.addSuccessor(finallyBlock); | 2281 enterBlock.addSuccessor(finallyBlock); |
| 2257 open(finallyBlock); | 2282 open(finallyBlock); |
| 2258 visit(node.finallyBlock); | 2283 visit(node.finallyBlock); |
| 2259 if (!isAborted()) blocks.add(close(new HGoto())); | 2284 if (!isAborted()) blocks.add(close(new HGoto())); |
| 2260 tryInstruction.finallyBlock = finallyBlock; | 2285 tryInstruction.finallyBlock = finallyBlock; |
| 2261 } | 2286 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2274 } | 2299 } |
| 2275 | 2300 |
| 2276 visitCatchBlock(CatchBlock node) { | 2301 visitCatchBlock(CatchBlock node) { |
| 2277 visit(node.block); | 2302 visit(node.block); |
| 2278 } | 2303 } |
| 2279 | 2304 |
| 2280 visitTypedef(Typedef node) { | 2305 visitTypedef(Typedef node) { |
| 2281 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 2306 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 2282 } | 2307 } |
| 2283 } | 2308 } |
| OLD | NEW |