| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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 library dart2js.ir_nodes_sexpr; | 5 library dart2js.ir_nodes_sexpr; |
| 6 | 6 |
| 7 import '../constants/values.dart'; | 7 import '../constants/values.dart'; |
| 8 import '../util/util.dart'; | 8 import '../util/util.dart'; |
| 9 import 'cps_ir_nodes.dart'; | 9 import 'cps_ir_nodes.dart'; |
| 10 import '../universe/call_structure.dart' show | 10 import '../universe/call_structure.dart' show |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 } | 101 } |
| 102 | 102 |
| 103 String visitLetMutable(LetMutable node) { | 103 String visitLetMutable(LetMutable node) { |
| 104 String name = visit(node.variable); | 104 String name = visit(node.variable); |
| 105 String value = access(node.value); | 105 String value = access(node.value); |
| 106 String body = indentBlock(() => visit(node.body)); | 106 String body = indentBlock(() => visit(node.body)); |
| 107 return '$indentation(LetMutable ($name $value)\n$body)'; | 107 return '$indentation(LetMutable ($name $value)\n$body)'; |
| 108 } | 108 } |
| 109 | 109 |
| 110 String formatArguments(CallStructure call, | 110 String formatArguments(CallStructure call, |
| 111 List<Reference<Primitive>> arguments, | 111 List<Reference<Primitive>> arguments, |
| 112 {bool isIntercepted: false}) { | 112 [CallingConvention callingConvention = CallingConvention.Normal]) { |
| 113 int positionalArgumentCount = call.positionalArgumentCount; | 113 int positionalArgumentCount = call.positionalArgumentCount; |
| 114 if (isIntercepted) ++positionalArgumentCount; | 114 if (callingConvention == CallingConvention.Intercepted) { |
| 115 ++positionalArgumentCount; |
| 116 } |
| 115 List<String> args = | 117 List<String> args = |
| 116 arguments.getRange(0, positionalArgumentCount).map(access).toList(); | 118 arguments.getRange(0, positionalArgumentCount).map(access).toList(); |
| 117 List<String> argumentNames = call.getOrderedNamedArguments(); | 119 List<String> argumentNames = call.getOrderedNamedArguments(); |
| 118 for (int i = 0; i < argumentNames.length; ++i) { | 120 for (int i = 0; i < argumentNames.length; ++i) { |
| 119 String name = argumentNames[i]; | 121 String name = argumentNames[i]; |
| 120 String arg = access(arguments[positionalArgumentCount + i]); | 122 String arg = access(arguments[positionalArgumentCount + i]); |
| 121 args.add("($name: $arg)"); | 123 args.add("($name: $arg)"); |
| 122 } | 124 } |
| 123 return '(${args.join(' ')})'; | 125 return '(${args.join(' ')})'; |
| 124 } | 126 } |
| 125 | 127 |
| 126 String visitInvokeStatic(InvokeStatic node) { | 128 String visitInvokeStatic(InvokeStatic node) { |
| 127 String name = node.target.name; | 129 String name = node.target.name; |
| 128 String cont = access(node.continuation); | |
| 129 String args = formatArguments(node.selector.callStructure, node.arguments); | 130 String args = formatArguments(node.selector.callStructure, node.arguments); |
| 130 return '$indentation(InvokeStatic $name $args $cont)'; | 131 return '(InvokeStatic $name $args)'; |
| 131 } | 132 } |
| 132 | 133 |
| 133 String visitInvokeMethod(InvokeMethod node) { | 134 String visitInvokeMethod(InvokeMethod node) { |
| 134 String name = node.selector.name; | 135 String name = node.selector.name; |
| 135 String rcv = access(node.receiver); | 136 String rcv = access(node.receiver); |
| 136 String cont = access(node.continuation); | |
| 137 String args = formatArguments(node.selector.callStructure, node.arguments, | 137 String args = formatArguments(node.selector.callStructure, node.arguments, |
| 138 isIntercepted: node.receiverIsIntercepted); | 138 node.callingConvention); |
| 139 return '$indentation(InvokeMethod $rcv $name $args $cont)'; | 139 return '(InvokeMethod $rcv $name $args)'; |
| 140 } | 140 } |
| 141 | 141 |
| 142 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 142 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
| 143 String receiver = access(node.receiver); | 143 String receiver = access(node.receiver); |
| 144 String name = node.selector.name; | 144 String name = node.selector.name; |
| 145 String cont = access(node.continuation); | 145 String args = formatArguments(node.selector.callStructure, node.arguments, |
| 146 String args = formatArguments(node.selector.callStructure, node.arguments); | 146 node.callingConvention); |
| 147 return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)'; | 147 return '(InvokeMethodDirectly $receiver $name $args)'; |
| 148 } | 148 } |
| 149 | 149 |
| 150 String visitInvokeConstructor(InvokeConstructor node) { | 150 String visitInvokeConstructor(InvokeConstructor node) { |
| 151 String className; | 151 String className; |
| 152 // TODO(karlklose): for illegal nodes constructed for tests or unresolved | 152 // TODO(karlklose): for illegal nodes constructed for tests or unresolved |
| 153 // constructor calls in the DartBackend, we get an element with no enclosing | 153 // constructor calls in the DartBackend, we get an element with no enclosing |
| 154 // class. Clean this up by introducing a name field to the node and | 154 // class. Clean this up by introducing a name field to the node and |
| 155 // removing [ErroneousElement]s from the IR. | 155 // removing [ErroneousElement]s from the IR. |
| 156 if (node.dartType != null) { | 156 if (node.dartType != null) { |
| 157 className = node.dartType.toString(); | 157 className = node.dartType.toString(); |
| 158 } else { | 158 } else { |
| 159 className = node.target.enclosingClass.name; | 159 className = node.target.enclosingClass.name; |
| 160 } | 160 } |
| 161 String callName; | 161 String callName; |
| 162 if (node.target.name.isEmpty) { | 162 if (node.target.name.isEmpty) { |
| 163 callName = '${className}'; | 163 callName = '${className}'; |
| 164 } else { | 164 } else { |
| 165 callName = '${className}.${node.target.name}'; | 165 callName = '${className}.${node.target.name}'; |
| 166 } | 166 } |
| 167 String cont = access(node.continuation); | |
| 168 String args = formatArguments(node.selector.callStructure, node.arguments); | 167 String args = formatArguments(node.selector.callStructure, node.arguments); |
| 169 return '$indentation(InvokeConstructor $callName $args $cont)'; | 168 return '(InvokeConstructor $callName $args)'; |
| 170 } | 169 } |
| 171 | 170 |
| 172 String visitInvokeContinuation(InvokeContinuation node) { | 171 String visitInvokeContinuation(InvokeContinuation node) { |
| 173 String name = access(node.continuation); | 172 String name = access(node.continuation); |
| 174 if (node.isRecursive) name = 'rec $name'; | 173 if (node.isRecursive) name = 'rec $name'; |
| 175 String args = node.arguments.map(access).join(' '); | 174 String args = node.arguments.map(access).join(' '); |
| 176 return '$indentation(InvokeContinuation $name ($args))'; | 175 return '$indentation(InvokeContinuation $name ($args))'; |
| 177 } | 176 } |
| 178 | 177 |
| 179 String visitThrow(Throw node) { | 178 String visitThrow(Throw node) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 return '(GetMutable ${access(node.variable)})'; | 224 return '(GetMutable ${access(node.variable)})'; |
| 226 } | 225 } |
| 227 | 226 |
| 228 String visitSetMutable(SetMutable node) { | 227 String visitSetMutable(SetMutable node) { |
| 229 String value = access(node.value); | 228 String value = access(node.value); |
| 230 return '(SetMutable ${access(node.variable)} $value)'; | 229 return '(SetMutable ${access(node.variable)} $value)'; |
| 231 } | 230 } |
| 232 | 231 |
| 233 String visitTypeCast(TypeCast node) { | 232 String visitTypeCast(TypeCast node) { |
| 234 String value = access(node.value); | 233 String value = access(node.value); |
| 235 String cont = access(node.continuation); | |
| 236 String typeArguments = node.typeArguments.map(access).join(' '); | 234 String typeArguments = node.typeArguments.map(access).join(' '); |
| 237 return '$indentation(TypeCast $value ${node.dartType}' | 235 return '(TypeCast $value ${node.dartType} ($typeArguments))'; |
| 238 ' ($typeArguments) $cont)'; | |
| 239 } | 236 } |
| 240 | 237 |
| 241 String visitTypeTest(TypeTest node) { | 238 String visitTypeTest(TypeTest node) { |
| 242 String value = access(node.value); | 239 String value = access(node.value); |
| 243 String typeArguments = node.typeArguments.map(access).join(' '); | 240 String typeArguments = node.typeArguments.map(access).join(' '); |
| 244 String interceptor = node.interceptor == null | 241 String interceptor = node.interceptor == null |
| 245 ? '' | 242 ? '' |
| 246 : access(node.interceptor); | 243 : access(node.interceptor); |
| 247 return '(TypeTest $value ${node.dartType} ($typeArguments) ($interceptor))'; | 244 return '(TypeTest $value ${node.dartType} ($typeArguments) ($interceptor))'; |
| 248 } | 245 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 279 } |
| 283 | 280 |
| 284 String visitSetStatic(SetStatic node) { | 281 String visitSetStatic(SetStatic node) { |
| 285 String element = node.element.name; | 282 String element = node.element.name; |
| 286 String value = access(node.value); | 283 String value = access(node.value); |
| 287 return '(SetStatic $element $value)'; | 284 return '(SetStatic $element $value)'; |
| 288 } | 285 } |
| 289 | 286 |
| 290 String visitGetLazyStatic(GetLazyStatic node) { | 287 String visitGetLazyStatic(GetLazyStatic node) { |
| 291 String element = node.element.name; | 288 String element = node.element.name; |
| 292 String cont = access(node.continuation); | 289 return '(GetLazyStatic $element)'; |
| 293 return '$indentation(GetLazyStatic $element $cont)'; | |
| 294 } | 290 } |
| 295 | 291 |
| 296 String visitCreateBox(CreateBox node) { | 292 String visitCreateBox(CreateBox node) { |
| 297 return '(CreateBox)'; | 293 return '(CreateBox)'; |
| 298 } | 294 } |
| 299 | 295 |
| 300 String visitCreateInstance(CreateInstance node) { | 296 String visitCreateInstance(CreateInstance node) { |
| 301 String className = node.classElement.name; | 297 String className = node.classElement.name; |
| 302 String arguments = node.arguments.map(access).join(' '); | 298 String arguments = node.arguments.map(access).join(' '); |
| 303 String typeInformation = node.typeInformation.map(access).join(' '); | 299 String typeInformation = node.typeInformation.map(access).join(' '); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 | 331 |
| 336 String visitApplyBuiltinMethod(ApplyBuiltinMethod node) { | 332 String visitApplyBuiltinMethod(ApplyBuiltinMethod node) { |
| 337 String method = node.method.toString(); | 333 String method = node.method.toString(); |
| 338 String receiver = access(node.receiver); | 334 String receiver = access(node.receiver); |
| 339 String args = node.arguments.map(access).join(' '); | 335 String args = node.arguments.map(access).join(' '); |
| 340 return '(ApplyBuiltinMethod $method $receiver ($args))'; | 336 return '(ApplyBuiltinMethod $method $receiver ($args))'; |
| 341 } | 337 } |
| 342 | 338 |
| 343 String visitForeignCode(ForeignCode node) { | 339 String visitForeignCode(ForeignCode node) { |
| 344 String arguments = node.arguments.map(access).join(' '); | 340 String arguments = node.arguments.map(access).join(' '); |
| 345 String continuation = node.continuation == null ? '' | 341 return '(JS "${node.codeTemplate.source}" ($arguments))'; |
| 346 : ' ${access(node.continuation)}'; | |
| 347 return '$indentation(JS "${node.codeTemplate.source}"' | |
| 348 ' ($arguments)$continuation)'; | |
| 349 } | 342 } |
| 350 | 343 |
| 351 String visitGetLength(GetLength node) { | 344 String visitGetLength(GetLength node) { |
| 352 String object = access(node.object); | 345 String object = access(node.object); |
| 353 return '(GetLength $object)'; | 346 return '(GetLength $object)'; |
| 354 } | 347 } |
| 355 | 348 |
| 356 String visitGetIndex(GetIndex node) { | 349 String visitGetIndex(GetIndex node) { |
| 357 String object = access(node.object); | 350 String object = access(node.object); |
| 358 String index = access(node.index); | 351 String index = access(node.index); |
| 359 return '(GetIndex $object $index)'; | 352 return '(GetIndex $object $index)'; |
| 360 } | 353 } |
| 361 | 354 |
| 362 String visitSetIndex(SetIndex node) { | 355 String visitSetIndex(SetIndex node) { |
| 363 String object = access(node.object); | 356 String object = access(node.object); |
| 364 String index = access(node.index); | 357 String index = access(node.index); |
| 365 String value = access(node.value); | 358 String value = access(node.value); |
| 366 return '(SetIndex $object $index $value)'; | 359 return '(SetIndex $object $index $value)'; |
| 367 } | 360 } |
| 368 | 361 |
| 369 @override | 362 @override |
| 370 String visitAwait(Await node) { | 363 String visitAwait(Await node) { |
| 371 String value = access(node.input); | 364 String value = access(node.input); |
| 372 String continuation = access(node.continuation); | 365 return '(Await $value)'; |
| 373 return '(Await $value $continuation)'; | |
| 374 } | 366 } |
| 375 | 367 |
| 376 @override | 368 @override |
| 377 String visitYield(Yield node) { | 369 String visitYield(Yield node) { |
| 378 String value = access(node.input); | 370 String value = access(node.input); |
| 379 String continuation = access(node.continuation); | 371 return '(Yield $value)'; |
| 380 return '(Yield $value $continuation)'; | |
| 381 } | 372 } |
| 382 | 373 |
| 383 String visitRefinement(Refinement node) { | 374 String visitRefinement(Refinement node) { |
| 384 String value = access(node.value); | 375 String value = access(node.value); |
| 385 return '(Refinement $value ${node.type})'; | 376 return '(Refinement $value ${node.type})'; |
| 386 } | 377 } |
| 387 } | 378 } |
| 388 | 379 |
| 389 class ConstantStringifier extends ConstantValueVisitor<String, Null> { | 380 class ConstantStringifier extends ConstantValueVisitor<String, Null> { |
| 390 // Some of these methods are unimplemented because we haven't had a need | 381 // Some of these methods are unimplemented because we haven't had a need |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 void setReturnContinuation(Continuation node) { | 482 void setReturnContinuation(Continuation node) { |
| 492 assert(!_names.containsKey(node) || _names[node] == 'return'); | 483 assert(!_names.containsKey(node) || _names[node] == 'return'); |
| 493 _names[node] = 'return'; | 484 _names[node] = 'return'; |
| 494 } | 485 } |
| 495 | 486 |
| 496 String getName(Node node) { | 487 String getName(Node node) { |
| 497 if (!_names.containsKey(node)) return 'MISSING_NAME'; | 488 if (!_names.containsKey(node)) return 'MISSING_NAME'; |
| 498 return _names[node]; | 489 return _names[node]; |
| 499 } | 490 } |
| 500 } | 491 } |
| OLD | NEW |