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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_nodes.dart

Issue 692513002: Remove old dart2js code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library tree_ir_nodes;
6
7 import '../constants/expressions.dart';
8 import '../constants/values.dart' as values;
9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
10 import '../dart_types.dart' show DartType, GenericType;
11 import '../elements/elements.dart';
12 import '../universe/universe.dart';
13 import '../universe/universe.dart' show Selector;
14
15
16 // The Tree language is the target of translation out of the CPS-based IR.
17 //
18 // The translation from CPS to Dart consists of several stages. Among the
19 // stages are translation to direct style, translation out of SSA, eliminating
20 // unnecessary names, recognizing high-level control constructs. Combining
21 // these separate concerns is complicated and the constraints of the CPS-based
22 // language do not permit a multi-stage translation.
23 //
24 // For that reason, CPS is translated to the direct-style language Tree.
25 // Translation out of SSA, unnaming, and control-flow, as well as 'instruction
26 // selection' are performed on the Tree language.
27 //
28 // In contrast to the CPS-based IR, non-primitive expressions can be named and
29 // arguments (to calls, primitives, and blocks) can be arbitrary expressions.
30 //
31 // Additionally, variables are considered in scope within inner functions;
32 // closure variables are thus handled directly instead of using ref cells.
33
34 /**
35 * The base class of all Tree nodes.
36 */
37 abstract class Node {
38 }
39
40 /**
41 * The base class of [Expression]s.
42 */
43 abstract class Expression extends Node {
44 accept(ExpressionVisitor v);
45
46 /// Temporary variable used by [StatementRewriter].
47 /// If set to true, this expression has already had enclosing assignments
48 /// propagated into its variables, and should not be processed again.
49 /// It is only set for expressions that are known to be in risk of redundant
50 /// processing.
51 bool processed = false;
52 }
53
54 abstract class Statement extends Node {
55 Statement get next;
56 void set next(Statement s);
57 accept(StatementVisitor v);
58 }
59
60 /**
61 * Labels name [LabeledStatement]s.
62 */
63 class Label {
64 // A counter used to generate names. The counter is reset to 0 for each
65 // function emitted.
66 static int counter = 0;
67 static String _newName() => 'L${counter++}';
68
69 String cachedName;
70
71 String get name {
72 if (cachedName == null) cachedName = _newName();
73 return cachedName;
74 }
75
76 /// Number of [Break] or [Continue] statements that target this label.
77 /// The [Break] constructor will increment this automatically, but the
78 /// counter must be decremented by hand when a [Break] becomes orphaned.
79 int useCount = 0;
80
81 /// The [LabeledStatement] or [WhileTrue] binding this label.
82 JumpTarget binding;
83 }
84
85 /**
86 * Variables are [Expression]s.
87 */
88 class Variable extends Expression {
89 /// Function that declares this variable.
90 FunctionDefinition host;
91
92 /// [Entity] used for synthesizing a name for the variable.
93 /// Different variables may have the same entity. May be null.
94 Entity element;
95
96 int readCount = 0;
97
98 /// Number of places where this variable occurs as:
99 /// - left-hand of an [Assign]
100 /// - left-hand of a [FunctionDeclaration]
101 /// - parameter in a [FunctionDefinition]
102 int writeCount = 0;
103
104 Variable(this.host, this.element) {
105 assert(host != null);
106 }
107
108 accept(ExpressionVisitor visitor) => visitor.visitVariable(this);
109 }
110
111 /**
112 * Common interface for invocations with arguments.
113 */
114 abstract class Invoke {
115 List<Expression> get arguments;
116 Selector get selector;
117 }
118
119 /**
120 * A call to a static function or getter/setter to a static field.
121 *
122 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions.
123 */
124 class InvokeStatic extends Expression implements Invoke {
125 final Entity target;
126 final List<Expression> arguments;
127 final Selector selector;
128
129 InvokeStatic(this.target, this.selector, this.arguments);
130
131 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this);
132 }
133
134 /**
135 * A call to a method, operator, getter, setter or index getter/setter.
136 *
137 * In contrast to the CPS-based IR, the receiver and arguments can be
138 * arbitrary expressions.
139 */
140 class InvokeMethod extends Expression implements Invoke {
141 Expression receiver;
142 final Selector selector;
143 final List<Expression> arguments;
144
145 InvokeMethod(this.receiver, this.selector, this.arguments) {
146 assert(receiver != null);
147 }
148
149 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this);
150 }
151
152 class InvokeSuperMethod extends Expression implements Invoke {
153 final Selector selector;
154 final List<Expression> arguments;
155
156 InvokeSuperMethod(this.selector, this.arguments) ;
157
158 accept(ExpressionVisitor visitor) => visitor.visitInvokeSuperMethod(this);
159 }
160
161 /**
162 * Call to a factory or generative constructor.
163 */
164 class InvokeConstructor extends Expression implements Invoke {
165 final DartType type;
166 final FunctionElement target;
167 final List<Expression> arguments;
168 final Selector selector;
169 final values.ConstantValue constant;
170
171 InvokeConstructor(this.type, this.target, this.selector, this.arguments,
172 [this.constant]);
173
174 ClassElement get targetClass => target.enclosingElement;
175
176 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstructor(this);
177 }
178
179 /// Calls [toString] on each argument and concatenates the results.
180 class ConcatenateStrings extends Expression {
181 final List<Expression> arguments;
182 final values.ConstantValue constant;
183
184 ConcatenateStrings(this.arguments, [this.constant]);
185
186 accept(ExpressionVisitor visitor) => visitor.visitConcatenateStrings(this);
187 }
188
189 /**
190 * A constant.
191 */
192 class Constant extends Expression {
193 final ConstantExpression expression;
194
195 Constant(this.expression);
196
197 Constant.primitive(values.PrimitiveConstantValue primitiveValue)
198 : expression = new PrimitiveConstantExpression(primitiveValue);
199
200 accept(ExpressionVisitor visitor) => visitor.visitConstant(this);
201
202 values.ConstantValue get value => expression.value;
203 }
204
205 class This extends Expression {
206 accept(ExpressionVisitor visitor) => visitor.visitThis(this);
207 }
208
209 class ReifyTypeVar extends Expression {
210 TypeVariableElement typeVariable;
211
212 ReifyTypeVar(this.typeVariable);
213
214 accept(ExpressionVisitor visitor) => visitor.visitReifyTypeVar(this);
215 }
216
217 class LiteralList extends Expression {
218 final GenericType type;
219 final List<Expression> values;
220
221 LiteralList(this.type, this.values);
222
223 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this);
224 }
225
226 class LiteralMap extends Expression {
227 final GenericType type;
228 final List<Expression> keys;
229 final List<Expression> values;
230
231 LiteralMap(this.type, this.keys, this.values);
232
233 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this);
234 }
235
236 class TypeOperator extends Expression {
237 Expression receiver;
238 final DartType type;
239 final String operator;
240
241 TypeOperator(this.receiver, this.type, this.operator) ;
242
243 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
244 }
245
246 /// A conditional expression.
247 class Conditional extends Expression {
248 Expression condition;
249 Expression thenExpression;
250 Expression elseExpression;
251
252 Conditional(this.condition, this.thenExpression, this.elseExpression);
253
254 accept(ExpressionVisitor visitor) => visitor.visitConditional(this);
255 }
256
257 /// An && or || expression. The operator is internally represented as a boolean
258 /// [isAnd] to simplify rewriting of logical operators.
259 class LogicalOperator extends Expression {
260 Expression left;
261 bool isAnd;
262 Expression right;
263
264 LogicalOperator(this.left, this.right, this.isAnd);
265 LogicalOperator.and(this.left, this.right) : isAnd = true;
266 LogicalOperator.or(this.left, this.right) : isAnd = false;
267
268 String get operator => isAnd ? '&&' : '||';
269
270 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this);
271 }
272
273 /// Logical negation.
274 class Not extends Expression {
275 Expression operand;
276
277 Not(this.operand);
278
279 accept(ExpressionVisitor visitor) => visitor.visitNot(this);
280 }
281
282 class FunctionExpression extends Expression {
283 final FunctionDefinition definition;
284
285 FunctionExpression(this.definition) {
286 assert(definition.element.type.returnType.treatAsDynamic);
287 }
288
289 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this);
290 }
291
292 /// Declares a local function.
293 /// Used for functions that may not occur in expression context due to
294 /// being recursive or having a return type.
295 /// The [variable] must not occur as the left-hand side of an [Assign] or
296 /// any other [FunctionDeclaration].
297 class FunctionDeclaration extends Statement {
298 Variable variable;
299 final FunctionDefinition definition;
300 Statement next;
301
302 FunctionDeclaration(this.variable, this.definition, this.next) {
303 ++variable.writeCount;
304 }
305
306 accept(StatementVisitor visitor) => visitor.visitFunctionDeclaration(this);
307 }
308
309 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition].
310 abstract class JumpTarget extends Statement {
311 Label get label;
312 Statement get body;
313 }
314
315 /**
316 * A labeled statement. Breaks to the label within the labeled statement
317 * target the successor statement.
318 */
319 class LabeledStatement extends JumpTarget {
320 Statement next;
321 final Label label;
322 Statement body;
323
324 LabeledStatement(this.label, this.body, this.next) {
325 assert(label.binding == null);
326 label.binding = this;
327 }
328
329 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this);
330 }
331
332 /// A [WhileTrue] or [WhileCondition] loop.
333 abstract class Loop extends JumpTarget {
334 }
335
336 /**
337 * A labeled while(true) loop.
338 */
339 class WhileTrue extends Loop {
340 final Label label;
341 Statement body;
342
343 WhileTrue(this.label, this.body) {
344 assert(label.binding == null);
345 label.binding = this;
346 }
347
348 Statement get next => null;
349 void set next(Statement s) => throw 'UNREACHABLE';
350
351 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this);
352 }
353
354 /**
355 * A while loop with a condition. If the condition is false, control resumes
356 * at the [next] statement.
357 *
358 * It is NOT valid to target this statement with a [Break].
359 * The only way to reach [next] is for the condition to evaluate to false.
360 *
361 * [WhileCondition] statements are introduced in the [LoopRewriter] and is
362 * assumed not to occur before then.
363 */
364 class WhileCondition extends Loop {
365 final Label label;
366 Expression condition;
367 Statement body;
368 Statement next;
369
370 WhileCondition(this.label, this.condition, this.body,
371 this.next) {
372 assert(label.binding == null);
373 label.binding = this;
374 }
375
376 accept(StatementVisitor visitor) => visitor.visitWhileCondition(this);
377 }
378
379 /// A [Break] or [Continue] statement.
380 abstract class Jump extends Statement {
381 Label get target;
382 }
383
384 /**
385 * A break from an enclosing [LabeledStatement]. The break targets the
386 * labeled statement's successor statement.
387 */
388 class Break extends Jump {
389 final Label target;
390
391 Statement get next => null;
392 void set next(Statement s) => throw 'UNREACHABLE';
393
394 Break(this.target) {
395 ++target.useCount;
396 }
397
398 accept(StatementVisitor visitor) => visitor.visitBreak(this);
399 }
400
401 /**
402 * A continue to an enclosing [WhileTrue] or [WhileCondition] loop.
403 * The continue targets the loop's body.
404 */
405 class Continue extends Jump {
406 final Label target;
407
408 Statement get next => null;
409 void set next(Statement s) => throw 'UNREACHABLE';
410
411 Continue(this.target) {
412 ++target.useCount;
413 }
414
415 accept(StatementVisitor visitor) => visitor.visitContinue(this);
416 }
417
418 /**
419 * An assignments of an [Expression] to a [Variable].
420 *
421 * In contrast to the CPS-based IR, non-primitive expressions can be assigned
422 * to variables.
423 */
424 class Assign extends Statement {
425 Statement next;
426 Variable variable;
427 Expression definition;
428
429 /// If true, this declares a new copy of the closure variable.
430 /// The consequences are similar to [cps_ir.SetClosureVariable].
431 /// All uses of the variable must be nested inside the [next] statement.
432 bool isDeclaration;
433
434 Assign(this.variable, this.definition, this.next,
435 { this.isDeclaration: false }) {
436 variable.writeCount++;
437 }
438
439 bool get hasExactlyOneUse => variable.readCount == 1;
440
441 accept(StatementVisitor visitor) => visitor.visitAssign(this);
442 }
443
444 /**
445 * A return exit from the function.
446 *
447 * In contrast to the CPS-based IR, the return value is an arbitrary
448 * expression.
449 */
450 class Return extends Statement {
451 /// Should not be null. Use [Constant] with [NullConstantValue] for void
452 /// returns.
453 Expression value;
454
455 Statement get next => null;
456 void set next(Statement s) => throw 'UNREACHABLE';
457
458 Return(this.value);
459
460 accept(StatementVisitor visitor) => visitor.visitReturn(this);
461 }
462
463 /**
464 * A conditional branch based on the true value of an [Expression].
465 */
466 class If extends Statement {
467 Expression condition;
468 Statement thenStatement;
469 Statement elseStatement;
470
471 Statement get next => null;
472 void set next(Statement s) => throw 'UNREACHABLE';
473
474 If(this.condition, this.thenStatement, this.elseStatement);
475
476 accept(StatementVisitor visitor) => visitor.visitIf(this);
477 }
478
479 class ExpressionStatement extends Statement {
480 Statement next;
481 Expression expression;
482
483 ExpressionStatement(this.expression, this.next);
484
485 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this);
486 }
487
488 class FunctionDefinition extends Node {
489 final FunctionElement element;
490 final List<Variable> parameters;
491 Statement body;
492 final List<ConstDeclaration> localConstants;
493 final List<ConstantExpression> defaultParameterValues;
494
495 FunctionDefinition(this.element, this.parameters, this.body,
496 this.localConstants, this.defaultParameterValues);
497
498 /// Returns `true` if this function is abstract.
499 ///
500 /// If `true` [body] is `null` and [localConstants] is empty.
501 bool get isAbstract => body == null;
502 }
503
504 abstract class ExpressionVisitor<E> {
505 E visitExpression(Expression e) => e.accept(this);
506 E visitVariable(Variable node);
507 E visitInvokeStatic(InvokeStatic node);
508 E visitInvokeMethod(InvokeMethod node);
509 E visitInvokeSuperMethod(InvokeSuperMethod node);
510 E visitInvokeConstructor(InvokeConstructor node);
511 E visitConcatenateStrings(ConcatenateStrings node);
512 E visitConstant(Constant node);
513 E visitThis(This node);
514 E visitReifyTypeVar(ReifyTypeVar node);
515 E visitConditional(Conditional node);
516 E visitLogicalOperator(LogicalOperator node);
517 E visitNot(Not node);
518 E visitLiteralList(LiteralList node);
519 E visitLiteralMap(LiteralMap node);
520 E visitTypeOperator(TypeOperator node);
521 E visitFunctionExpression(FunctionExpression node);
522 }
523
524 abstract class StatementVisitor<S> {
525 S visitStatement(Statement s) => s.accept(this);
526 S visitLabeledStatement(LabeledStatement node);
527 S visitAssign(Assign node);
528 S visitReturn(Return node);
529 S visitBreak(Break node);
530 S visitContinue(Continue node);
531 S visitIf(If node);
532 S visitWhileTrue(WhileTrue node);
533 S visitWhileCondition(WhileCondition node);
534 S visitFunctionDeclaration(FunctionDeclaration node);
535 S visitExpressionStatement(ExpressionStatement node);
536 }
537
538 abstract class Visitor<S,E> implements ExpressionVisitor<E>,
539 StatementVisitor<S> {
540 E visitExpression(Expression e) => e.accept(this);
541 S visitStatement(Statement s) => s.accept(this);
542 }
543
544 class RecursiveVisitor extends Visitor {
545 visitFunctionDefinition(FunctionDefinition node) {
546 visitStatement(node.body);
547 }
548
549 visitVariable(Variable node) {}
550
551 visitInvokeStatic(InvokeStatic node) {
552 node.arguments.forEach(visitExpression);
553 }
554
555 visitInvokeMethod(InvokeMethod node) {
556 visitExpression(node.receiver);
557 node.arguments.forEach(visitExpression);
558 }
559
560 visitInvokeSuperMethod(InvokeSuperMethod node) {
561 node.arguments.forEach(visitExpression);
562 }
563
564 visitInvokeConstructor(InvokeConstructor node) {
565 node.arguments.forEach(visitExpression);
566 }
567
568 visitConcatenateStrings(ConcatenateStrings node) {
569 node.arguments.forEach(visitExpression);
570 }
571
572 visitConstant(Constant node) {}
573
574 visitThis(This node) {}
575
576 visitReifyTypeVar(ReifyTypeVar node) {}
577
578 visitConditional(Conditional node) {
579 visitExpression(node.condition);
580 visitExpression(node.thenExpression);
581 visitExpression(node.elseExpression);
582 }
583
584 visitLogicalOperator(LogicalOperator node) {
585 visitExpression(node.left);
586 visitExpression(node.right);
587 }
588
589 visitNot(Not node) {
590 visitExpression(node.operand);
591 }
592
593 visitLiteralList(LiteralList node) {
594 node.values.forEach(visitExpression);
595 }
596
597 visitLiteralMap(LiteralMap node) {
598 for (int i=0; i<node.keys.length; i++) {
599 visitExpression(node.keys[i]);
600 visitExpression(node.values[i]);
601 }
602 }
603
604 visitTypeOperator(TypeOperator node) {
605 visitExpression(node.receiver);
606 }
607
608 visitFunctionExpression(FunctionExpression node) {
609 visitFunctionDefinition(node.definition);
610 }
611
612 visitLabeledStatement(LabeledStatement node) {
613 visitStatement(node.body);
614 visitStatement(node.next);
615 }
616
617 visitAssign(Assign node) {
618 visitExpression(node.definition);
619 visitVariable(node.variable);
620 visitStatement(node.next);
621 }
622
623 visitReturn(Return node) {
624 visitExpression(node.value);
625 }
626
627 visitBreak(Break node) {}
628
629 visitContinue(Continue node) {}
630
631 visitIf(If node) {
632 visitExpression(node.condition);
633 visitStatement(node.thenStatement);
634 visitStatement(node.elseStatement);
635 }
636
637 visitWhileTrue(WhileTrue node) {
638 visitStatement(node.body);
639 }
640
641 visitWhileCondition(WhileCondition node) {
642 visitExpression(node.condition);
643 visitStatement(node.body);
644 visitStatement(node.next);
645 }
646
647 visitFunctionDeclaration(FunctionDeclaration node) {
648 visitFunctionDefinition(node.definition);
649 visitStatement(node.next);
650 }
651
652 visitExpressionStatement(ExpressionStatement node) {
653 visitExpression(node.expression);
654 visitStatement(node.next);
655 }
656 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698