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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart

Issue 1155463005: dart2js cps: Remove dart2dart from cps pipeline and clean up. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 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
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
5 // IrNodes are kept in a separate library to have precise control over their
6 // dependencies on other parts of the system.
7 library dart2js.ir_nodes; 4 library dart2js.ir_nodes;
8 5
9 import '../constants/expressions.dart'; 6 import '../constants/expressions.dart';
10 import '../constants/values.dart' as values show ConstantValue; 7 import '../constants/values.dart' as values show ConstantValue;
11 import '../dart_types.dart' show DartType, GenericType, TypeVariableType; 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
12 import '../dart2jslib.dart' as dart2js show
13 CURRENT_ELEMENT_SPANNABLE,
14 InternalErrorFunction,
15 invariant;
16 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
17 import '../io/source_information.dart' show SourceInformation; 10 import '../io/source_information.dart' show SourceInformation;
18 import '../universe/universe.dart' show Selector, SelectorKind; 11 import '../universe/universe.dart' show Selector, SelectorKind;
19 12
20 abstract class Node { 13 abstract class Node {
21 /// A pointer to the parent node. Is null until set by optimization passes. 14 /// A pointer to the parent node. Is null until set by optimization passes.
22 Node parent; 15 Node parent;
23 16
24 accept(Visitor visitor); 17 accept(Visitor visitor);
25 } 18 }
26 19
20 /// Expressions can be evaluated, and may diverge, throw, and/or have
21 /// side-effects.
22 ///
23 /// Evaluation continues by stepping into a sub-expression, invoking a
24 /// continuation, or throwing an exception.
25 ///
26 /// Expressions do not a return value. Expressions that produce values should
27 /// invoke a [Continuation] with the result as argument. Alternatively, values
28 /// that can be obtained without side-effects, divergence, or throwing
29 /// exceptions can be built using a [LetPrim].
27 abstract class Expression extends Node { 30 abstract class Expression extends Node {
28 Expression plug(Expression expr) => throw 'impossible'; 31 Expression plug(Expression expr) => throw 'impossible';
29 } 32 }
30 33
31 /// The base class of things that variables can refer to: primitives, 34 /// The base class of things that variables can refer to: primitives,
32 /// continuations, function and continuation parameters, etc. 35 /// continuations, function and continuation parameters, etc.
33 abstract class Definition<T extends Definition<T>> extends Node { 36 abstract class Definition<T extends Definition<T>> extends Node {
34 // The head of a linked-list of occurrences, in no particular order. 37 // The head of a linked-list of occurrences, in no particular order.
35 Reference<T> firstRef; 38 Reference<T> firstRef;
36 39
(...skipping 15 matching lines...) Expand all
52 previous.next = firstRef; 55 previous.next = firstRef;
53 if (firstRef != null) firstRef.previous = previous; 56 if (firstRef != null) firstRef.previous = previous;
54 firstRef = other.firstRef; 57 firstRef = other.firstRef;
55 other.firstRef = null; 58 other.firstRef = null;
56 } 59 }
57 } 60 }
58 61
59 /// An expression that cannot throw or diverge and has no side-effects. 62 /// An expression that cannot throw or diverge and has no side-effects.
60 /// All primitives are named using the identity of the [Primitive] object. 63 /// All primitives are named using the identity of the [Primitive] object.
61 /// 64 ///
62 /// Primitives may allocate objects, this is not considered side-effect here. 65 /// Primitives may allocate objects; this is not considered side-effect here.
63 /// 66 ///
64 /// Although primitives may not mutate state, they may depend on state. 67 /// Although primitives may not mutate state, they may depend on state.
68 ///
69 /// All primitives except [Parameter] must be bound by a [LetPrim].
65 abstract class Primitive extends Definition<Primitive> { 70 abstract class Primitive extends Definition<Primitive> {
66 /// The [VariableElement] or [ParameterElement] from which the primitive 71 /// The [VariableElement] or [ParameterElement] from which the primitive
67 /// binding originated. 72 /// binding originated.
68 Entity hint; 73 Entity hint;
69 74
70 /// Use the given element as a hint for naming this primitive. 75 /// Use the given element as a hint for naming this primitive.
71 /// 76 ///
72 /// Has no effect if this primitive already has a non-null [element]. 77 /// Has no effect if this primitive already has a non-null [element].
73 void useElementAsHint(Entity hint) { 78 void useElementAsHint(Entity hint) {
74 if (this.hint == null) { 79 if (this.hint == null) {
(...skipping 23 matching lines...) Expand all
98 if (previous == null) { 103 if (previous == null) {
99 assert(definition.firstRef == this); 104 assert(definition.firstRef == this);
100 definition.firstRef = next; 105 definition.firstRef = next;
101 } else { 106 } else {
102 previous.next = next; 107 previous.next = next;
103 } 108 }
104 if (next != null) next.previous = previous; 109 if (next != null) next.previous = previous;
105 } 110 }
106 } 111 }
107 112
108 /// Binding a value (primitive or constant): 'let val x = V in E'. The bound 113 /// Evaluates a primitive and binds it to variable: `let val x = V in E`.
109 /// value is in scope in the body. 114 ///
110 /// During one-pass construction a LetVal with an empty body is used to 115 /// The bound value is in scope in the body.
111 /// represent the one-hole context 'let val x = V in []'. 116 ///
117 /// During one-pass construction a LetPrim with an empty body is used to
118 /// represent the one-hole context `let val x = V in []`.
112 class LetPrim extends Expression implements InteriorNode { 119 class LetPrim extends Expression implements InteriorNode {
113 final Primitive primitive; 120 final Primitive primitive;
114 Expression body; 121 Expression body;
115 122
116 LetPrim(this.primitive, [this.body = null]); 123 LetPrim(this.primitive, [this.body = null]);
117 124
118 Expression plug(Expression expr) { 125 Expression plug(Expression expr) {
119 assert(body == null); 126 assert(body == null);
120 return body = expr; 127 return body = expr;
121 } 128 }
122 129
123 accept(Visitor visitor) => visitor.visitLetPrim(this); 130 accept(Visitor visitor) => visitor.visitLetPrim(this);
124 } 131 }
125 132
126 133
127 /// Binding continuations. 134 /// Binding continuations.
128 /// 135 ///
129 /// let cont k0(v0 ...) = E0 136 /// let cont k0(v0 ...) = E0
130 /// k1(v1 ...) = E1 137 /// k1(v1 ...) = E1
131 /// ... 138 /// ...
132 /// in E 139 /// in E
133 /// 140 ///
134 /// The bound continuations are in scope in the body and the continuation 141 /// The bound continuations are in scope in the body and the continuation
135 /// parameters are in scope in the respective continuation bodies. 142 /// parameters are in scope in the respective continuation bodies.
143 ///
136 /// During one-pass construction a LetCont whose first continuation has an empty 144 /// During one-pass construction a LetCont whose first continuation has an empty
137 /// body is used to represent the one-hole context 145 /// body is used to represent the one-hole context
138 /// 'let cont ... k(v) = [] ... in E'. 146 /// `let cont ... k(v) = [] ... in E`.
139 class LetCont extends Expression implements InteriorNode { 147 class LetCont extends Expression implements InteriorNode {
140 List<Continuation> continuations; 148 List<Continuation> continuations;
141 Expression body; 149 Expression body;
142 150
143 LetCont(Continuation continuation, this.body) 151 LetCont(Continuation continuation, this.body)
144 : continuations = <Continuation>[continuation]; 152 : continuations = <Continuation>[continuation];
145 153
146 LetCont.many(this.continuations, this.body); 154 LetCont.many(this.continuations, this.body);
147 155
148 Expression plug(Expression expr) { 156 Expression plug(Expression expr) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 /// Node child = node.body; 216 /// Node child = node.body;
209 /// InteriorNode parent = node.parent; 217 /// InteriorNode parent = node.parent;
210 /// 218 ///
211 /// child.parent = parent; 219 /// child.parent = parent;
212 /// parent.body = child; 220 /// parent.body = child;
213 abstract class InteriorNode extends Node { 221 abstract class InteriorNode extends Node {
214 Expression get body; 222 Expression get body;
215 void set body(Expression body); 223 void set body(Expression body);
216 } 224 }
217 225
218 /// Invoke a static function or static getter/setter. 226 /// Invoke a static function.
227 ///
228 /// All optional arguments declared by [target] are passed in explicitly, and
229 /// occur at the end of [arguments] list, in normalized order.
230 ///
231 /// Discussion:
232 /// All information in the [selector] is technically redundant; it will likely
233 /// be removed.
219 class InvokeStatic extends Expression implements Invoke { 234 class InvokeStatic extends Expression implements Invoke {
220 /// [FunctionElement] or [FieldElement]. 235 final FunctionElement target;
221 final Entity target;
222
223 /**
224 * The selector encodes how the function is invoked: number of positional
225 * arguments, names used in named arguments. This information is required
226 * to build the [StaticCallSiteTypeInformation] for the inference graph.
227 */
228 final Selector selector; 236 final Selector selector;
229
230 final List<Reference<Primitive>> arguments; 237 final List<Reference<Primitive>> arguments;
231 final Reference<Continuation> continuation; 238 final Reference<Continuation> continuation;
232 final SourceInformation sourceInformation; 239 final SourceInformation sourceInformation;
233 240
234 InvokeStatic(this.target, 241 InvokeStatic(this.target,
235 this.selector, 242 this.selector,
236 List<Primitive> args, 243 List<Primitive> args,
237 Continuation cont, 244 Continuation cont,
238 this.sourceInformation) 245 this.sourceInformation)
239 : arguments = _referenceList(args), 246 : arguments = _referenceList(args),
240 continuation = new Reference<Continuation>(cont) { 247 continuation = new Reference<Continuation>(cont);
241 assert(target is ErroneousElement || selector.name == target.name);
242 }
243 248
244 accept(Visitor visitor) => visitor.visitInvokeStatic(this); 249 accept(Visitor visitor) => visitor.visitInvokeStatic(this);
245 } 250 }
246 251
247 /// A [CallingConvention] codifies how arguments are matched to parameters when 252 /// Invoke a method on an object.
248 /// emitting code for a function call. 253 ///
249 class CallingConvention { 254 /// This includes getters, setters, operators, and index getter/setters.
250 final String name; 255 ///
251 const CallingConvention(this.name); 256 /// Tearing off a method is treated like a getter invocation (getters and
252 /// The normal way of calling a Dart function: Positional arguments are 257 /// tear-offs cannot be distinguished at compile-time).
253 /// matched with (mandatory and optional) positionals parameters from left to 258 ///
254 /// right and named arguments are matched by name. 259 /// The [selector] records the names of named arguments. The value of named
255 static const CallingConvention DART = const CallingConvention("Dart call"); 260 /// arguments occur at the end of the [arguments] list, in normalized order.
256 /// Intercepted calls have an additional first argument that is the actual 261 ///
257 /// receiver of the call. See the documentation of [Interceptor] for more 262 /// Discussion:
258 /// information. 263 /// If the [selector] is a [TypedSelector], the type information contained
259 static const CallingConvention JS_INTERCEPTED = 264 /// there is used by optimization passes. This is likely to change.
260 const CallingConvention("intercepted JavaScript call");
261 }
262
263 /// Invoke a method, operator, getter, setter, or index getter/setter.
264 /// Converting a method to a function object is treated as a getter invocation.
265 class InvokeMethod extends Expression implements Invoke { 265 class InvokeMethod extends Expression implements Invoke {
266 Reference<Primitive> receiver; 266 Reference<Primitive> receiver;
267 Selector selector; 267 Selector selector;
268 CallingConvention callingConvention;
269 final List<Reference<Primitive>> arguments; 268 final List<Reference<Primitive>> arguments;
270 final Reference<Continuation> continuation; 269 final Reference<Continuation> continuation;
271 final SourceInformation sourceInformation; 270 final SourceInformation sourceInformation;
272 271
273 InvokeMethod(Primitive receiver, 272 InvokeMethod(Primitive receiver,
274 Selector selector, 273 this.selector,
275 List<Primitive> arguments, 274 List<Primitive> arguments,
276 Continuation continuation, 275 Continuation continuation,
277 {SourceInformation sourceInformation}) 276 {this.sourceInformation})
278 : this.internal(new Reference<Primitive>(receiver), 277 : this.receiver = new Reference<Primitive>(receiver),
279 selector, 278 this.arguments = _referenceList(arguments),
280 _referenceList(arguments), 279 this.continuation = new Reference<Continuation>(continuation);
281 new Reference<Continuation>(continuation),
282 sourceInformation);
283
284 InvokeMethod.internal(this.receiver,
285 this.selector,
286 this.arguments,
287 this.continuation,
288 this.sourceInformation,
289 [this.callingConvention = CallingConvention.DART]) {
290 assert(isValid);
291 }
292
293 /// Returns whether the arguments match the selector under the given calling
294 /// convention.
295 ///
296 /// This check is designed to be used in an assert, as it also checks that the
297 /// selector, arguments, and calling convention have meaningful values.
298 bool get isValid {
299 if (selector == null || callingConvention == null) return false;
300 if (callingConvention != CallingConvention.DART &&
301 callingConvention != CallingConvention.JS_INTERCEPTED) {
302 return false;
303 }
304 int numberOfArguments =
305 callingConvention == CallingConvention.JS_INTERCEPTED
306 ? arguments.length - 1
307 : arguments.length;
308 return selector.kind == SelectorKind.CALL ||
309 selector.kind == SelectorKind.OPERATOR ||
310 (selector.kind == SelectorKind.GETTER && numberOfArguments == 0) ||
311 (selector.kind == SelectorKind.SETTER && numberOfArguments == 1) ||
312 (selector.kind == SelectorKind.INDEX && numberOfArguments == 1) ||
313 (selector.kind == SelectorKind.INDEX && numberOfArguments == 2);
314 }
315 280
316 accept(Visitor visitor) => visitor.visitInvokeMethod(this); 281 accept(Visitor visitor) => visitor.visitInvokeMethod(this);
317 } 282 }
318 283
319 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. 284 /// Invoke [target] on [receiver], bypassing dispatch and override semantics.
320 /// 285 ///
321 /// That is, if [receiver] is an instance of a class that overrides [target] 286 /// That is, if [receiver] is an instance of a class that overrides [target]
322 /// with a different implementation, the overriding implementation is bypassed 287 /// with a different implementation, the overriding implementation is bypassed
323 /// and [target]'s implementation is invoked. 288 /// and [target]'s implementation is invoked.
324 /// 289 ///
325 /// As with [InvokeMethod], this can be used to invoke a method, operator, 290 /// As with [InvokeMethod], this can be used to invoke a method, operator,
326 /// getter, setter, or index getter/setter. 291 /// getter, setter, or index getter/setter.
327 /// 292 ///
328 /// If it is known that [target] does not use its receiver argument, then 293 /// If it is known that [target] does not use its receiver argument, then
329 /// [receiver] may refer to a null constant primitive. This happens for direct 294 /// [receiver] may refer to a null constant primitive. This happens for direct
330 /// invocations to intercepted methods, where the effective receiver is instead 295 /// invocations to intercepted methods, where the effective receiver is instead
331 /// passed as a formal parameter. 296 /// passed as a formal parameter.
332 /// 297 ///
333 /// TODO(sra): Review. A direct call to a method that is mixed into a native 298 /// TODO(sra): Review. A direct call to a method that is mixed into a native
334 /// class will still require an explicit argument. 299 /// class will still require an explicit argument.
335 /// 300 ///
336 /// When targeting Dart, this instruction is used to represent super calls. 301 /// All optional arguments declared by [target] are passed in explicitly, and
337 /// Here, [receiver] must always be a reference to `this`, and [target] must be 302 /// occur at the end of [arguments] list, in normalized order.
338 /// a method that is available in the super class.
339 class InvokeMethodDirectly extends Expression implements Invoke { 303 class InvokeMethodDirectly extends Expression implements Invoke {
340 Reference<Primitive> receiver; 304 Reference<Primitive> receiver;
341 final Element target; 305 final FunctionElement target;
342 final Selector selector; 306 final Selector selector;
343 final List<Reference<Primitive>> arguments; 307 final List<Reference<Primitive>> arguments;
344 final Reference<Continuation> continuation; 308 final Reference<Continuation> continuation;
345 309
346 InvokeMethodDirectly(Primitive receiver, 310 InvokeMethodDirectly(Primitive receiver,
347 this.target, 311 this.target,
348 this.selector, 312 this.selector,
349 List<Primitive> args, 313 List<Primitive> arguments,
350 Continuation cont) 314 Continuation continuation)
351 : this.receiver = new Reference<Primitive>(receiver), 315 : this.receiver = new Reference<Primitive>(receiver),
352 arguments = _referenceList(args), 316 this.arguments = _referenceList(arguments),
353 continuation = new Reference<Continuation>(cont) { 317 this.continuation = new Reference<Continuation>(continuation);
354 assert(selector != null);
355 assert(selector.kind == SelectorKind.CALL ||
356 selector.kind == SelectorKind.OPERATOR ||
357 (selector.kind == SelectorKind.GETTER && arguments.isEmpty) ||
358 (selector.kind == SelectorKind.SETTER && arguments.length == 1) ||
359 (selector.kind == SelectorKind.INDEX && arguments.length == 1) ||
360 (selector.kind == SelectorKind.INDEX && arguments.length == 2));
361 }
362 318
363 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); 319 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this);
364 } 320 }
365 321
366 /// Non-const call to a constructor. The [target] may be a generative 322 /// Non-const call to a constructor.
367 /// constructor, factory, or redirecting factory. 323 ///
324 /// The [target] may be a generative constructor (forwarding or normal)
325 /// or a non-redirecting factory.
326 ///
327 /// All optional arguments declared by [target] are passed in explicitly, and
328 /// occur in the [arguments] list, in normalized order.
329 ///
330 /// Last in the [arguments] list, after the mandatory and optional arguments,
331 /// the internal representation of each type argument occurs, unless it could
332 /// be determined at build-time that the constructed class has no need for its
333 /// runtime type information.
334 ///
335 /// Note that [InvokeConstructor] does it itself allocate an object.
336 /// The invoked constructor will do that using [CreateInstance].
368 class InvokeConstructor extends Expression implements Invoke { 337 class InvokeConstructor extends Expression implements Invoke {
369 final DartType type; 338 final DartType type;
370 final FunctionElement target; 339 final ConstructorElement target;
371 final List<Reference<Primitive>> arguments; 340 final List<Reference<Primitive>> arguments;
372 final Reference<Continuation> continuation; 341 final Reference<Continuation> continuation;
373 final Selector selector; 342 final Selector selector;
374 343
375 /// The class being instantiated. This is the same as `target.enclosingClass`
376 /// and `type.element`.
377 ClassElement get targetClass => target.enclosingElement;
378
379 /// True if this is an invocation of a factory constructor.
380 bool get isFactory => target.isFactoryConstructor;
381
382 InvokeConstructor(this.type, 344 InvokeConstructor(this.type,
383 this.target, 345 this.target,
384 this.selector, 346 this.selector,
385 List<Primitive> args, 347 List<Primitive> args,
386 Continuation cont) 348 Continuation cont)
387 : arguments = _referenceList(args), 349 : arguments = _referenceList(args),
388 continuation = new Reference<Continuation>(cont) { 350 continuation = new Reference<Continuation>(cont);
389 assert(dart2js.invariant(target,
390 target.isErroneous ||
391 type.isDynamic ||
392 type.element == target.enclosingClass.declaration,
393 message: "Constructor invocation target is not a constructor: "
394 "$target."));
395 }
396 351
397 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); 352 accept(Visitor visitor) => visitor.visitInvokeConstructor(this);
398 } 353 }
399 354
400 /// "as" casts and "is" checks. 355 // TODO(asgerf): Make a Primitive for "is" and an Expression for "as".
401 // We might want to turn "is"-checks into a [Primitive] as it can never diverge. 356
402 // But then we need to special-case for is-checks with an erroneous .type as 357 /// An "as" cast or an "is" check.
403 // these will throw.
404 class TypeOperator extends Expression { 358 class TypeOperator extends Expression {
405 Reference<Primitive> value; 359 Reference<Primitive> value;
406 final DartType type; 360 final DartType type;
407 361
408 /// If [type] is a [GenericType], this holds the internal representation of 362 /// If [type] is an [InterfaceType], this holds the internal representation of
409 /// the type arguments to [type]. Since these may reference type variables 363 /// the type arguments to [type]. Since these may reference type variables
410 /// from the enclosing class, they are not constant. 364 /// from the enclosing class, they are not constant.
411 /// 365 ///
412 /// If [type] is a [TypeVariableType], this is a singleton list with 366 /// If [type] is a [TypeVariableType], this is a singleton list with
413 /// the internal representation of the type held in that type variable. 367 /// the internal representation of the type held in that type variable.
414 /// 368 ///
415 /// Otherwise the list is empty. 369 /// Otherwise the list is empty.
416 final List<Reference<Primitive>> typeArguments; 370 final List<Reference<Primitive>> typeArguments;
417 final Reference<Continuation> continuation; 371 final Reference<Continuation> continuation;
418 // TODO(johnniwinther): Use `Operator` class to encapsule the operator type.
419 final bool isTypeTest; 372 final bool isTypeTest;
420 373
421 TypeOperator(Primitive value, 374 TypeOperator(Primitive value,
422 this.type, 375 this.type,
423 List<Primitive> typeArguments, 376 List<Primitive> typeArguments,
424 Continuation cont, 377 Continuation cont,
425 {bool this.isTypeTest}) 378 {bool this.isTypeTest})
426 : this.value = new Reference<Primitive>(value), 379 : this.value = new Reference<Primitive>(value),
427 this.typeArguments = _referenceList(typeArguments), 380 this.typeArguments = _referenceList(typeArguments),
428 this.continuation = new Reference<Continuation>(cont) { 381 this.continuation = new Reference<Continuation>(cont) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 this.value = new Reference<Primitive>(value); 466 this.value = new Reference<Primitive>(value);
514 467
515 accept(Visitor visitor) => visitor.visitSetMutableVariable(this); 468 accept(Visitor visitor) => visitor.visitSetMutableVariable(this);
516 469
517 Expression plug(Expression expr) { 470 Expression plug(Expression expr) {
518 assert(body == null); 471 assert(body == null);
519 return body = expr; 472 return body = expr;
520 } 473 }
521 } 474 }
522 475
523 /// Create a potentially recursive function and store it in a [MutableVariable].
524 /// The function can access itself using [GetMutableVariable] on [variable].
525 /// There must not exist a [SetMutableVariable] to [variable].
526 ///
527 /// This can be seen as a let rec binding:
528 ///
529 /// let rec [variable] = [definition] in [body]
530 ///
531 class DeclareFunction extends Expression
532 implements InteriorNode, DartSpecificNode {
533 final MutableVariable variable;
534 final FunctionDefinition definition;
535 Expression body;
536
537 DeclareFunction(this.variable, this.definition);
538
539 Expression plug(Expression expr) {
540 assert(body == null);
541 return body = expr;
542 }
543
544 accept(Visitor visitor) => visitor.visitDeclareFunction(this);
545 }
546
547 /// Invoke a continuation in tail position. 476 /// Invoke a continuation in tail position.
548 class InvokeContinuation extends Expression { 477 class InvokeContinuation extends Expression {
549 Reference<Continuation> continuation; 478 Reference<Continuation> continuation;
550 List<Reference<Primitive>> arguments; 479 List<Reference<Primitive>> arguments;
551 480
552 // An invocation of a continuation is recursive if it occurs in the body of 481 // An invocation of a continuation is recursive if it occurs in the body of
553 // the continuation itself. 482 // the continuation itself.
554 bool isRecursive; 483 bool isRecursive;
555 484
556 InvokeContinuation(Continuation cont, List<Primitive> args, 485 InvokeContinuation(Continuation cont, List<Primitive> args,
(...skipping 22 matching lines...) Expand all
579 508
580 class IsTrue extends Condition { 509 class IsTrue extends Condition {
581 final Reference<Primitive> value; 510 final Reference<Primitive> value;
582 511
583 IsTrue(Primitive val) : value = new Reference<Primitive>(val); 512 IsTrue(Primitive val) : value = new Reference<Primitive>(val);
584 513
585 accept(Visitor visitor) => visitor.visitIsTrue(this); 514 accept(Visitor visitor) => visitor.visitIsTrue(this);
586 } 515 }
587 516
588 /// Choose between a pair of continuations based on a condition value. 517 /// Choose between a pair of continuations based on a condition value.
518 ///
519 /// The two continuations must not declare any parameters.
589 class Branch extends Expression { 520 class Branch extends Expression {
590 final Condition condition; 521 final Condition condition;
591 final Reference<Continuation> trueContinuation; 522 final Reference<Continuation> trueContinuation;
592 final Reference<Continuation> falseContinuation; 523 final Reference<Continuation> falseContinuation;
593 524
594 Branch(this.condition, Continuation trueCont, Continuation falseCont) 525 Branch(this.condition, Continuation trueCont, Continuation falseCont)
595 : trueContinuation = new Reference<Continuation>(trueCont), 526 : trueContinuation = new Reference<Continuation>(trueCont),
596 falseContinuation = new Reference<Continuation>(falseCont); 527 falseContinuation = new Reference<Continuation>(falseCont);
597 528
598 accept(Visitor visitor) => visitor.visitBranch(this); 529 accept(Visitor visitor) => visitor.visitBranch(this);
599 } 530 }
600 531
601 /// Marker interface for nodes that are only handled in the JavaScript backend.
602 ///
603 /// These nodes are generated by the unsugar step or the [JsIrBuilder] and need
604 /// special translation to the Tree IR, which is implemented in JsTreeBuilder.
605 abstract class JsSpecificNode implements Node {}
606
607 /// Marker interface for nodes that are only handled inthe Dart backend.
608 abstract class DartSpecificNode implements Node {}
609
610 /// Directly assigns to a field on a given object. 532 /// Directly assigns to a field on a given object.
611 class SetField extends Expression implements InteriorNode, JsSpecificNode { 533 class SetField extends Expression implements InteriorNode {
612 final Reference<Primitive> object; 534 final Reference<Primitive> object;
613 Element field; 535 FieldElement field;
614 final Reference<Primitive> value; 536 final Reference<Primitive> value;
615 Expression body; 537 Expression body;
616 538
617 SetField(Primitive object, this.field, Primitive value) 539 SetField(Primitive object, this.field, Primitive value)
618 : this.object = new Reference<Primitive>(object), 540 : this.object = new Reference<Primitive>(object),
619 this.value = new Reference<Primitive>(value); 541 this.value = new Reference<Primitive>(value);
620 542
621 Expression plug(Expression expr) { 543 Expression plug(Expression expr) {
622 assert(body == null); 544 assert(body == null);
623 return body = expr; 545 return body = expr;
624 } 546 }
625 547
626 accept(Visitor visitor) => visitor.visitSetField(this); 548 accept(Visitor visitor) => visitor.visitSetField(this);
627 } 549 }
628 550
629 /// Directly reads from a field on a given object. 551 /// Directly reads from a field on a given object.
630 class GetField extends Primitive implements JsSpecificNode { 552 class GetField extends Primitive {
631 final Reference<Primitive> object; 553 final Reference<Primitive> object;
632 Element field; 554 FieldElement field;
633 555
634 GetField(Primitive object, this.field) 556 GetField(Primitive object, this.field)
635 : this.object = new Reference<Primitive>(object); 557 : this.object = new Reference<Primitive>(object);
636 558
637 accept(Visitor visitor) => visitor.visitGetField(this); 559 accept(Visitor visitor) => visitor.visitGetField(this);
638 } 560 }
639 561
640 /// Reads the value of a static field or tears off a static method. 562 /// Reads the value of a static field or tears off a static method.
641 class GetStatic extends Primitive { 563 class GetStatic extends Primitive {
564 /// Can be [FieldElement] or [FunctionElement].
642 final Element element; 565 final Element element;
643 final SourceInformation sourceInformation; 566 final SourceInformation sourceInformation;
644 567
645 GetStatic(this.element, this.sourceInformation); 568 GetStatic(this.element, this.sourceInformation);
646 569
647 accept(Visitor visitor) => visitor.visitGetStatic(this); 570 accept(Visitor visitor) => visitor.visitGetStatic(this);
648 } 571 }
649 572
650 /// Sets the value of a static field. 573 /// Sets the value of a static field.
651 class SetStatic extends Expression implements InteriorNode { 574 class SetStatic extends Expression implements InteriorNode {
652 final Element element; 575 final FieldElement element;
653 final Reference<Primitive> value; 576 final Reference<Primitive> value;
654 Expression body; 577 Expression body;
655 final SourceInformation sourceInformation; 578 final SourceInformation sourceInformation;
656 579
657 SetStatic(this.element, Primitive value, this.sourceInformation) 580 SetStatic(this.element, Primitive value, this.sourceInformation)
658 : this.value = new Reference<Primitive>(value); 581 : this.value = new Reference<Primitive>(value);
659 582
660 Expression plug(Expression expr) { 583 Expression plug(Expression expr) {
661 assert(body == null); 584 assert(body == null);
662 return body = expr; 585 return body = expr;
663 } 586 }
664 587
665 accept(Visitor visitor) => visitor.visitSetStatic(this); 588 accept(Visitor visitor) => visitor.visitSetStatic(this);
666 } 589 }
667 590
668 /// Reads the value of a lazily initialized static field. 591 /// Reads the value of a lazily initialized static field.
669 /// 592 ///
670 /// If the field has not yet been initialized, its initializer is evaluated 593 /// If the field has not yet been initialized, its initializer is evaluated
671 /// and assigned to the field. 594 /// and assigned to the field.
672 /// 595 ///
673 /// [continuation] is then invoked with the value of the field as argument. 596 /// [continuation] is then invoked with the value of the field as argument.
674 class GetLazyStatic extends Expression { 597 class GetLazyStatic extends Expression {
675 final FieldElement element; 598 final FieldElement element;
676 final Reference<Continuation> continuation; 599 final Reference<Continuation> continuation;
677 final SourceInformation sourceInformation; 600 final SourceInformation sourceInformation;
678 601
679 GetLazyStatic(this.element, 602 GetLazyStatic(this.element,
680 Continuation cont, 603 Continuation continuation,
681 this.sourceInformation) 604 this.sourceInformation)
682 : continuation = new Reference<Continuation>(cont); 605 : continuation = new Reference<Continuation>(continuation);
683 606
684 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); 607 accept(Visitor visitor) => visitor.visitGetLazyStatic(this);
685 } 608 }
686 609
687 /// Creates an object for holding boxed variables captured by a closure. 610 /// Creates an object for holding boxed variables captured by a closure.
688 class CreateBox extends Primitive implements JsSpecificNode { 611 class CreateBox extends Primitive {
689 accept(Visitor visitor) => visitor.visitCreateBox(this); 612 accept(Visitor visitor) => visitor.visitCreateBox(this);
690 } 613 }
691 614
692 /// Creates an instance of a class and initializes its fields and runtime type 615 /// Creates an instance of a class and initializes its fields and runtime type
693 /// information. 616 /// information.
694 class CreateInstance extends Primitive implements JsSpecificNode { 617 class CreateInstance extends Primitive {
695 final ClassElement classElement; 618 final ClassElement classElement;
696 619
697 /// Initial values for the fields on the class. 620 /// Initial values for the fields on the class.
698 /// The order corresponds to the order of fields on the class. 621 /// The order corresponds to the order of fields on the class.
699 final List<Reference<Primitive>> arguments; 622 final List<Reference<Primitive>> arguments;
700 623
701 /// The runtime type information structure which contains the type arguments. 624 /// The runtime type information structure which contains the type arguments.
702 /// 625 ///
703 /// May be `null` to indicate that no type information is needed because the 626 /// May be `null` to indicate that no type information is needed because the
704 /// compiler determined that the type information for instances of this class 627 /// compiler determined that the type information for instances of this class
705 /// is not needed at runtime. 628 /// is not needed at runtime.
706 final List<Reference<Primitive>> typeInformation; 629 final List<Reference<Primitive>> typeInformation;
707 630
708 CreateInstance(this.classElement, List<Primitive> arguments, 631 CreateInstance(this.classElement, List<Primitive> arguments,
709 List<Primitive> typeInformation) 632 List<Primitive> typeInformation)
710 : this.arguments = _referenceList(arguments), 633 : this.arguments = _referenceList(arguments),
711 this.typeInformation = _referenceList(typeInformation); 634 this.typeInformation = _referenceList(typeInformation);
712 635
713 accept(Visitor visitor) => visitor.visitCreateInstance(this); 636 accept(Visitor visitor) => visitor.visitCreateInstance(this);
714 } 637 }
715 638
716 class Identical extends Primitive implements JsSpecificNode { 639 /// Compare objects for identity.
640 ///
641 /// It is an error pass in a value that does not correspond to a Dart value,
642 /// such as an interceptor or a box.
643 class Identical extends Primitive {
717 final Reference<Primitive> left; 644 final Reference<Primitive> left;
718 final Reference<Primitive> right; 645 final Reference<Primitive> right;
719 Identical(Primitive left, Primitive right) 646 Identical(Primitive left, Primitive right)
720 : left = new Reference<Primitive>(left), 647 : left = new Reference<Primitive>(left),
721 right = new Reference<Primitive>(right); 648 right = new Reference<Primitive>(right);
722 accept(Visitor visitor) => visitor.visitIdentical(this); 649 accept(Visitor visitor) => visitor.visitIdentical(this);
723 } 650 }
724 651
725 class Interceptor extends Primitive implements JsSpecificNode { 652 class Interceptor extends Primitive {
726 final Reference<Primitive> input; 653 final Reference<Primitive> input;
727 final Set<ClassElement> interceptedClasses; 654 final Set<ClassElement> interceptedClasses;
728 Interceptor(Primitive input, this.interceptedClasses) 655 Interceptor(Primitive input, this.interceptedClasses)
729 : this.input = new Reference<Primitive>(input); 656 : this.input = new Reference<Primitive>(input);
730 accept(Visitor visitor) => visitor.visitInterceptor(this); 657 accept(Visitor visitor) => visitor.visitInterceptor(this);
731 } 658 }
732 659
733 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. 660 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`.
734 class CreateInvocationMirror extends Primitive implements JsSpecificNode { 661 class CreateInvocationMirror extends Primitive {
735 final Selector selector; 662 final Selector selector;
736 final List<Reference<Primitive>> arguments; 663 final List<Reference<Primitive>> arguments;
737 664
738 CreateInvocationMirror(this.selector, List<Primitive> arguments) 665 CreateInvocationMirror(this.selector, List<Primitive> arguments)
739 : this.arguments = _referenceList(arguments); 666 : this.arguments = _referenceList(arguments);
740 667
741 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); 668 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this);
742 } 669 }
743 670
744 class Constant extends Primitive { 671 class Constant extends Primitive {
745 final ConstantExpression expression; 672 final ConstantExpression expression;
746 673
747 Constant(this.expression); 674 Constant(this.expression);
748 675
749 values.ConstantValue get value => expression.value; 676 values.ConstantValue get value => expression.value;
750 677
751 accept(Visitor visitor) => visitor.visitConstant(this); 678 accept(Visitor visitor) => visitor.visitConstant(this);
752 } 679 }
753 680
754 /// Reify the given type variable as a [Type].
755 /// This depends on the current binding of 'this'.
756 class ReifyTypeVar extends Primitive implements DartSpecificNode {
757 final TypeVariableElement typeVariable;
758
759 ReifyTypeVar(this.typeVariable);
760
761 values.ConstantValue get constant => null;
762
763 accept(Visitor visitor) => visitor.visitReifyTypeVar(this);
764 }
765
766 class LiteralList extends Primitive { 681 class LiteralList extends Primitive {
767 /// The List type being created; this is not the type argument. 682 /// The List type being created; this is not the type argument.
768 final GenericType type; 683 final InterfaceType type;
769 final List<Reference<Primitive>> values; 684 final List<Reference<Primitive>> values;
770 685
771 LiteralList(this.type, List<Primitive> values) 686 LiteralList(this.type, List<Primitive> values)
772 : this.values = _referenceList(values); 687 : this.values = _referenceList(values);
773 688
774 accept(Visitor visitor) => visitor.visitLiteralList(this); 689 accept(Visitor visitor) => visitor.visitLiteralList(this);
775 } 690 }
776 691
777 class LiteralMapEntry { 692 class LiteralMapEntry {
778 final Reference<Primitive> key; 693 final Reference<Primitive> key;
779 final Reference<Primitive> value; 694 final Reference<Primitive> value;
780 695
781 LiteralMapEntry(Primitive key, Primitive value) 696 LiteralMapEntry(Primitive key, Primitive value)
782 : this.key = new Reference<Primitive>(key), 697 : this.key = new Reference<Primitive>(key),
783 this.value = new Reference<Primitive>(value); 698 this.value = new Reference<Primitive>(value);
784 } 699 }
785 700
786 class LiteralMap extends Primitive { 701 class LiteralMap extends Primitive {
787 final GenericType type; 702 final InterfaceType type;
788 final List<LiteralMapEntry> entries; 703 final List<LiteralMapEntry> entries;
789 704
790 LiteralMap(this.type, this.entries); 705 LiteralMap(this.type, this.entries);
791 706
792 accept(Visitor visitor) => visitor.visitLiteralMap(this); 707 accept(Visitor visitor) => visitor.visitLiteralMap(this);
793 } 708 }
794 709
795 /// Create a non-recursive function. 710 /// Currently unused.
796 class CreateFunction extends Primitive implements DartSpecificNode { 711 ///
712 /// Nested functions (from Dart code) are translated to classes by closure
713 /// conversion, hence they are instantiated with [CreateInstance].
714 ///
715 /// We keep this around for now because it might come in handy when we
716 /// handle async/await in the CPS IR.
717 ///
718 /// Instantiates a nested function. [MutableVariable]s are in scope in the
719 /// inner function, but primitives are not shared across function boundaries.
720 class CreateFunction extends Primitive {
797 final FunctionDefinition definition; 721 final FunctionDefinition definition;
798 722
799 CreateFunction(this.definition); 723 CreateFunction(this.definition);
800 724
801 accept(Visitor visitor) => visitor.visitCreateFunction(this); 725 accept(Visitor visitor) => visitor.visitCreateFunction(this);
802 } 726 }
803 727
804 class Parameter extends Primitive { 728 class Parameter extends Primitive {
805 Parameter(Entity hint) { 729 Parameter(Entity hint) {
806 super.hint = hint; 730 super.hint = hint;
807 } 731 }
808 732
809 // In addition to a parent pointer to the containing Continuation or 733 // In addition to a parent pointer to the containing Continuation or
810 // FunctionDefinition, parameters have an index into the list of parameters 734 // FunctionDefinition, parameters have an index into the list of parameters
811 // bound by the parent. This gives constant-time access to the continuation 735 // bound by the parent. This gives constant-time access to the continuation
812 // from the parent. 736 // from the parent.
813 int parentIndex; 737 int parentIndex;
814 738
815 accept(Visitor visitor) => visitor.visitParameter(this); 739 accept(Visitor visitor) => visitor.visitParameter(this);
816 740
817 String toString() => 'Parameter(${hint == null ? null : hint.name})'; 741 String toString() => 'Parameter(${hint == null ? null : hint.name})';
818 } 742 }
819 743
820 /// Continuations are normally bound by 'let cont'. A continuation with one 744 /// Continuations are normally bound by 'let cont'. A continuation with one
821 /// parameter and no body is used to represent a function's return continuation. 745 /// parameter and no body is used to represent a function's return continuation.
822 /// The return continuation is bound by the Function, not by 'let cont'. 746 /// The return continuation is bound by the function, not by 'let cont'.
823 class Continuation extends Definition<Continuation> implements InteriorNode { 747 class Continuation extends Definition<Continuation> implements InteriorNode {
824 final List<Parameter> parameters; 748 final List<Parameter> parameters;
825 Expression body = null; 749 Expression body = null;
826 750
827 // In addition to a parent pointer to the containing LetCont, continuations 751 // In addition to a parent pointer to the containing LetCont, continuations
828 // have an index into the list of continuations bound by the LetCont. This 752 // have an index into the list of continuations bound by the LetCont. This
829 // gives constant-time access to the continuation from the parent. 753 // gives constant-time access to the continuation from the parent.
830 int parent_index; 754 int parent_index;
831 755
832 // A continuation is recursive if it has any recursive invocations. 756 // A continuation is recursive if it has any recursive invocations.
833 bool isRecursive; 757 bool isRecursive;
834 758
835 bool get isReturnContinuation => body == null; 759 bool get isReturnContinuation => body == null;
836 760
837 Continuation(this.parameters, {this.isRecursive: false}); 761 Continuation(this.parameters, {this.isRecursive: false});
838 762
839 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; 763 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)];
840 764
841 accept(Visitor visitor) => visitor.visitContinuation(this); 765 accept(Visitor visitor) => visitor.visitContinuation(this);
842 } 766 }
843 767
844 abstract class RootNode extends Node {
845 Element get element;
846
847 /// True if there is no body for this root node.
848 ///
849 /// In some parts of the compiler, empty root nodes are used as placeholders
850 /// for abstract methods, external constructors, fields without initializers,
851 /// etc.
852 bool get isEmpty;
853
854 /// List of parameters, or an empty list if this is a field.
855 /// For fields, this list is immutable.
856 List<Definition> get parameters;
857 }
858
859 // This is basically a function definition with an empty parameter list and a
860 // field element instead of a function element and no const declarations, and
861 // never a getter or setter, though that's less important.
862 class FieldDefinition extends RootNode implements DartSpecificNode {
863 final FieldElement element;
864 List<Definition> get parameters => const <Definition>[];
865 final Body body;
866
867 FieldDefinition(this.element, this.body);
868
869 FieldDefinition.withoutInitializer(this.element)
870 : this.body = null;
871
872 accept(Visitor visitor) => visitor.visitFieldDefinition(this);
873
874 bool get isEmpty => body == null;
875 }
876
877 /// Identifies a mutable variable. 768 /// Identifies a mutable variable.
878 class MutableVariable extends Definition { 769 class MutableVariable extends Definition {
879 Entity hint; 770 Entity hint;
880 771
881 MutableVariable(this.hint); 772 MutableVariable(this.hint);
882 773
883 accept(Visitor v) => v.visitMutableVariable(this); 774 accept(Visitor v) => v.visitMutableVariable(this);
884 } 775 }
885 776
886 class Body extends InteriorNode { 777 /// A function definition, consisting of parameters and a body.
887 Expression body; 778 ///
888 final Continuation returnContinuation; 779 /// There is an explicit parameter for the `this` argument, and a return
889 Body(this.body, this.returnContinuation); 780 /// continuation to invoke when returning from the function.
890 accept(Visitor visitor) => visitor.visitBody(this); 781 class FunctionDefinition extends InteriorNode {
891 }
892
893 /// A function definition, consisting of parameters and a body. The parameters
894 /// include a distinguished continuation parameter (held by the body).
895 class FunctionDefinition extends RootNode {
896 final ExecutableElement element; 782 final ExecutableElement element;
897 final Parameter thisParameter; 783 final Parameter thisParameter;
898 /// Mixed list of [Parameter]s and [MutableVariable]s. 784 final List<Parameter> parameters;
899 final List<Definition> parameters; 785 final Continuation returnContinuation;
900 final Body body; 786 Expression body;
901 final List<ConstDeclaration> localConstants;
902
903 /// Values for optional parameters.
904 final List<ConstantExpression> defaultParameterValues;
905 787
906 FunctionDefinition(this.element, 788 FunctionDefinition(this.element,
907 this.thisParameter, 789 this.thisParameter,
908 this.parameters, 790 this.parameters,
909 this.body, 791 this.returnContinuation,
910 this.localConstants, 792 this.body);
911 this.defaultParameterValues);
912
913 FunctionDefinition.abstract(this.element,
914 this.parameters,
915 this.defaultParameterValues)
916 : body = null,
917 thisParameter = null,
918 localConstants = const <ConstDeclaration>[];
919 793
920 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); 794 accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
921
922 bool get isEmpty => body == null;
923 }
924
925 abstract class Initializer extends Node implements DartSpecificNode {}
926
927 class FieldInitializer extends Initializer {
928 final FieldElement element;
929 final Body body;
930
931 FieldInitializer(this.element, this.body);
932 accept(Visitor visitor) => visitor.visitFieldInitializer(this);
933 }
934
935 class SuperInitializer extends Initializer {
936 final ConstructorElement target;
937 final List<Body> arguments;
938 final Selector selector;
939 SuperInitializer(this.target, this.arguments, this.selector);
940 accept(Visitor visitor) => visitor.visitSuperInitializer(this);
941 }
942
943 class ConstructorDefinition extends RootNode implements DartSpecificNode {
944 final ConstructorElement element;
945 final Parameter thisParameter;
946 /// Mixed list of [Parameter]s and [MutableVariable]s.
947 final List<Definition> parameters;
948 final Body body;
949 final List<ConstDeclaration> localConstants;
950 final List<Initializer> initializers;
951
952 /// Values for optional parameters.
953 final List<ConstantExpression> defaultParameterValues;
954
955 ConstructorDefinition(this.element,
956 this.thisParameter,
957 this.parameters,
958 this.body,
959 this.initializers,
960 this.localConstants,
961 this.defaultParameterValues);
962
963 // 'Abstract' here means "has no body" and is used to represent external
964 // constructors.
965 ConstructorDefinition.abstract(
966 this.element,
967 this.parameters,
968 this.defaultParameterValues)
969 : body = null,
970 initializers = null,
971 thisParameter = null,
972 localConstants = const <ConstDeclaration>[];
973
974 accept(Visitor visitor) => visitor.visitConstructorDefinition(this);
975
976 bool get isEmpty => body == null;
977 } 795 }
978 796
979 /// Converts the internal representation of a type to a Dart object of type 797 /// Converts the internal representation of a type to a Dart object of type
980 /// [Type]. 798 /// [Type].
981 class ReifyRuntimeType extends Primitive implements JsSpecificNode { 799 class ReifyRuntimeType extends Primitive {
982 /// Reference to the internal representation of a type (as produced, for 800 /// Reference to the internal representation of a type (as produced, for
983 /// example, by [ReadTypeVariable]). 801 /// example, by [ReadTypeVariable]).
984 final Reference<Primitive> value; 802 final Reference<Primitive> value;
985 ReifyRuntimeType(Primitive value) 803 ReifyRuntimeType(Primitive value)
986 : this.value = new Reference<Primitive>(value); 804 : this.value = new Reference<Primitive>(value);
987 805
988 @override 806 @override
989 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); 807 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
990 } 808 }
991 809
992 /// Read the value the type variable [variable] from the target object. 810 /// Read the value the type variable [variable] from the target object.
993 /// 811 ///
994 /// The resulting value is an internal representation (and not neccessarily a 812 /// The resulting value is an internal representation (and not neccessarily a
995 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be 813 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be
996 /// used as a Dart value. 814 /// used as a Dart value.
997 class ReadTypeVariable extends Primitive implements JsSpecificNode { 815 class ReadTypeVariable extends Primitive {
998 final TypeVariableType variable; 816 final TypeVariableType variable;
999 final Reference<Primitive> target; 817 final Reference<Primitive> target;
1000 818
1001 ReadTypeVariable(this.variable, Primitive target) 819 ReadTypeVariable(this.variable, Primitive target)
1002 : this.target = new Reference<Primitive>(target); 820 : this.target = new Reference<Primitive>(target);
1003 821
1004 @override 822 @override
1005 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); 823 accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
1006 } 824 }
1007 825
1008 /// Representation of a closed type (that is, a type without type variables). 826 /// Representation of a closed type (that is, a type without type variables).
1009 /// 827 ///
1010 /// The resulting value is constructed from [dartType] by replacing the type 828 /// The resulting value is constructed from [dartType] by replacing the type
1011 /// variables with consecutive values from [arguments], in the order generated 829 /// variables with consecutive values from [arguments], in the order generated
1012 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are 830 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are
1013 /// treated as 'holes' in the term, which means that it must be ensured at 831 /// treated as 'holes' in the term, which means that it must be ensured at
1014 /// construction, that duplicate occurences of a type variable in [dartType] 832 /// construction, that duplicate occurences of a type variable in [dartType]
1015 /// are assigned the same value. 833 /// are assigned the same value.
1016 class TypeExpression extends Primitive implements JsSpecificNode { 834 class TypeExpression extends Primitive {
1017 final DartType dartType; 835 final DartType dartType;
1018 final List<Reference<Primitive>> arguments; 836 final List<Reference<Primitive>> arguments;
1019 837
1020 TypeExpression(this.dartType, 838 TypeExpression(this.dartType,
1021 [List<Primitive> arguments = const <Primitive>[]]) 839 [List<Primitive> arguments = const <Primitive>[]])
1022 : this.arguments = _referenceList(arguments); 840 : this.arguments = _referenceList(arguments);
1023 841
1024 @override 842 @override
1025 accept(Visitor visitor) { 843 accept(Visitor visitor) {
1026 return visitor.visitTypeExpression(this); 844 return visitor.visitTypeExpression(this);
1027 } 845 }
1028 } 846 }
1029 847
1030 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { 848 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
1031 return definitions.map((e) => new Reference<Primitive>(e)).toList(); 849 return definitions.map((e) => new Reference<Primitive>(e)).toList();
1032 } 850 }
1033 851
1034 abstract class Visitor<T> { 852 abstract class Visitor<T> {
1035 const Visitor(); 853 const Visitor();
1036 854
1037 T visit(Node node); 855 T visit(Node node);
1038 856
1039 // Concrete classes. 857 // Concrete classes.
1040 T visitFieldDefinition(FieldDefinition node);
1041 T visitFunctionDefinition(FunctionDefinition node); 858 T visitFunctionDefinition(FunctionDefinition node);
1042 T visitConstructorDefinition(ConstructorDefinition node);
1043 T visitBody(Body node);
1044
1045 // Initializers
1046 T visitFieldInitializer(FieldInitializer node);
1047 T visitSuperInitializer(SuperInitializer node);
1048 859
1049 // Expressions. 860 // Expressions.
1050 T visitLetPrim(LetPrim node); 861 T visitLetPrim(LetPrim node);
1051 T visitLetCont(LetCont node); 862 T visitLetCont(LetCont node);
1052 T visitLetHandler(LetHandler node); 863 T visitLetHandler(LetHandler node);
1053 T visitLetMutable(LetMutable node); 864 T visitLetMutable(LetMutable node);
1054 T visitInvokeContinuation(InvokeContinuation node); 865 T visitInvokeContinuation(InvokeContinuation node);
1055 T visitInvokeStatic(InvokeStatic node); 866 T visitInvokeStatic(InvokeStatic node);
1056 T visitInvokeMethod(InvokeMethod node); 867 T visitInvokeMethod(InvokeMethod node);
1057 T visitInvokeMethodDirectly(InvokeMethodDirectly node); 868 T visitInvokeMethodDirectly(InvokeMethodDirectly node);
1058 T visitInvokeConstructor(InvokeConstructor node); 869 T visitInvokeConstructor(InvokeConstructor node);
1059 T visitConcatenateStrings(ConcatenateStrings node); 870 T visitConcatenateStrings(ConcatenateStrings node);
1060 T visitThrow(Throw node); 871 T visitThrow(Throw node);
1061 T visitRethrow(Rethrow node); 872 T visitRethrow(Rethrow node);
1062 T visitBranch(Branch node); 873 T visitBranch(Branch node);
1063 T visitTypeOperator(TypeOperator node); 874 T visitTypeOperator(TypeOperator node);
1064 T visitSetMutableVariable(SetMutableVariable node); 875 T visitSetMutableVariable(SetMutableVariable node);
1065 T visitDeclareFunction(DeclareFunction node);
1066 T visitSetStatic(SetStatic node); 876 T visitSetStatic(SetStatic node);
1067 T visitGetLazyStatic(GetLazyStatic node); 877 T visitGetLazyStatic(GetLazyStatic node);
878 T visitSetField(SetField node);
1068 879
1069 // Definitions. 880 // Definitions.
1070 T visitLiteralList(LiteralList node); 881 T visitLiteralList(LiteralList node);
1071 T visitLiteralMap(LiteralMap node); 882 T visitLiteralMap(LiteralMap node);
1072 T visitConstant(Constant node); 883 T visitConstant(Constant node);
1073 T visitReifyTypeVar(ReifyTypeVar node);
1074 T visitCreateFunction(CreateFunction node); 884 T visitCreateFunction(CreateFunction node);
1075 T visitGetMutableVariable(GetMutableVariable node); 885 T visitGetMutableVariable(GetMutableVariable node);
1076 T visitParameter(Parameter node); 886 T visitParameter(Parameter node);
1077 T visitContinuation(Continuation node); 887 T visitContinuation(Continuation node);
1078 T visitMutableVariable(MutableVariable node); 888 T visitMutableVariable(MutableVariable node);
1079 T visitNonTailThrow(NonTailThrow node); 889 T visitNonTailThrow(NonTailThrow node);
1080 T visitGetStatic(GetStatic node); 890 T visitGetStatic(GetStatic node);
1081
1082 // JavaScript specific nodes.
1083
1084 // Conditions.
1085 T visitIsTrue(IsTrue node);
1086
1087 // Expressions.
1088 T visitSetField(SetField node);
1089
1090 // Definitions.
1091 T visitIdentical(Identical node); 891 T visitIdentical(Identical node);
1092 T visitInterceptor(Interceptor node); 892 T visitInterceptor(Interceptor node);
1093 T visitCreateInstance(CreateInstance node); 893 T visitCreateInstance(CreateInstance node);
1094 T visitGetField(GetField node); 894 T visitGetField(GetField node);
1095 T visitCreateBox(CreateBox node); 895 T visitCreateBox(CreateBox node);
1096 T visitReifyRuntimeType(ReifyRuntimeType node); 896 T visitReifyRuntimeType(ReifyRuntimeType node);
1097 T visitReadTypeVariable(ReadTypeVariable node); 897 T visitReadTypeVariable(ReadTypeVariable node);
1098 T visitTypeExpression(TypeExpression node); 898 T visitTypeExpression(TypeExpression node);
1099 T visitCreateInvocationMirror(CreateInvocationMirror node); 899 T visitCreateInvocationMirror(CreateInvocationMirror node);
900
901 // Conditions.
902 T visitIsTrue(IsTrue node);
1100 } 903 }
1101 904
1102 /// Recursively visits the entire CPS term, and calls abstract `process*` 905 /// Recursively visits the entire CPS term, and calls abstract `process*`
1103 /// (i.e. `processLetPrim`) functions in pre-order. 906 /// (i.e. `processLetPrim`) functions in pre-order.
1104 class RecursiveVisitor implements Visitor { 907 class RecursiveVisitor implements Visitor {
1105 const RecursiveVisitor(); 908 const RecursiveVisitor();
1106 909
1107 visit(Node node) => node.accept(this); 910 visit(Node node) => node.accept(this);
1108 911
1109 processReference(Reference ref) {} 912 processReference(Reference ref) {}
1110 913
1111 processBody(Body node) {}
1112 visitBody(Body node) {
1113 processBody(node);
1114 visit(node.returnContinuation);
1115 visit(node.body);
1116 }
1117
1118 processFieldDefinition(FieldDefinition node) {}
1119 visitFieldDefinition(FieldDefinition node) {
1120 processFieldDefinition(node);
1121 if (node.body != null) {
1122 visit(node.body);
1123 }
1124 }
1125
1126 processFunctionDefinition(FunctionDefinition node) {} 914 processFunctionDefinition(FunctionDefinition node) {}
1127 visitFunctionDefinition(FunctionDefinition node) { 915 visitFunctionDefinition(FunctionDefinition node) {
1128 processFunctionDefinition(node); 916 processFunctionDefinition(node);
1129 if (node.thisParameter != null) visit(node.thisParameter); 917 if (node.thisParameter != null) visit(node.thisParameter);
1130 node.parameters.forEach(visit); 918 node.parameters.forEach(visit);
1131 if (node.body != null) { 919 visit(node.returnContinuation);
1132 visit(node.body);
1133 }
1134 }
1135
1136 processConstructorDefinition(ConstructorDefinition node) {}
1137 visitConstructorDefinition(ConstructorDefinition node) {
1138 processConstructorDefinition(node);
1139 if (node.thisParameter != null) visit(node.thisParameter);
1140 node.parameters.forEach(visit);
1141 if (node.initializers != null) {
1142 node.initializers.forEach(visit);
1143 }
1144 if (node.body != null) {
1145 visit(node.body);
1146 }
1147 }
1148
1149 processFieldInitializer(FieldInitializer node) {}
1150 visitFieldInitializer(FieldInitializer node) {
1151 processFieldInitializer(node);
1152 visit(node.body); 920 visit(node.body);
1153 } 921 }
1154 922
1155 processSuperInitializer(SuperInitializer node) {}
1156 visitSuperInitializer(SuperInitializer node) {
1157 processSuperInitializer(node);
1158 node.arguments.forEach(visit);
1159 }
1160
1161 // Expressions. 923 // Expressions.
1162 924
1163 processLetPrim(LetPrim node) {} 925 processLetPrim(LetPrim node) {}
1164 visitLetPrim(LetPrim node) { 926 visitLetPrim(LetPrim node) {
1165 processLetPrim(node); 927 processLetPrim(node);
1166 visit(node.primitive); 928 visit(node.primitive);
1167 visit(node.body); 929 visit(node.body);
1168 } 930 }
1169 931
1170 processLetCont(LetCont node) {} 932 processLetCont(LetCont node) {}
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 } 1023 }
1262 1024
1263 processSetMutableVariable(SetMutableVariable node) {} 1025 processSetMutableVariable(SetMutableVariable node) {}
1264 visitSetMutableVariable(SetMutableVariable node) { 1026 visitSetMutableVariable(SetMutableVariable node) {
1265 processSetMutableVariable(node); 1027 processSetMutableVariable(node);
1266 processReference(node.variable); 1028 processReference(node.variable);
1267 processReference(node.value); 1029 processReference(node.value);
1268 visit(node.body); 1030 visit(node.body);
1269 } 1031 }
1270 1032
1271 processDeclareFunction(DeclareFunction node) {}
1272 visitDeclareFunction(DeclareFunction node) {
1273 processDeclareFunction(node);
1274 visit(node.variable);
1275 visit(node.definition);
1276 visit(node.body);
1277 }
1278
1279 processGetLazyStatic(GetLazyStatic node) {} 1033 processGetLazyStatic(GetLazyStatic node) {}
1280 visitGetLazyStatic(GetLazyStatic node) { 1034 visitGetLazyStatic(GetLazyStatic node) {
1281 processGetLazyStatic(node); 1035 processGetLazyStatic(node);
1282 processReference(node.continuation); 1036 processReference(node.continuation);
1283 } 1037 }
1284 1038
1285 // Definitions.
1286
1287 processLiteralList(LiteralList node) {} 1039 processLiteralList(LiteralList node) {}
1288 visitLiteralList(LiteralList node) { 1040 visitLiteralList(LiteralList node) {
1289 processLiteralList(node); 1041 processLiteralList(node);
1290 node.values.forEach(processReference); 1042 node.values.forEach(processReference);
1291 } 1043 }
1292 1044
1293 processLiteralMap(LiteralMap node) {} 1045 processLiteralMap(LiteralMap node) {}
1294 visitLiteralMap(LiteralMap node) { 1046 visitLiteralMap(LiteralMap node) {
1295 processLiteralMap(node); 1047 processLiteralMap(node);
1296 for (LiteralMapEntry entry in node.entries) { 1048 for (LiteralMapEntry entry in node.entries) {
1297 processReference(entry.key); 1049 processReference(entry.key);
1298 processReference(entry.value); 1050 processReference(entry.value);
1299 } 1051 }
1300 } 1052 }
1301 1053
1302 processConstant(Constant node) {} 1054 processConstant(Constant node) {}
1303 visitConstant(Constant node) { 1055 visitConstant(Constant node) {
1304 processConstant(node); 1056 processConstant(node);
1305 } 1057 }
1306 1058
1307 processReifyTypeVar(ReifyTypeVar node) {}
1308 visitReifyTypeVar(ReifyTypeVar node) {
1309 processReifyTypeVar(node);
1310 }
1311
1312 processCreateFunction(CreateFunction node) {} 1059 processCreateFunction(CreateFunction node) {}
1313 visitCreateFunction(CreateFunction node) { 1060 visitCreateFunction(CreateFunction node) {
1314 processCreateFunction(node); 1061 processCreateFunction(node);
1315 visit(node.definition); 1062 visit(node.definition);
1316 } 1063 }
1317 1064
1318 processMutableVariable(node) {} 1065 processMutableVariable(node) {}
1319 visitMutableVariable(MutableVariable node) { 1066 visitMutableVariable(MutableVariable node) {
1320 processMutableVariable(node); 1067 processMutableVariable(node);
1321 } 1068 }
1322 1069
1323 processGetMutableVariable(GetMutableVariable node) {} 1070 processGetMutableVariable(GetMutableVariable node) {}
1324 visitGetMutableVariable(GetMutableVariable node) { 1071 visitGetMutableVariable(GetMutableVariable node) {
1325 processGetMutableVariable(node); 1072 processGetMutableVariable(node);
1326 processReference(node.variable); 1073 processReference(node.variable);
1327 } 1074 }
1328 1075
1329 processParameter(Parameter node) {} 1076 processParameter(Parameter node) {}
1330 visitParameter(Parameter node) { 1077 visitParameter(Parameter node) {
1331 processParameter(node); 1078 processParameter(node);
1332 } 1079 }
1333 1080
1334 processContinuation(Continuation node) {} 1081 processContinuation(Continuation node) {}
1335 visitContinuation(Continuation node) { 1082 visitContinuation(Continuation node) {
1336 processContinuation(node); 1083 processContinuation(node);
1337 node.parameters.forEach(visitParameter); 1084 node.parameters.forEach(visitParameter);
1338 if (node.body != null) visit(node.body); 1085 if (node.body != null) visit(node.body);
1339 } 1086 }
1340 1087
1341 // Conditions.
1342
1343 processIsTrue(IsTrue node) {} 1088 processIsTrue(IsTrue node) {}
1344 visitIsTrue(IsTrue node) { 1089 visitIsTrue(IsTrue node) {
1345 processIsTrue(node); 1090 processIsTrue(node);
1346 processReference(node.value); 1091 processReference(node.value);
1347 } 1092 }
1348 1093
1349 // JavaScript specific nodes.
1350 processIdentical(Identical node) {} 1094 processIdentical(Identical node) {}
1351 visitIdentical(Identical node) { 1095 visitIdentical(Identical node) {
1352 processIdentical(node); 1096 processIdentical(node);
1353 processReference(node.left); 1097 processReference(node.left);
1354 processReference(node.right); 1098 processReference(node.right);
1355 } 1099 }
1356 1100
1357 processInterceptor(Interceptor node) {} 1101 processInterceptor(Interceptor node) {}
1358 visitInterceptor(Interceptor node) { 1102 visitInterceptor(Interceptor node) {
1359 processInterceptor(node); 1103 processInterceptor(node);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 processNonTailThrow(node); 1165 processNonTailThrow(node);
1422 processReference(node.value); 1166 processReference(node.value);
1423 } 1167 }
1424 1168
1425 processCreateInvocationMirror(CreateInvocationMirror node) {} 1169 processCreateInvocationMirror(CreateInvocationMirror node) {}
1426 visitCreateInvocationMirror(CreateInvocationMirror node) { 1170 visitCreateInvocationMirror(CreateInvocationMirror node) {
1427 processCreateInvocationMirror(node); 1171 processCreateInvocationMirror(node);
1428 node.arguments.forEach(processReference); 1172 node.arguments.forEach(processReference);
1429 } 1173 }
1430 } 1174 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698