| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // IrNodes are kept in a separate library to have precise control over their | 5 // IrNodes are kept in a separate library to have precise control over their |
| 6 // dependencies on other parts of the system. | 6 // dependencies on other parts of the system. |
| 7 library dart2js.ir_nodes; | 7 library dart2js.ir_nodes; |
| 8 | 8 |
| 9 import '../dart2jslib.dart' as dart2js show Constant; | 9 import '../dart2jslib.dart' as dart2js show Constant; |
| 10 import '../elements/elements.dart' | 10 import '../elements/elements.dart' |
| 11 show FunctionElement, LibraryElement, ParameterElement; | 11 show FunctionElement, LibraryElement, ParameterElement, ClassElement; |
| 12 import 'ir_pickler.dart' show Pickler, IrConstantPool; | 12 import 'ir_pickler.dart' show Pickler, IrConstantPool; |
| 13 import '../universe/universe.dart' show Selector, SelectorKind; | 13 import '../universe/universe.dart' show Selector, SelectorKind; |
| 14 import '../dart_types.dart' show DartType, GenericType; |
| 14 | 15 |
| 15 abstract class Node { | 16 abstract class Node { |
| 16 static int hashCount = 0; | 17 static int hashCount = 0; |
| 17 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff; | 18 final int hashCode = hashCount = (hashCount + 1) & 0x3fffffff; |
| 18 | 19 |
| 19 accept(Visitor visitor); | 20 accept(Visitor visitor); |
| 20 } | 21 } |
| 21 | 22 |
| 22 abstract class Expression extends Node { | 23 abstract class Expression extends Node { |
| 23 Expression plug(Expression expr) => throw 'impossible'; | 24 Expression plug(Expression expr) => throw 'impossible'; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 List<Definition> args) | 118 List<Definition> args) |
| 118 : continuation = new Reference(cont), | 119 : continuation = new Reference(cont), |
| 119 arguments = args.map((t) => new Reference(t)).toList(growable: false) { | 120 arguments = args.map((t) => new Reference(t)).toList(growable: false) { |
| 120 assert(selector.kind == SelectorKind.CALL); | 121 assert(selector.kind == SelectorKind.CALL); |
| 121 assert(selector.name == target.name); | 122 assert(selector.name == target.name); |
| 122 } | 123 } |
| 123 | 124 |
| 124 accept(Visitor visitor) => visitor.visitInvokeStatic(this); | 125 accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
| 125 } | 126 } |
| 126 | 127 |
| 128 /// Invoke a method, operator, getter, setter, or index getter/setter in |
| 129 /// tail position. |
| 130 class InvokeMethod extends Expression { |
| 131 final Reference receiver; |
| 132 final Selector selector; |
| 133 final Reference continuation; |
| 134 final List<Reference> arguments; |
| 135 |
| 136 InvokeMethod(Definition receiver, |
| 137 this.selector, |
| 138 Continuation cont, |
| 139 List<Definition> args) |
| 140 : receiver = new Reference(receiver), |
| 141 continuation = new Reference(cont), |
| 142 arguments = args.map((t) => new Reference(t)).toList(growable: false) { |
| 143 assert(selector != null); |
| 144 assert(selector.kind == SelectorKind.CALL || |
| 145 selector.kind == SelectorKind.OPERATOR || |
| 146 (selector.kind == SelectorKind.GETTER && arguments.isEmpty) || |
| 147 (selector.kind == SelectorKind.SETTER && arguments.length == 1) || |
| 148 (selector.kind == SelectorKind.INDEX && arguments.length == 1) || |
| 149 (selector.kind == SelectorKind.INDEX && arguments.length == 2)); |
| 150 } |
| 151 |
| 152 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 153 } |
| 154 |
| 155 /// Non-const call to a constructor. The [target] may be a generative |
| 156 /// constructor, factory, or redirecting factory. |
| 157 class InvokeConstructor extends Expression { |
| 158 final GenericType type; |
| 159 final FunctionElement target; |
| 160 final Reference continuation; |
| 161 final List<Reference> arguments; |
| 162 |
| 163 /// The class being instantiated. This is the same as `target.enclosingClass` |
| 164 /// and `type.element`. |
| 165 ClassElement get targetClass => target.enclosingElement; |
| 166 |
| 167 /// True if this is an invocation of a factory constructor. |
| 168 bool get isFactory => target.isFactoryConstructor; |
| 169 |
| 170 InvokeConstructor(this.type, |
| 171 this.target, |
| 172 Continuation cont, |
| 173 List<Definition> args) |
| 174 : continuation = new Reference(cont), |
| 175 arguments = args.map((t) => new Reference(t)).toList(growable: false) { |
| 176 assert(target.isConstructor); |
| 177 assert(type.element == target.enclosingElement); |
| 178 } |
| 179 |
| 180 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| 181 } |
| 182 |
| 127 /// Invoke a continuation in tail position. | 183 /// Invoke a continuation in tail position. |
| 128 class InvokeContinuation extends Expression { | 184 class InvokeContinuation extends Expression { |
| 129 final Reference continuation; | 185 final Reference continuation; |
| 130 final List<Reference> arguments; | 186 final List<Reference> arguments; |
| 131 | 187 |
| 132 InvokeContinuation(Continuation cont, List<Definition> args) | 188 InvokeContinuation(Continuation cont, List<Definition> args) |
| 133 : continuation = new Reference(cont), | 189 : continuation = new Reference(cont), |
| 134 arguments = args.map((t) => new Reference(t)).toList(growable: false); | 190 arguments = args.map((t) => new Reference(t)).toList(growable: false); |
| 135 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); | 191 accept(Visitor visitor) => visitor.visitInvokeContinuation(this); |
| 136 } | 192 } |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 T visitCondition(Condition node) => visitNode(node); | 272 T visitCondition(Condition node) => visitNode(node); |
| 217 | 273 |
| 218 // Concrete classes. | 274 // Concrete classes. |
| 219 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); | 275 T visitFunctionDefinition(FunctionDefinition node) => visitNode(node); |
| 220 | 276 |
| 221 // Expressions. | 277 // Expressions. |
| 222 T visitLetPrim(LetPrim node) => visitExpression(node); | 278 T visitLetPrim(LetPrim node) => visitExpression(node); |
| 223 T visitLetCont(LetCont node) => visitExpression(node); | 279 T visitLetCont(LetCont node) => visitExpression(node); |
| 224 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); | 280 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); |
| 225 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); | 281 T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node); |
| 282 T visitInvokeMethod(InvokeMethod node) => visitExpression(node); |
| 283 T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node); |
| 226 T visitBranch(Branch node) => visitExpression(node); | 284 T visitBranch(Branch node) => visitExpression(node); |
| 227 | 285 |
| 228 // Definitions. | 286 // Definitions. |
| 229 T visitConstant(Constant node) => visitPrimitive(node); | 287 T visitConstant(Constant node) => visitPrimitive(node); |
| 230 T visitParameter(Parameter node) => visitPrimitive(node); | 288 T visitParameter(Parameter node) => visitPrimitive(node); |
| 231 T visitContinuation(Continuation node) => visitDefinition(node); | 289 T visitContinuation(Continuation node) => visitDefinition(node); |
| 232 | 290 |
| 233 // Conditions. | 291 // Conditions. |
| 234 T visitIsTrue(IsTrue node) => visitCondition(node); | 292 T visitIsTrue(IsTrue node) => visitCondition(node); |
| 235 } | 293 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 String body = visit(node.body); | 339 String body = visit(node.body); |
| 282 return '(LetCont ($cont$parameters) $contBody) $body'; | 340 return '(LetCont ($cont$parameters) $contBody) $body'; |
| 283 } | 341 } |
| 284 | 342 |
| 285 String visitInvokeStatic(InvokeStatic node) { | 343 String visitInvokeStatic(InvokeStatic node) { |
| 286 String name = node.target.name; | 344 String name = node.target.name; |
| 287 String cont = names[node.continuation.definition]; | 345 String cont = names[node.continuation.definition]; |
| 288 String args = node.arguments.map((v) => names[v.definition]).join(' '); | 346 String args = node.arguments.map((v) => names[v.definition]).join(' '); |
| 289 return '(InvokeStatic $name $cont $args)'; | 347 return '(InvokeStatic $name $cont $args)'; |
| 290 } | 348 } |
| 349 |
| 350 String visitInvokeMethod(InvokeMethod node) { |
| 351 String name = node.selector.name; |
| 352 String rcv = names[node.receiver.definition]; |
| 353 String cont = names[node.continuation.definition]; |
| 354 String args = node.arguments.map((v) => names[v.definition]).join(' '); |
| 355 return '(InvokeMethod $rcv $name $cont $args)'; |
| 356 } |
| 357 |
| 358 String visitInvokeConstructor(InvokeConstructor node) { |
| 359 String callName; |
| 360 if (node.target.name.isEmpty) { |
| 361 callName = '${node.type}'; |
| 362 } else { |
| 363 callName = '${node.type}.${node.target.name}'; |
| 364 } |
| 365 String cont = names[node.continuation.definition]; |
| 366 String args = node.arguments.map((v) => names[v.definition]).join(' '); |
| 367 return '(InvokeConstructor $callName $cont $args)'; |
| 368 } |
| 291 | 369 |
| 292 String visitInvokeContinuation(InvokeContinuation node) { | 370 String visitInvokeContinuation(InvokeContinuation node) { |
| 293 String cont = names[node.continuation.definition]; | 371 String cont = names[node.continuation.definition]; |
| 294 String args = node.arguments.map((v) => names[v.definition]).join(' '); | 372 String args = node.arguments.map((v) => names[v.definition]).join(' '); |
| 295 return '(InvokeContinuation $cont $args)'; | 373 return '(InvokeContinuation $cont $args)'; |
| 296 } | 374 } |
| 297 | 375 |
| 298 String visitBranch(Branch node) { | 376 String visitBranch(Branch node) { |
| 299 String condition = visit(node.condition); | 377 String condition = visit(node.condition); |
| 300 String trueCont = names[node.trueContinuation.definition]; | 378 String trueCont = names[node.trueContinuation.definition]; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 314 String visitContinuation(Continuation node) { | 392 String visitContinuation(Continuation node) { |
| 315 // Continuations are visited directly in visitLetCont. | 393 // Continuations are visited directly in visitLetCont. |
| 316 return '(Unexpected Continuation)'; | 394 return '(Unexpected Continuation)'; |
| 317 } | 395 } |
| 318 | 396 |
| 319 String visitIsTrue(IsTrue node) { | 397 String visitIsTrue(IsTrue node) { |
| 320 String value = names[node.value.definition]; | 398 String value = names[node.value.definition]; |
| 321 return '(IsTrue $value)'; | 399 return '(IsTrue $value)'; |
| 322 } | 400 } |
| 323 } | 401 } |
| OLD | NEW |