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

Side by Side Diff: pkg/compiler/lib/src/js_backend/codegen/unsugar.dart

Issue 1083663005: Implement try/catch in the JS backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comment.s 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
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/glue.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 library dart2js.unsugar_cps; 1 library dart2js.unsugar_cps;
2 2
3 import '../../cps_ir/cps_ir_nodes.dart'; 3 import '../../cps_ir/cps_ir_nodes.dart';
4 4
5 // TODO(karlklose): share the [ParentVisitor]. 5 // TODO(karlklose): share the [ParentVisitor].
6 import '../../cps_ir/optimizers.dart'; 6 import '../../cps_ir/optimizers.dart';
7 import '../../constants/expressions.dart'; 7 import '../../constants/expressions.dart';
8 import '../../constants/values.dart'; 8 import '../../constants/values.dart';
9 import '../../elements/elements.dart' show ClassElement, FieldElement, Element; 9 import '../../elements/elements.dart'
10 show ClassElement, FieldElement, FunctionElement, Element;
10 import '../../js_backend/codegen/glue.dart'; 11 import '../../js_backend/codegen/glue.dart';
11 import '../../dart2jslib.dart' show Selector, World; 12 import '../../dart2jslib.dart' show Selector, World;
12 13
13 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts 14 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
14 /// special nodes that respect JavaScript behavior. 15 /// special nodes that respect JavaScript behavior.
15 /// 16 ///
16 /// Performs the following rewrites: 17 /// Performs the following rewrites:
17 /// - rewrite [IsTrue] in a [Branch] to do boolean conversion. 18 /// - rewrite [IsTrue] in a [Branch] to do boolean conversion.
19 /// - converts two-parameter exception handlers to one-parameter ones.
18 class UnsugarVisitor extends RecursiveVisitor { 20 class UnsugarVisitor extends RecursiveVisitor {
19 Glue _glue; 21 Glue _glue;
22 ParentVisitor _parentVisitor = new ParentVisitor();
20 23
21 UnsugarVisitor(this._glue); 24 UnsugarVisitor(this._glue);
22 25
23 void rewrite(FunctionDefinition function) { 26 void rewrite(FunctionDefinition function) {
24 // Set all parent pointers. 27 // Set all parent pointers.
25 new ParentVisitor().visit(function); 28 _parentVisitor.visit(function);
26 visit(function); 29 visit(function);
27 } 30 }
28 31
29 @override 32 @override
30 visit(Node node) { 33 visit(Node node) {
31 Node result = node.accept(this); 34 Node result = node.accept(this);
32 return result != null ? result : node; 35 return result != null ? result : node;
33 } 36 }
34 37
35 Constant get trueConstant { 38 Constant get trueConstant {
36 return new Constant( 39 return new Constant(
37 new PrimitiveConstantExpression( 40 new PrimitiveConstantExpression(
38 new TrueConstantValue())); 41 new TrueConstantValue()));
39 } 42 }
40 43
41 void insertLetPrim(Primitive primitive, Expression node) { 44 void insertLetPrim(Primitive primitive, Expression node) {
42 LetPrim let = new LetPrim(primitive); 45 LetPrim let = new LetPrim(primitive);
43 InteriorNode parent = node.parent; 46 InteriorNode parent = node.parent;
44 parent.body = let; 47 parent.body = let;
45 let.body = node; 48 let.body = node;
46 node.parent = let; 49 node.parent = let;
47 let.parent = parent; 50 let.parent = parent;
48 } 51 }
49 52
53 /// Insert a static call to [function] at the point of [node] with result
54 /// [result].
55 ///
56 /// Rewrite [node] to
57 ///
58 /// let cont continuation(result) = node
59 /// in invoke function arguments continuation
60 void insertStaticCall(FunctionElement function, List<Primitive> arguments,
61 Parameter result,
62 Expression node) {
63 InteriorNode parent = node.parent;
64 Continuation continuation = new Continuation([result]);
65 continuation.body = node;
66 _parentVisitor.processContinuation(continuation);
67
68 Selector selector = new Selector.fromElement(function);
69 // TODO(johnniwinther): Come up with an implementation of SourceInformation
70 // for calls such as this one that don't appear in the original source.
71 InvokeStatic invoke =
72 new InvokeStatic(function, selector, continuation, arguments, null);
73 _parentVisitor.processInvokeStatic(invoke);
74
75 LetCont letCont = new LetCont(continuation, invoke);
76 _parentVisitor.processLetCont(letCont);
77
78 parent.body = letCont;
79 letCont.parent = parent;
80 }
81
82 processLetHandler(LetHandler node) {
83 // BEFORE: Handlers have two parameters, exception and stack trace.
84 // AFTER: Handlers have a single parameter, which is unwrapped to get
85 // the exception and stack trace.
86 assert(node.handler.parameters.length == 2);
87 Parameter exceptionParameter = node.handler.parameters.first;
88 Parameter stackTraceParameter = node.handler.parameters.last;
89 Expression body = node.handler.body;
90 if (exceptionParameter.hasAtLeastOneUse ||
91 stackTraceParameter.hasAtLeastOneUse) {
92 Parameter exceptionValue = new Parameter(null);
93 exceptionValue.substituteFor(exceptionParameter);
94 insertStaticCall(_glue.getExceptionUnwrapper(), [exceptionParameter],
95 exceptionValue, body);
96
97 if (stackTraceParameter.hasAtLeastOneUse) {
98 Parameter stackTraceValue = new Parameter(null);
99 stackTraceValue.substituteFor(stackTraceParameter);
100 insertStaticCall(_glue.getTraceFromException(), [exceptionValue],
101 stackTraceValue, body);
102 }
103 }
104
105 assert(stackTraceParameter.hasNoUses);
106 node.handler.parameters.removeLast();
107 }
108
50 processInvokeMethod(InvokeMethod node) { 109 processInvokeMethod(InvokeMethod node) {
51 Selector selector = node.selector; 110 Selector selector = node.selector;
52 // TODO(karlklose): should we rewrite all selectors? 111 // TODO(karlklose): should we rewrite all selectors?
53 if (!_glue.isInterceptedSelector(selector)) return; 112 if (!_glue.isInterceptedSelector(selector)) return;
54 113
55 Primitive receiver = node.receiver.definition; 114 Primitive receiver = node.receiver.definition;
56 Set<ClassElement> interceptedClasses = 115 Set<ClassElement> interceptedClasses =
57 _glue.getInterceptedClassesOn(selector); 116 _glue.getInterceptedClassesOn(selector);
58 _glue.registerSpecializedGetInterceptor(interceptedClasses); 117 _glue.registerSpecializedGetInterceptor(interceptedClasses);
59 118
(...skipping 29 matching lines...) Expand all
89 new LetPrim(i, 148 new LetPrim(i,
90 new Branch(new IsTrue(i), 149 new Branch(new IsTrue(i),
91 node.trueContinuation.definition, 150 node.trueContinuation.definition,
92 node.falseContinuation.definition))); 151 node.falseContinuation.definition)));
93 condition.value.unlink(); 152 condition.value.unlink();
94 node.trueContinuation.unlink(); 153 node.trueContinuation.unlink();
95 node.falseContinuation.unlink(); 154 node.falseContinuation.unlink();
96 parent.body = newNode; 155 parent.body = newNode;
97 } 156 }
98 } 157 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/codegen/glue.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698