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

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

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (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 LiteralMapEntry {
227 Expression key;
228 Expression value;
229
230 LiteralMapEntry(this.key, this.value);
231 }
232
233 class LiteralMap extends Expression {
234 final GenericType type;
235 final List<LiteralMapEntry> entries;
236
237 LiteralMap(this.type, this.entries);
238
239 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this);
240 }
241
242 class TypeOperator extends Expression {
243 Expression receiver;
244 final DartType type;
245 final bool isTypeTest;
246
247 TypeOperator(this.receiver, this.type, {bool this.isTypeTest});
248
249 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
250
251 String get operator => isTypeTest ? 'is' : 'as';
252 }
253
254 /// A conditional expression.
255 class Conditional extends Expression {
256 Expression condition;
257 Expression thenExpression;
258 Expression elseExpression;
259
260 Conditional(this.condition, this.thenExpression, this.elseExpression);
261
262 accept(ExpressionVisitor visitor) => visitor.visitConditional(this);
263 }
264
265 /// An && or || expression. The operator is internally represented as a boolean
266 /// [isAnd] to simplify rewriting of logical operators.
267 class LogicalOperator extends Expression {
268 Expression left;
269 bool isAnd;
270 Expression right;
271
272 LogicalOperator(this.left, this.right, this.isAnd);
273 LogicalOperator.and(this.left, this.right) : isAnd = true;
274 LogicalOperator.or(this.left, this.right) : isAnd = false;
275
276 String get operator => isAnd ? '&&' : '||';
277
278 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this);
279 }
280
281 /// Logical negation.
282 class Not extends Expression {
283 Expression operand;
284
285 Not(this.operand);
286
287 accept(ExpressionVisitor visitor) => visitor.visitNot(this);
288 }
289
290 class FunctionExpression extends Expression {
291 final FunctionDefinition definition;
292
293 FunctionExpression(this.definition) {
294 assert(definition.element.type.returnType.treatAsDynamic);
295 }
296
297 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this);
298 }
299
300 /// Declares a local function.
301 /// Used for functions that may not occur in expression context due to
302 /// being recursive or having a return type.
303 /// The [variable] must not occur as the left-hand side of an [Assign] or
304 /// any other [FunctionDeclaration].
305 class FunctionDeclaration extends Statement {
306 Variable variable;
307 final FunctionDefinition definition;
308 Statement next;
309
310 FunctionDeclaration(this.variable, this.definition, this.next) {
311 ++variable.writeCount;
312 }
313
314 accept(StatementVisitor visitor) => visitor.visitFunctionDeclaration(this);
315 }
316
317 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition].
318 abstract class JumpTarget extends Statement {
319 Label get label;
320 Statement get body;
321 }
322
323 /**
324 * A labeled statement. Breaks to the label within the labeled statement
325 * target the successor statement.
326 */
327 class LabeledStatement extends JumpTarget {
328 Statement next;
329 final Label label;
330 Statement body;
331
332 LabeledStatement(this.label, this.body, this.next) {
333 assert(label.binding == null);
334 label.binding = this;
335 }
336
337 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this);
338 }
339
340 /// A [WhileTrue] or [WhileCondition] loop.
341 abstract class Loop extends JumpTarget {
342 }
343
344 /**
345 * A labeled while(true) loop.
346 */
347 class WhileTrue extends Loop {
348 final Label label;
349 Statement body;
350
351 WhileTrue(this.label, this.body) {
352 assert(label.binding == null);
353 label.binding = this;
354 }
355
356 Statement get next => null;
357 void set next(Statement s) => throw 'UNREACHABLE';
358
359 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this);
360 }
361
362 /**
363 * A while loop with a condition. If the condition is false, control resumes
364 * at the [next] statement.
365 *
366 * It is NOT valid to target this statement with a [Break].
367 * The only way to reach [next] is for the condition to evaluate to false.
368 *
369 * [WhileCondition] statements are introduced in the [LoopRewriter] and is
370 * assumed not to occur before then.
371 */
372 class WhileCondition extends Loop {
373 final Label label;
374 Expression condition;
375 Statement body;
376 Statement next;
377
378 WhileCondition(this.label, this.condition, this.body,
379 this.next) {
380 assert(label.binding == null);
381 label.binding = this;
382 }
383
384 accept(StatementVisitor visitor) => visitor.visitWhileCondition(this);
385 }
386
387 /// A [Break] or [Continue] statement.
388 abstract class Jump extends Statement {
389 Label get target;
390 }
391
392 /**
393 * A break from an enclosing [LabeledStatement]. The break targets the
394 * labeled statement's successor statement.
395 */
396 class Break extends Jump {
397 final Label target;
398
399 Statement get next => null;
400 void set next(Statement s) => throw 'UNREACHABLE';
401
402 Break(this.target) {
403 ++target.useCount;
404 }
405
406 accept(StatementVisitor visitor) => visitor.visitBreak(this);
407 }
408
409 /**
410 * A continue to an enclosing [WhileTrue] or [WhileCondition] loop.
411 * The continue targets the loop's body.
412 */
413 class Continue extends Jump {
414 final Label target;
415
416 Statement get next => null;
417 void set next(Statement s) => throw 'UNREACHABLE';
418
419 Continue(this.target) {
420 ++target.useCount;
421 }
422
423 accept(StatementVisitor visitor) => visitor.visitContinue(this);
424 }
425
426 /**
427 * An assignments of an [Expression] to a [Variable].
428 *
429 * In contrast to the CPS-based IR, non-primitive expressions can be assigned
430 * to variables.
431 */
432 class Assign extends Statement {
433 Statement next;
434 Variable variable;
435 Expression definition;
436
437 /// If true, this declares a new copy of the closure variable.
438 /// The consequences are similar to [cps_ir.SetClosureVariable].
439 /// All uses of the variable must be nested inside the [next] statement.
440 bool isDeclaration;
441
442 Assign(this.variable, this.definition, this.next,
443 { this.isDeclaration: false }) {
444 variable.writeCount++;
445 }
446
447 bool get hasExactlyOneUse => variable.readCount == 1;
448
449 accept(StatementVisitor visitor) => visitor.visitAssign(this);
450 }
451
452 /**
453 * A return exit from the function.
454 *
455 * In contrast to the CPS-based IR, the return value is an arbitrary
456 * expression.
457 */
458 class Return extends Statement {
459 /// Should not be null. Use [Constant] with [NullConstantValue] for void
460 /// returns.
461 Expression value;
462
463 Statement get next => null;
464 void set next(Statement s) => throw 'UNREACHABLE';
465
466 Return(this.value);
467
468 accept(StatementVisitor visitor) => visitor.visitReturn(this);
469 }
470
471 /**
472 * A conditional branch based on the true value of an [Expression].
473 */
474 class If extends Statement {
475 Expression condition;
476 Statement thenStatement;
477 Statement elseStatement;
478
479 Statement get next => null;
480 void set next(Statement s) => throw 'UNREACHABLE';
481
482 If(this.condition, this.thenStatement, this.elseStatement);
483
484 accept(StatementVisitor visitor) => visitor.visitIf(this);
485 }
486
487 class ExpressionStatement extends Statement {
488 Statement next;
489 Expression expression;
490
491 ExpressionStatement(this.expression, this.next);
492
493 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this);
494 }
495
496 class FunctionDefinition extends Node {
497 final FunctionElement element;
498 final List<Variable> parameters;
499 Statement body;
500 final List<ConstDeclaration> localConstants;
501 final List<ConstantExpression> defaultParameterValues;
502
503 FunctionDefinition(this.element, this.parameters, this.body,
504 this.localConstants, this.defaultParameterValues);
505
506 /// Returns `true` if this function is abstract.
507 ///
508 /// If `true` [body] is `null` and [localConstants] is empty.
509 bool get isAbstract => body == null;
510 }
511
512 abstract class ExpressionVisitor<E> {
513 E visitExpression(Expression e) => e.accept(this);
514 E visitVariable(Variable node);
515 E visitInvokeStatic(InvokeStatic node);
516 E visitInvokeMethod(InvokeMethod node);
517 E visitInvokeSuperMethod(InvokeSuperMethod node);
518 E visitInvokeConstructor(InvokeConstructor node);
519 E visitConcatenateStrings(ConcatenateStrings node);
520 E visitConstant(Constant node);
521 E visitThis(This node);
522 E visitReifyTypeVar(ReifyTypeVar node);
523 E visitConditional(Conditional node);
524 E visitLogicalOperator(LogicalOperator node);
525 E visitNot(Not node);
526 E visitLiteralList(LiteralList node);
527 E visitLiteralMap(LiteralMap node);
528 E visitTypeOperator(TypeOperator node);
529 E visitFunctionExpression(FunctionExpression node);
530 }
531
532 abstract class StatementVisitor<S> {
533 S visitStatement(Statement s) => s.accept(this);
534 S visitLabeledStatement(LabeledStatement node);
535 S visitAssign(Assign node);
536 S visitReturn(Return node);
537 S visitBreak(Break node);
538 S visitContinue(Continue node);
539 S visitIf(If node);
540 S visitWhileTrue(WhileTrue node);
541 S visitWhileCondition(WhileCondition node);
542 S visitFunctionDeclaration(FunctionDeclaration node);
543 S visitExpressionStatement(ExpressionStatement node);
544 }
545
546 abstract class Visitor<S,E> implements ExpressionVisitor<E>,
547 StatementVisitor<S> {
548 E visitExpression(Expression e) => e.accept(this);
549 S visitStatement(Statement s) => s.accept(this);
550 }
551
552 class RecursiveVisitor extends Visitor {
553 visitFunctionDefinition(FunctionDefinition node) {
554 visitStatement(node.body);
555 }
556
557 visitVariable(Variable node) {}
558
559 visitInvokeStatic(InvokeStatic node) {
560 node.arguments.forEach(visitExpression);
561 }
562
563 visitInvokeMethod(InvokeMethod node) {
564 visitExpression(node.receiver);
565 node.arguments.forEach(visitExpression);
566 }
567
568 visitInvokeSuperMethod(InvokeSuperMethod node) {
569 node.arguments.forEach(visitExpression);
570 }
571
572 visitInvokeConstructor(InvokeConstructor node) {
573 node.arguments.forEach(visitExpression);
574 }
575
576 visitConcatenateStrings(ConcatenateStrings node) {
577 node.arguments.forEach(visitExpression);
578 }
579
580 visitConstant(Constant node) {}
581
582 visitThis(This node) {}
583
584 visitReifyTypeVar(ReifyTypeVar node) {}
585
586 visitConditional(Conditional node) {
587 visitExpression(node.condition);
588 visitExpression(node.thenExpression);
589 visitExpression(node.elseExpression);
590 }
591
592 visitLogicalOperator(LogicalOperator node) {
593 visitExpression(node.left);
594 visitExpression(node.right);
595 }
596
597 visitNot(Not node) {
598 visitExpression(node.operand);
599 }
600
601 visitLiteralList(LiteralList node) {
602 node.values.forEach(visitExpression);
603 }
604
605 visitLiteralMap(LiteralMap node) {
606 node.entries.forEach((LiteralMapEntry entry) {
607 visitExpression(entry.key);
608 visitExpression(entry.value);
609 });
610 }
611
612 visitTypeOperator(TypeOperator node) {
613 visitExpression(node.receiver);
614 }
615
616 visitFunctionExpression(FunctionExpression node) {
617 visitFunctionDefinition(node.definition);
618 }
619
620 visitLabeledStatement(LabeledStatement node) {
621 visitStatement(node.body);
622 visitStatement(node.next);
623 }
624
625 visitAssign(Assign node) {
626 visitExpression(node.definition);
627 visitVariable(node.variable);
628 visitStatement(node.next);
629 }
630
631 visitReturn(Return node) {
632 visitExpression(node.value);
633 }
634
635 visitBreak(Break node) {}
636
637 visitContinue(Continue node) {}
638
639 visitIf(If node) {
640 visitExpression(node.condition);
641 visitStatement(node.thenStatement);
642 visitStatement(node.elseStatement);
643 }
644
645 visitWhileTrue(WhileTrue node) {
646 visitStatement(node.body);
647 }
648
649 visitWhileCondition(WhileCondition node) {
650 visitExpression(node.condition);
651 visitStatement(node.body);
652 visitStatement(node.next);
653 }
654
655 visitFunctionDeclaration(FunctionDeclaration node) {
656 visitFunctionDefinition(node.definition);
657 visitStatement(node.next);
658 }
659
660 visitExpressionStatement(ExpressionStatement node) {
661 visitExpression(node.expression);
662 visitStatement(node.next);
663 }
664 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698