OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_nodes_sexpr; | 5 library dart2js.ir_nodes_sexpr; |
6 | 6 |
7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
8 import '../util/util.dart'; | 8 import '../util/util.dart'; |
9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
10 import '../universe/call_structure.dart' show | 10 import '../universe/call_structure.dart' show |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 namer.setReturnContinuation(node.returnContinuation); | 64 namer.setReturnContinuation(node.returnContinuation); |
65 String body = indentBlock(() => visit(node.body)); | 65 String body = indentBlock(() => visit(node.body)); |
66 return '$indentation' | 66 return '$indentation' |
67 '(FunctionDefinition $name $thisParameter ($parameters) return\n' | 67 '(FunctionDefinition $name $thisParameter ($parameters) return\n' |
68 '$body)'; | 68 '$body)'; |
69 } | 69 } |
70 | 70 |
71 String visitLetPrim(LetPrim node) { | 71 String visitLetPrim(LetPrim node) { |
72 String name = newValueName(node.primitive); | 72 String name = newValueName(node.primitive); |
73 String value = visit(node.primitive); | 73 String value = visit(node.primitive); |
| 74 String bindings = '($name $value)'; |
| 75 String skip = ' ' * '(LetPrim ('.length; |
| 76 while (node.body is LetPrim) { |
| 77 node = node.body; |
| 78 name = newValueName(node.primitive); |
| 79 value = visit(node.primitive); |
| 80 bindings += '\n${indentation}$skip($name $value)'; |
| 81 } |
74 String body = indentBlock(() => visit(node.body)); | 82 String body = indentBlock(() => visit(node.body)); |
75 return '$indentation(LetPrim ($name $value)\n$body)'; | 83 return '$indentation(LetPrim ($bindings)\n$body)'; |
| 84 } |
| 85 |
| 86 bool isBranchTarget(Continuation cont) { |
| 87 return cont.hasExactlyOneUse && cont.firstRef.parent is Branch; |
76 } | 88 } |
77 | 89 |
78 String visitLetCont(LetCont node) { | 90 String visitLetCont(LetCont node) { |
79 String conts; | 91 String conts; |
80 bool first = true; | 92 bool first = true; |
| 93 String skip = ' ' * '(LetCont ('.length; |
81 for (Continuation continuation in node.continuations) { | 94 for (Continuation continuation in node.continuations) { |
| 95 // Branch continuations will be printed at their use site. |
| 96 if (isBranchTarget(continuation)) continue; |
82 if (first) { | 97 if (first) { |
83 first = false; | 98 first = false; |
84 conts = visit(continuation); | 99 conts = visit(continuation); |
85 } else { | 100 } else { |
86 // Each subsequent line is indented additional spaces to align it | 101 // Each subsequent line is indented additional spaces to align it |
87 // with the previous continuation. | 102 // with the previous continuation. |
88 String indent = '$indentation${' ' * '(LetCont ('.length}'; | 103 conts += '\n${indentation}$skip${visit(continuation)}'; |
89 conts = '$conts\n$indent${visit(continuation)}'; | |
90 } | 104 } |
91 } | 105 } |
| 106 // If there were no continuations printed, just print the body. |
| 107 if (first) return visit(node.body); |
| 108 |
92 String body = indentBlock(() => visit(node.body)); | 109 String body = indentBlock(() => visit(node.body)); |
93 return '$indentation(LetCont ($conts)\n$body)'; | 110 return '$indentation(LetCont ($conts)\n$body)'; |
94 } | 111 } |
95 | 112 |
96 String visitLetHandler(LetHandler node) { | 113 String visitLetHandler(LetHandler node) { |
97 // There are no explicit references to the handler, so we leave it | 114 // There are no explicit references to the handler, so we leave it |
98 // anonymous in the printed representation. | 115 // anonymous in the printed representation. |
99 String parameters = node.handler.parameters | 116 String parameters = node.handler.parameters |
100 .map((p) => '${decorator(p, newValueName(p))}') | 117 .map((p) => '${decorator(p, newValueName(p))}') |
101 .join(' '); | 118 .join(' '); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
184 String value = access(node.value); | 201 String value = access(node.value); |
185 return '$indentation(Throw $value)'; | 202 return '$indentation(Throw $value)'; |
186 } | 203 } |
187 | 204 |
188 String visitRethrow(Rethrow node) { | 205 String visitRethrow(Rethrow node) { |
189 return '$indentation(Rethrow)'; | 206 return '$indentation(Rethrow)'; |
190 } | 207 } |
191 | 208 |
192 String visitBranch(Branch node) { | 209 String visitBranch(Branch node) { |
193 String condition = access(node.condition); | 210 String condition = access(node.condition); |
194 String trueCont = access(node.trueContinuation); | 211 assert(isBranchTarget(node.trueContinuation.definition)); |
195 String falseCont = access(node.falseContinuation); | 212 assert(isBranchTarget(node.falseContinuation.definition)); |
| 213 String trueCont = |
| 214 indentBlock(() => visit(node.trueContinuation.definition)); |
| 215 String falseCont = |
| 216 indentBlock(() => visit(node.falseContinuation.definition)); |
196 String strict = node.isStrictCheck ? 'Strict' : 'NonStrict'; | 217 String strict = node.isStrictCheck ? 'Strict' : 'NonStrict'; |
197 return '$indentation(Branch $condition $trueCont $falseCont $strict)'; | 218 return '$indentation(Branch $strict $condition\n$trueCont\n$falseCont)'; |
198 } | 219 } |
199 | 220 |
200 String visitUnreachable(Unreachable node) { | 221 String visitUnreachable(Unreachable node) { |
201 return '$indentation(Unreachable)'; | 222 return '$indentation(Unreachable)'; |
202 } | 223 } |
203 | 224 |
204 String visitConstant(Constant node) { | 225 String visitConstant(Constant node) { |
205 String value = node.value.accept(new ConstantStringifier(), null); | 226 String value = node.value.accept(new ConstantStringifier(), null); |
206 return '(Constant $value)'; | 227 return '(Constant $value)'; |
207 } | 228 } |
208 | 229 |
209 String visitContinuation(Continuation node) { | 230 String visitContinuation(Continuation node) { |
| 231 if (isBranchTarget(node)) { |
| 232 assert(node.parameters.isEmpty); |
| 233 assert(!node.isRecursive); |
| 234 return indentBlock(() => visit(node.body)); |
| 235 } |
210 String name = newContinuationName(node); | 236 String name = newContinuationName(node); |
211 if (node.isRecursive) name = 'rec $name'; | 237 if (node.isRecursive) name = 'rec $name'; |
212 // TODO(karlklose): this should be changed to `.map(visit).join(' ')` and | 238 // TODO(karlklose): this should be changed to `.map(visit).join(' ')` |
213 // should recurse to [visit]. Currently we can't do that, because the | 239 // and should recurse to [visit]. Currently we can't do that, because |
214 // unstringifier_test produces [LetConts] with dummy arguments on them. | 240 // the unstringifier_test produces [LetConts] with dummy arguments on |
| 241 // them. |
215 String parameters = node.parameters | 242 String parameters = node.parameters |
216 .map((p) => '${decorator(p, newValueName(p))}') | 243 .map((p) => '${decorator(p, newValueName(p))}') |
217 .join(' '); | 244 .join(' '); |
218 String body = indentBlock(() => indentBlock(() => visit(node.body))); | 245 String body = indentBlock(() => indentBlock(() => visit(node.body))); |
219 return '($name ($parameters)\n$body)'; | 246 return '($name ($parameters)\n$body)'; |
220 } | 247 } |
221 | 248 |
222 String visitGetMutable(GetMutable node) { | 249 String visitGetMutable(GetMutable node) { |
223 return '(GetMutable ${access(node.variable)})'; | 250 return '(GetMutable ${access(node.variable)})'; |
224 } | 251 } |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 void setReturnContinuation(Continuation node) { | 518 void setReturnContinuation(Continuation node) { |
492 assert(!_names.containsKey(node) || _names[node] == 'return'); | 519 assert(!_names.containsKey(node) || _names[node] == 'return'); |
493 _names[node] = 'return'; | 520 _names[node] = 'return'; |
494 } | 521 } |
495 | 522 |
496 String getName(Node node) { | 523 String getName(Node node) { |
497 if (!_names.containsKey(node)) return 'MISSING_NAME'; | 524 if (!_names.containsKey(node)) return 'MISSING_NAME'; |
498 return _names[node]; | 525 return _names[node]; |
499 } | 526 } |
500 } | 527 } |
OLD | NEW |