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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ir/ir_nodes.dart

Issue 231863007: Support local variables in dart2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 6 years, 7 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 // IrNodes are kept in a separate library to have precise control over their 5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system. 6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 7 library dart2js.ir_nodes;
8 8
9 import '../dart2jslib.dart' as dart2js show Constant; 9 import '../dart2jslib.dart' as dart2js show Constant;
10 import '../elements/elements.dart' 10 import '../elements/elements.dart'
(...skipping 14 matching lines...) Expand all
25 25
26 /// The base class of things that variables can refer to: primitives, 26 /// The base class of things that variables can refer to: primitives,
27 /// continuations, function and continuation parameters, etc. 27 /// continuations, function and continuation parameters, etc.
28 abstract class Definition extends Node { 28 abstract class Definition extends Node {
29 // The head of a linked-list of occurrences, in no particular order. 29 // The head of a linked-list of occurrences, in no particular order.
30 Reference firstRef = null; 30 Reference firstRef = null;
31 31
32 bool get hasAtMostOneUse => firstRef == null || firstRef.nextRef == null; 32 bool get hasAtMostOneUse => firstRef == null || firstRef.nextRef == null;
33 bool get hasExactlyOneUse => firstRef != null && firstRef.nextRef == null; 33 bool get hasExactlyOneUse => firstRef != null && firstRef.nextRef == null;
34 bool get hasAtLeastOneUse => firstRef != null; 34 bool get hasAtLeastOneUse => firstRef != null;
35
36 void substituteFor(Definition other) {
37 if (other.firstRef == null) return;
38 Reference previous, current = other.firstRef;
39 do {
40 current.definition = this;
41 previous = current;
42 current = current.nextRef;
43 } while (current != null);
44 previous.nextRef = firstRef;
45 firstRef = other.firstRef;
46 }
35 } 47 }
36 48
37 abstract class Primitive extends Definition { 49 abstract class Primitive extends Definition {
38 } 50 }
39 51
40 /// Operands to invocations and primitives are always variables. They point to 52 /// Operands to invocations and primitives are always variables. They point to
41 /// their definition and are linked into a list of occurrences. 53 /// their definition and are linked into a list of occurrences.
42 class Reference { 54 class Reference {
43 Definition definition; 55 Definition definition;
44 Reference nextRef = null; 56 Reference nextRef = null;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 assert(selector.kind == SelectorKind.CALL); 120 assert(selector.kind == SelectorKind.CALL);
109 assert(selector.name == target.name); 121 assert(selector.name == target.name);
110 } 122 }
111 123
112 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 124 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
113 } 125 }
114 126
115 /// Invoke a continuation in tail position. 127 /// Invoke a continuation in tail position.
116 class InvokeContinuation extends Expression { 128 class InvokeContinuation extends Expression {
117 final Reference continuation; 129 final Reference continuation;
118 final Reference argument; 130 final List<Reference> arguments;
119 131
120 InvokeContinuation(Continuation cont, Definition arg) 132 InvokeContinuation(Continuation cont, List<Definition> args)
121 : continuation = new Reference(cont), 133 : continuation = new Reference(cont),
122 argument = new Reference(arg); 134 arguments = args.map((t) => new Reference(t)).toList(growable: false);
135 accept(Visitor visitor) => visitor.visitInvokeContinuation(this);
136 }
123 137
124 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); 138 /// The base class of things which can be tested and branched on.
139 abstract class Condition extends Node {
140 }
141
142 class IsTrue extends Condition {
143 final Reference value;
144
145 IsTrue(Definition val) : value = new Reference(val);
146
147 accept(Visitor visitor) => visitor.visitIsTrue(this);
148 }
149
150 /// Choose between a pair of continuations based on a condition value.
151 class Branch extends Expression {
152 final Condition condition;
153 final Reference trueContinuation;
154 final Reference falseContinuation;
155
156 Branch(this.condition, Continuation trueCont, Continuation falseCont)
157 : trueContinuation = new Reference(trueCont),
158 falseContinuation = new Reference(falseCont);
159
160 accept(Visitor visitor) => visitor.visitBranch(this);
125 } 161 }
126 162
127 class Constant extends Primitive { 163 class Constant extends Primitive {
128 final dart2js.Constant value; 164 final dart2js.Constant value;
129 165
130 Constant(this.value); 166 Constant(this.value);
131 167
132 accept(Visitor visitor) => visitor.visitConstant(this); 168 accept(Visitor visitor) => visitor.visitConstant(this);
133 } 169 }
134 170
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); 206 accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
171 } 207 }
172 208
173 abstract class Visitor<T> { 209 abstract class Visitor<T> {
174 T visit(Node node) => node.accept(this); 210 T visit(Node node) => node.accept(this);
175 // Abstract classes. 211 // Abstract classes.
176 T visitNode(Node node) => null; 212 T visitNode(Node node) => null;
177 T visitExpression(Expression node) => visitNode(node); 213 T visitExpression(Expression node) => visitNode(node);
178 T visitDefinition(Definition node) => visitNode(node); 214 T visitDefinition(Definition node) => visitNode(node);
179 T visitPrimitive(Primitive node) => visitDefinition(node); 215 T visitPrimitive(Primitive node) => visitDefinition(node);
216 T visitCondition(Condition node) => visitNode(node);
180 217
181 // Concrete classes. 218 // Concrete classes.
182 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); 219 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node);
183 220
221 // Expressions.
184 T visitLetPrim(LetPrim node) => visitExpression(node); 222 T visitLetPrim(LetPrim node) => visitExpression(node);
185 T visitLetCont(LetCont node) => visitExpression(node); 223 T visitLetCont(LetCont node) => visitExpression(node);
186 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); 224 T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
187 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); 225 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node);
226 T visitBranch(Branch node) => visitExpression(node);
188 227
228 // Definitions.
189 T visitConstant(Constant node) => visitPrimitive(node); 229 T visitConstant(Constant node) => visitPrimitive(node);
190 T visitParameter(Parameter node) => visitPrimitive(node); 230 T visitParameter(Parameter node) => visitPrimitive(node);
191 T visitContinuation(Continuation node) => visitDefinition(node); 231 T visitContinuation(Continuation node) => visitDefinition(node);
232
233 // Conditions.
234 T visitIsTrue(IsTrue node) => visitCondition(node);
192 } 235 }
193 236
194 /// Generate a Lisp-like S-expression representation of an IR node as a string. 237 /// Generate a Lisp-like S-expression representation of an IR node as a string.
195 /// The representation is not pretty-printed, but it can easily be quoted and 238 /// The representation is not pretty-printed, but it can easily be quoted and
196 /// dropped into the REPL of one's favorite Lisp or Scheme implementation to be 239 /// dropped into the REPL of one's favorite Lisp or Scheme implementation to be
197 /// pretty-printed. 240 /// pretty-printed.
198 class SExpressionStringifier extends Visitor<String> { 241 class SExpressionStringifier extends Visitor<String> {
199 final Map<Definition, String> names = <Definition, String>{}; 242 final Map<Definition, String> names = <Definition, String>{};
200 243
201 int _valueCounter = 0; 244 int _valueCounter = 0;
202 int _continuationCounter = 0; 245 int _continuationCounter = 0;
203 246
204 String newValueName() => 'v${_valueCounter++}'; 247 String newValueName() => 'v${_valueCounter++}';
205 String newContinuationName() => 'k${_continuationCounter++}'; 248 String newContinuationName() => 'k${_continuationCounter++}';
206 249
207 String visitFunctionDefinition(FunctionDefinition node) { 250 String visitFunctionDefinition(FunctionDefinition node) {
208 names[node.returnContinuation] = 'return'; 251 names[node.returnContinuation] = 'return';
209 String parameters = node.parameters 252 String parameters = node.parameters
210 .map((p) { 253 .map((p) {
211 String name = p.element.name; 254 String name = p.element.name;
212 names[p] = name; 255 names[p] = name;
213 return name; 256 return name;
214 }) 257 })
215 .join(' '); 258 .join(' ');
216 return '(FunctionDefinition ($parameters) ${node.body.accept(this)})'; 259 return '(FunctionDefinition ($parameters) ${visit(node.body)})';
217 } 260 }
218 261
219 String visitLetPrim(LetPrim expr) { 262 String visitLetPrim(LetPrim node) {
220 String name = newValueName(); 263 String name = newValueName();
221 names[expr.primitive] = name; 264 names[node.primitive] = name;
222 String value = expr.primitive.accept(this); 265 String value = visit(node.primitive);
223 String body = expr.body.accept(this); 266 String body = visit(node.body);
224 return '(LetPrim $name $value) $body'; 267 return '(LetPrim $name $value) $body';
225 } 268 }
226 269
227 String visitLetCont(LetCont expr) { 270 String visitLetCont(LetCont node) {
228 String cont = newContinuationName(); 271 String cont = newContinuationName();
229 names[expr.continuation] = cont; 272 names[node.continuation] = cont;
230 String parameters = expr.continuation.parameters 273 String parameters = node.continuation.parameters
231 .map((p) { 274 .map((p) {
232 String name = newValueName(); 275 String name = newValueName();
233 names[p] = name; 276 names[p] = name;
234 return name; 277 return ' $name';
235 }) 278 })
236 .join(' '); 279 .join('');
237 String contBody = expr.continuation.body.accept(this); 280 String contBody = visit(node.continuation.body);
238 String body = expr.body.accept(this); 281 String body = visit(node.body);
239 return '(LetCont ($cont $parameters) $contBody) $body'; 282 return '(LetCont ($cont$parameters) $contBody) $body';
240 } 283 }
241 284
242 String visitInvokeStatic(InvokeStatic expr) { 285 String visitInvokeStatic(InvokeStatic node) {
243 String name = expr.target.name; 286 String name = node.target.name;
244 String cont = names[expr.continuation.definition]; 287 String cont = names[node.continuation.definition];
245 String args = expr.arguments.map((v) => names[v.definition]).join(' '); 288 String args = node.arguments.map((v) => names[v.definition]).join(' ');
246 return '(InvokeStatic $name $cont $args)'; 289 return '(InvokeStatic $name $cont $args)';
247 } 290 }
248 291
249 String visitInvokeContinuation(InvokeContinuation expr) { 292 String visitInvokeContinuation(InvokeContinuation node) {
250 String cont = names[expr.continuation.definition]; 293 String cont = names[node.continuation.definition];
251 String arg = names[expr.argument.definition]; 294 String args = node.arguments.map((v) => names[v.definition]).join(' ');
252 return '(InvokeContinuation $cont $arg)'; 295 return '(InvokeContinuation $cont $args)';
253 } 296 }
254 297
255 String visitConstant(Constant triv) { 298 String visitBranch(Branch node) {
256 return '(Constant ${triv.value})'; 299 String condition = visit(node.condition);
300 String trueCont = names[node.trueContinuation.definition];
301 String falseCont = names[node.falseContinuation.definition];
302 return '(Branch $condition $trueCont $falseCont)';
257 } 303 }
258 304
259 String visitParameter(Parameter triv) { 305 String visitConstant(Constant node) {
306 return '(Constant ${node.value})';
307 }
308
309 String visitParameter(Parameter node) {
260 // Parameters are visited directly in visitLetCont. 310 // Parameters are visited directly in visitLetCont.
261 return '(Unexpected Parameter)'; 311 return '(Unexpected Parameter)';
262 } 312 }
263 313
264 String visitContinuation(Continuation triv) { 314 String visitContinuation(Continuation node) {
265 // Continuations are visited directly in visitLetCont. 315 // Continuations are visited directly in visitLetCont.
266 return '(Unexpected Continuation)'; 316 return '(Unexpected Continuation)';
267 } 317 }
318
319 String visitIsTrue(IsTrue node) {
320 String value = names[node.value.definition];
321 return '(IsTrue $value)';
322 }
268 } 323 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698