| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 String name = newValueName(node.primitive); | 69 String name = newValueName(node.primitive); |
| 70 String value = visit(node.primitive); | 70 String value = visit(node.primitive); |
| 71 String body = indentBlock(() => visit(node.body)); | 71 String body = indentBlock(() => visit(node.body)); |
| 72 return '$indentation(LetPrim ($name $value)\n$body)'; | 72 return '$indentation(LetPrim ($name $value)\n$body)'; |
| 73 } | 73 } |
| 74 | 74 |
| 75 String visitLetCont(LetCont node) { | 75 String visitLetCont(LetCont node) { |
| 76 String conts; | 76 String conts; |
| 77 bool first = true; | 77 bool first = true; |
| 78 for (Continuation continuation in node.continuations) { | 78 for (Continuation continuation in node.continuations) { |
| 79 String name = newContinuationName(continuation); | |
| 80 if (continuation.isRecursive) name = 'rec $name'; | |
| 81 // TODO(karlklose): this should be changed to `.map(visit).join(' ')` and | |
| 82 // should recurse to [visit]. Currently we can't do that, because the | |
| 83 // unstringifier_test produces [LetConts] with dummy arguments on them. | |
| 84 String parameters = continuation.parameters | |
| 85 .map((p) => '${decorator(p, newValueName(p))}') | |
| 86 .join(' '); | |
| 87 String body = | |
| 88 indentBlock(() => indentBlock(() => visit(continuation.body))); | |
| 89 if (first) { | 79 if (first) { |
| 90 first = false; | 80 first = false; |
| 91 conts = '($name ($parameters)\n$body)'; | 81 conts = visit(continuation); |
| 92 } else { | 82 } else { |
| 93 // Each subsequent line is indented additional spaces to align it | 83 // Each subsequent line is indented additional spaces to align it |
| 94 // with the previous continuation. | 84 // with the previous continuation. |
| 95 String indent = '$indentation${' ' * '(LetCont ('.length}'; | 85 String indent = '$indentation${' ' * '(LetCont ('.length}'; |
| 96 conts = '$conts\n$indent($name ($parameters)\n$body)'; | 86 conts = '$conts\n$indent${visit(continuation)}'; |
| 97 } | 87 } |
| 98 } | 88 } |
| 99 String body = indentBlock(() => visit(node.body)); | 89 String body = indentBlock(() => visit(node.body)); |
| 100 return '$indentation(LetCont ($conts)\n$body)'; | 90 return '$indentation(LetCont ($conts)\n$body)'; |
| 101 } | 91 } |
| 102 | 92 |
| 103 String visitLetHandler(LetHandler node) { | 93 String visitLetHandler(LetHandler node) { |
| 104 // There are no explicit references to the handler, so we leave it | 94 // There are no explicit references to the handler, so we leave it |
| 105 // anonymous in the printed representation. | 95 // anonymous in the printed representation. |
| 106 String parameters = node.handler.parameters | 96 String parameters = node.handler.parameters |
| 107 .map((p) => '${decorator(p, newValueName(p))}') | 97 .map((p) => '${decorator(p, newValueName(p))}') |
| 108 .join(' '); | 98 .join(' '); |
| 109 String handlerBody = | 99 String handlerBody = |
| 110 indentBlock(() => indentBlock(() => visit(node.handler.body))); | 100 indentBlock(() => indentBlock(() => visit(node.handler.body))); |
| 111 String body = indentBlock(() => visit(node.body)); | 101 String body = indentBlock(() => visit(node.body)); |
| 112 return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)'; | 102 return '$indentation(LetHandler (($parameters)\n$handlerBody)\n$body)'; |
| 113 } | 103 } |
| 114 | 104 |
| 115 String visitLetMutable(LetMutable node) { | 105 String visitLetMutable(LetMutable node) { |
| 116 String name = visit(node.variable); | 106 String name = visit(node.variable); |
| 117 String value = access(node.value); | 107 String value = access(node.value); |
| 118 String body = indentBlock(() => visit(node.body)); | 108 String body = indentBlock(() => visit(node.body)); |
| 119 return '$indentation(LetMutable ($name $value)\n$body)'; | 109 return '$indentation(LetMutable ($name $value)\n$body)'; |
| 120 } | 110 } |
| 121 | 111 |
| 122 String formatArguments(CallStructure call, | 112 String formatArguments(CallStructure call, |
| 123 List<Reference<Primitive>> arguments) { | 113 List<Reference<Primitive>> arguments, |
| 114 {bool isIntercepted: false}) { |
| 124 int positionalArgumentCount = call.positionalArgumentCount; | 115 int positionalArgumentCount = call.positionalArgumentCount; |
| 125 List<String> args = new List<String>(); | 116 if (isIntercepted) ++positionalArgumentCount; |
| 126 args.addAll(arguments.getRange(0, positionalArgumentCount).map(access)); | 117 List<String> args = |
| 118 arguments.getRange(0, positionalArgumentCount).map(access).toList(); |
| 127 List<String> argumentNames = call.getOrderedNamedArguments(); | 119 List<String> argumentNames = call.getOrderedNamedArguments(); |
| 128 for (int i = 0; i < argumentNames.length; ++i) { | 120 for (int i = 0; i < argumentNames.length; ++i) { |
| 129 String name = argumentNames[i]; | 121 String name = argumentNames[i]; |
| 130 String arg = access(arguments[positionalArgumentCount + i]); | 122 String arg = access(arguments[positionalArgumentCount + i]); |
| 131 args.add("($name: $arg)"); | 123 args.add("($name: $arg)"); |
| 132 } | 124 } |
| 133 return '(${args.join(' ')})'; | 125 return '(${args.join(' ')})'; |
| 134 } | 126 } |
| 135 | 127 |
| 136 String visitInvokeStatic(InvokeStatic node) { | 128 String visitInvokeStatic(InvokeStatic node) { |
| 137 String name = node.target.name; | 129 String name = node.target.name; |
| 138 String cont = access(node.continuation); | 130 String cont = access(node.continuation); |
| 139 String args = formatArguments(node.selector.callStructure, node.arguments); | 131 String args = formatArguments(node.selector.callStructure, node.arguments); |
| 140 return '$indentation(InvokeStatic $name $args $cont)'; | 132 return '$indentation(InvokeStatic $name $args $cont)'; |
| 141 } | 133 } |
| 142 | 134 |
| 143 String visitInvokeMethod(InvokeMethod node) { | 135 String visitInvokeMethod(InvokeMethod node) { |
| 144 String name = node.selector.name; | 136 String name = node.selector.name; |
| 145 String rcv = access(node.receiver); | 137 String rcv = access(node.receiver); |
| 146 String cont = access(node.continuation); | 138 String cont = access(node.continuation); |
| 147 String args = formatArguments(node.selector.callStructure, node.arguments); | 139 String args = formatArguments(node.selector.callStructure, node.arguments, |
| 140 isIntercepted: node.receiverIsIntercepted); |
| 148 return '$indentation(InvokeMethod $rcv $name $args $cont)'; | 141 return '$indentation(InvokeMethod $rcv $name $args $cont)'; |
| 149 } | 142 } |
| 150 | 143 |
| 151 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 144 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
| 152 String receiver = access(node.receiver); | 145 String receiver = access(node.receiver); |
| 153 String name = node.selector.name; | 146 String name = node.selector.name; |
| 154 String cont = access(node.continuation); | 147 String cont = access(node.continuation); |
| 155 String args = formatArguments(node.selector.callStructure, node.arguments); | 148 String args = formatArguments(node.selector.callStructure, node.arguments); |
| 156 return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)'; | 149 return '$indentation(InvokeMethodDirectly $receiver $name $args $cont)'; |
| 157 } | 150 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 211 return '(Constant $value)'; | 204 return '(Constant $value)'; |
| 212 } | 205 } |
| 213 | 206 |
| 214 String visitCreateFunction(CreateFunction node) { | 207 String visitCreateFunction(CreateFunction node) { |
| 215 String function = | 208 String function = |
| 216 indentBlock(() => indentBlock(() => visit(node.definition))); | 209 indentBlock(() => indentBlock(() => visit(node.definition))); |
| 217 return '(CreateFunction\n$function)'; | 210 return '(CreateFunction\n$function)'; |
| 218 } | 211 } |
| 219 | 212 |
| 220 String visitContinuation(Continuation node) { | 213 String visitContinuation(Continuation node) { |
| 221 // Continuations are visited directly in visitLetCont. | 214 String name = newContinuationName(node); |
| 222 return '(Unexpected Continuation)'; | 215 if (node.isRecursive) name = 'rec $name'; |
| 216 // TODO(karlklose): this should be changed to `.map(visit).join(' ')` and |
| 217 // should recurse to [visit]. Currently we can't do that, because the |
| 218 // unstringifier_test produces [LetConts] with dummy arguments on them. |
| 219 String parameters = node.parameters |
| 220 .map((p) => '${decorator(p, newValueName(p))}') |
| 221 .join(' '); |
| 222 String body = indentBlock(() => indentBlock(() => visit(node.body))); |
| 223 return '($name ($parameters)\n$body)'; |
| 223 } | 224 } |
| 224 | 225 |
| 225 String visitGetMutable(GetMutable node) { | 226 String visitGetMutable(GetMutable node) { |
| 226 return '(GetMutable ${access(node.variable)})'; | 227 return '(GetMutable ${access(node.variable)})'; |
| 227 } | 228 } |
| 228 | 229 |
| 229 String visitSetMutable(SetMutable node) { | 230 String visitSetMutable(SetMutable node) { |
| 230 String value = access(node.value); | 231 String value = access(node.value); |
| 231 return '(SetMutable ${access(node.variable)} $value)'; | 232 return '(SetMutable ${access(node.variable)} $value)'; |
| 232 } | 233 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 } | 288 } |
| 288 | 289 |
| 289 String visitCreateBox(CreateBox node) { | 290 String visitCreateBox(CreateBox node) { |
| 290 return '(CreateBox)'; | 291 return '(CreateBox)'; |
| 291 } | 292 } |
| 292 | 293 |
| 293 String visitCreateInstance(CreateInstance node) { | 294 String visitCreateInstance(CreateInstance node) { |
| 294 String className = node.classElement.name; | 295 String className = node.classElement.name; |
| 295 String arguments = node.arguments.map(access).join(' '); | 296 String arguments = node.arguments.map(access).join(' '); |
| 296 String typeInformation = node.typeInformation.map(access).join(' '); | 297 String typeInformation = node.typeInformation.map(access).join(' '); |
| 297 return '(CreateInstance $className ($arguments)$typeInformation)'; | 298 return '(CreateInstance $className ($arguments) ($typeInformation))'; |
| 298 } | 299 } |
| 299 | 300 |
| 300 String visitInterceptor(Interceptor node) { | 301 String visitInterceptor(Interceptor node) { |
| 301 return '(Interceptor ${access(node.input)})'; | 302 return '(Interceptor ${access(node.input)})'; |
| 302 } | 303 } |
| 303 | 304 |
| 304 String visitReifyRuntimeType(ReifyRuntimeType node) { | 305 String visitReifyRuntimeType(ReifyRuntimeType node) { |
| 305 return '(ReifyRuntimeType ${access(node.value)})'; | 306 return '(ReifyRuntimeType ${access(node.value)})'; |
| 306 } | 307 } |
| 307 | 308 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 void setReturnContinuation(Continuation node) { | 479 void setReturnContinuation(Continuation node) { |
| 479 assert(!_names.containsKey(node) || _names[node] == 'return'); | 480 assert(!_names.containsKey(node) || _names[node] == 'return'); |
| 480 _names[node] = 'return'; | 481 _names[node] = 'return'; |
| 481 } | 482 } |
| 482 | 483 |
| 483 String getName(Node node) { | 484 String getName(Node node) { |
| 484 if (!_names.containsKey(node)) return 'MISSING_NAME'; | 485 if (!_names.containsKey(node)) return 'MISSING_NAME'; |
| 485 return _names[node]; | 486 return _names[node]; |
| 486 } | 487 } |
| 487 } | 488 } |
| OLD | NEW |