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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1092023002: CPS implementation of throw and rethrow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library dart2js.ir_builder_task; 5 library dart2js.ir_builder_task;
6 6
7 import '../closure.dart' as closurelib; 7 import '../closure.dart' as closurelib;
8 import '../closure.dart' hide ClosureScope; 8 import '../closure.dart' hide ClosureScope;
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 // Build(EmptyStatement, C) = C 359 // Build(EmptyStatement, C) = C
360 ir.Primitive visitEmptyStatement(ast.EmptyStatement node) { 360 ir.Primitive visitEmptyStatement(ast.EmptyStatement node) {
361 assert(irBuilder.isOpen); 361 assert(irBuilder.isOpen);
362 return null; 362 return null;
363 } 363 }
364 364
365 // Build(ExpressionStatement(e), C) = C' 365 // Build(ExpressionStatement(e), C) = C'
366 // where (C', _) = Build(e, C) 366 // where (C', _) = Build(e, C)
367 ir.Primitive visitExpressionStatement(ast.ExpressionStatement node) { 367 ir.Primitive visitExpressionStatement(ast.ExpressionStatement node) {
368 assert(irBuilder.isOpen); 368 assert(irBuilder.isOpen);
369 visit(node.expression); 369 if (node.expression is ast.Throw) {
370 // Throw expressions that occur as statements are translated differently
371 // from ones that occur as subexpressions. This is achieved by peeking
372 // at statement-level expressions here.
373 irBuilder.buildThrow(visit(node.expression));
374 } else {
375 visit(node.expression);
376 }
370 return null; 377 return null;
371 } 378 }
372 379
380 ir.Primitive visitRethrow(ast.Rethrow node) {
381 assert(irBuilder.isOpen);
382 irBuilder.buildRethrow();
383 return null;
384 }
385
373 visitFor(ast.For node) { 386 visitFor(ast.For node) {
374 List<LocalElement> loopVariables = <LocalElement>[]; 387 List<LocalElement> loopVariables = <LocalElement>[];
375 if (node.initializer is ast.VariableDefinitions) { 388 if (node.initializer is ast.VariableDefinitions) {
376 ast.VariableDefinitions definitions = node.initializer; 389 ast.VariableDefinitions definitions = node.initializer;
377 for (ast.Node node in definitions.definitions.nodes) { 390 for (ast.Node node in definitions.definitions.nodes) {
378 LocalElement loopVariable = elements[node]; 391 LocalElement loopVariable = elements[node];
379 loopVariables.add(loopVariable); 392 loopVariables.add(loopVariable);
380 } 393 }
381 } 394 }
382 395
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 ir.Primitive visitReturn(ast.Return node) { 500 ir.Primitive visitReturn(ast.Return node) {
488 assert(irBuilder.isOpen); 501 assert(irBuilder.isOpen);
489 assert(invariant(node, node.beginToken.value != 'native')); 502 assert(invariant(node, node.beginToken.value != 'native'));
490 irBuilder.buildReturn(build(node.expression)); 503 irBuilder.buildReturn(build(node.expression));
491 return null; 504 return null;
492 } 505 }
493 506
494 visitTryStatement(ast.TryStatement node) { 507 visitTryStatement(ast.TryStatement node) {
495 // Multiple catch blocks are not yet implemented. 508 // Multiple catch blocks are not yet implemented.
496 if (node.catchBlocks.isEmpty || 509 if (node.catchBlocks.isEmpty ||
497 node.catchBlocks.nodes.tail == null) { 510 !node.catchBlocks.nodes.tail.isEmpty) {
498 return giveup(node, 'not exactly one catch block'); 511 return giveup(node, 'not exactly one catch block');
499 } 512 }
500 // 'on T' catch blocks are not yet implemented. 513 // 'on T' catch blocks are not yet implemented.
501 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) { 514 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) {
502 return giveup(node, '"on T" catch block'); 515 return giveup(node, '"on T" catch block');
503 } 516 }
504 // Finally blocks are not yet implemented. 517 // Finally blocks are not yet implemented.
505 if (node.finallyBlock != null) { 518 if (node.finallyBlock != null) {
506 return giveup(node, 'try/finally'); 519 return giveup(node, 'try/finally');
507 } 520 }
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1754 arguments.add(visitLiteralString(part.string)); 1767 arguments.add(visitLiteralString(part.string));
1755 } 1768 }
1756 return irBuilder.buildStringConcatenation(arguments); 1769 return irBuilder.buildStringConcatenation(arguments);
1757 } 1770 }
1758 1771
1759 ir.Primitive translateConstant(ast.Node node) { 1772 ir.Primitive translateConstant(ast.Node node) {
1760 assert(irBuilder.isOpen); 1773 assert(irBuilder.isOpen);
1761 return irBuilder.buildConstantLiteral(getConstantForNode(node)); 1774 return irBuilder.buildConstantLiteral(getConstantForNode(node));
1762 } 1775 }
1763 1776
1777 ir.Primitive visitThrow(ast.Throw node) {
1778 assert(irBuilder.isOpen);
1779 // This function is not called for throw expressions occurring as
1780 // statements.
1781 return irBuilder.buildNonTailThrow(visit(node.expression));
1782 }
1783
1764 ir.RootNode nullIfGiveup(ir.RootNode action()) { 1784 ir.RootNode nullIfGiveup(ir.RootNode action()) {
1765 try { 1785 try {
1766 return action(); 1786 return action();
1767 } catch(e, tr) { 1787 } catch(e) {
1768 if (e == ABORT_IRNODE_BUILDER) { 1788 if (e == ABORT_IRNODE_BUILDER) {
1769 return null; 1789 return null;
1770 } 1790 }
1771 rethrow; 1791 rethrow;
1772 } 1792 }
1773 } 1793 }
1774 1794
1775 void internalError(ast.Node node, String message) { 1795 void internalError(ast.Node node, String message) {
1776 giveup(node, message); 1796 giveup(node, message);
1777 } 1797 }
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1997 LocalFunctionElement element = elements[node.function]; 2017 LocalFunctionElement element = elements[node.function];
1998 Object inner = makeSubFunction(node.function); 2018 Object inner = makeSubFunction(node.function);
1999 irBuilder.declareLocalFunction(element, inner); 2019 irBuilder.declareLocalFunction(element, inner);
2000 } 2020 }
2001 2021
2002 ClosureScope getClosureScopeForNode(ast.Node node) => null; 2022 ClosureScope getClosureScopeForNode(ast.Node node) => null;
2003 ClosureEnvironment getClosureEnvironment() => null; 2023 ClosureEnvironment getClosureEnvironment() => null;
2004 2024
2005 ir.RootNode buildExecutable(ExecutableElement element) { 2025 ir.RootNode buildExecutable(ExecutableElement element) {
2006 return nullIfGiveup(() { 2026 return nullIfGiveup(() {
2027 ir.RootNode root;
2007 if (element is FieldElement) { 2028 if (element is FieldElement) {
2008 return buildField(element); 2029 root = buildField(element);
2009 } else if (element is FunctionElement || element is ConstructorElement) { 2030 } else if (element is FunctionElement || element is ConstructorElement) {
2010 return buildFunction(element); 2031 root = buildFunction(element);
2011 } else { 2032 } else {
2012 compiler.internalError(element, "Unexpected element type $element"); 2033 compiler.internalError(element, "Unexpected element type $element");
2013 } 2034 }
2035 new CleanupPass().visit(root);
2036 return root;
2014 }); 2037 });
2015 } 2038 }
2016 2039
2017 /// Returns a [ir.FieldDefinition] describing the initializer of [element]. 2040 /// Returns a [ir.FieldDefinition] describing the initializer of [element].
2018 ir.FieldDefinition buildField(FieldElement element) { 2041 ir.FieldDefinition buildField(FieldElement element) {
2019 assert(invariant(element, element.isImplementation)); 2042 assert(invariant(element, element.isImplementation));
2020 ast.VariableDefinitions definitions = element.node; 2043 ast.VariableDefinitions definitions = element.node;
2021 ast.Node fieldDefinition = definitions.definitions.nodes.first; 2044 ast.Node fieldDefinition = definitions.definitions.nodes.first;
2022 if (definitions.modifiers.isConst) { 2045 if (definitions.modifiers.isConst) {
2023 // TODO(sigurdm): Just return const value. 2046 // TODO(sigurdm): Just return const value.
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 elements); 2240 elements);
2218 closurelib.ClosureScope scope = map.capturingScopes[function.node]; 2241 closurelib.ClosureScope scope = map.capturingScopes[function.node];
2219 if (scope == null) return null; 2242 if (scope == null) return null;
2220 return new ClosureScope(scope.boxElement, 2243 return new ClosureScope(scope.boxElement,
2221 mapValues(scope.capturedVariables, getLocation), 2244 mapValues(scope.capturedVariables, getLocation),
2222 scope.boxedLoopVariables); 2245 scope.boxedLoopVariables);
2223 } 2246 }
2224 2247
2225 ir.RootNode buildExecutable(ExecutableElement element) { 2248 ir.RootNode buildExecutable(ExecutableElement element) {
2226 return nullIfGiveup(() { 2249 return nullIfGiveup(() {
2250 ir.RootNode root;
2227 switch (element.kind) { 2251 switch (element.kind) {
2228 case ElementKind.GENERATIVE_CONSTRUCTOR: 2252 case ElementKind.GENERATIVE_CONSTRUCTOR:
2229 return buildConstructor(element); 2253 root = buildConstructor(element);
2254 break;
2230 2255
2231 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY: 2256 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
2232 return buildConstructorBody(element); 2257 root = buildConstructorBody(element);
2258 break;
2233 2259
2234 case ElementKind.FUNCTION: 2260 case ElementKind.FUNCTION:
2235 case ElementKind.GETTER: 2261 case ElementKind.GETTER:
2236 case ElementKind.SETTER: 2262 case ElementKind.SETTER:
2237 return buildFunction(element); 2263 root = buildFunction(element);
2264 break;
2238 2265
2239 default: 2266 default:
2240 compiler.internalError(element, "Unexpected element type $element"); 2267 compiler.internalError(element, "Unexpected element type $element");
2241 } 2268 }
2269 new CleanupPass().visit(root);
2270 return root;
2242 }); 2271 });
2243 } 2272 }
2244 2273
2245 /// Builds the IR for an [expression] taken from a different [context]. 2274 /// Builds the IR for an [expression] taken from a different [context].
2246 /// 2275 ///
2247 /// Such expressions need to be compiled with a different [sourceFile] and 2276 /// Such expressions need to be compiled with a different [sourceFile] and
2248 /// [elements] mapping. 2277 /// [elements] mapping.
2249 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { 2278 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
2250 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( 2279 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
2251 context.resolvedAst.elements, 2280 context.resolvedAst.elements,
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
2765 SourceInformation buildCall(ast.Node node) { 2794 SourceInformation buildCall(ast.Node node) {
2766 return new PositionSourceInformation( 2795 return new PositionSourceInformation(
2767 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2796 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
2768 } 2797 }
2769 2798
2770 @override 2799 @override
2771 SourceInformationBuilder forContext(AstElement element) { 2800 SourceInformationBuilder forContext(AstElement element) {
2772 return new PositionSourceInformationBuilder(element); 2801 return new PositionSourceInformationBuilder(element);
2773 } 2802 }
2774 } 2803 }
2804
2805 /// Perform simple post-processing on the initial CPS-translated root term.
2806 ///
2807 /// This pass performs backend-independent post-processing on the translated
2808 /// term. It is implemented separately from the optimization passes because
2809 /// it is required for correctness of the implementation.
2810 ///
2811 /// It performs the following translations:
2812 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw]
2813 /// expression.
2814 class CleanupPass extends ir.RecursiveVisitor {
2815 RemovalVisitor _remover = new RemovalVisitor();
2816
2817 ir.Expression replacementFor(ir.Expression expression) {
2818 if (expression != null && expression is ir.LetPrim) {
2819 ir.Primitive primitive = expression.primitive;
2820 if (primitive is ir.NonTailThrow) {
2821 _remover.visit(expression);
2822 return new ir.Throw(primitive.value.definition);
2823 }
2824 }
2825 return expression;
2826 }
2827
2828 processLetPrim(ir.LetPrim node) {
2829 node.body = replacementFor(node.body);
2830 }
2831
2832 processLetCont(ir.LetCont node) {
2833 node.body = replacementFor(node.body);
2834 }
2835
2836 processLetHandler(ir.LetHandler node) {
2837 node.body = replacementFor(node.body);
2838 }
2839
2840 processLetMutable(ir.LetMutable node) {
2841 node.body = replacementFor(node.body);
2842 }
2843
2844 processSetMutableVariable(ir.SetMutableVariable node) {
2845 node.body = replacementFor(node.body);
2846 }
2847
2848 processDeclareFunction(ir.DeclareFunction node) {
2849 node.body = replacementFor(node.body);
2850 }
2851
2852 processSetField(ir.SetField node) {
2853 node.body = replacementFor(node.body);
2854 }
2855
2856 processContinuation(ir.Continuation node) {
2857 node.body = replacementFor(node.body);
2858 }
2859
2860 processBody(ir.Body node) {
2861 node.body = replacementFor(node.body);
2862 }
2863 }
2864
2865 /// Visit a just-deleted subterm and unlink all [Reference]s in it.
2866 class RemovalVisitor extends ir.RecursiveVisitor {
2867 processReference(ir.Reference reference) {
2868 reference.unlink();
2869 }
2870 }
2871
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698