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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 } | 91 } |
92 | 92 |
93 /// Main entry point for creating a [String] from a [Node]. All recursive | 93 /// Main entry point for creating a [String] from a [Node]. All recursive |
94 /// calls must go through this method. | 94 /// calls must go through this method. |
95 String visit(Node node) { | 95 String visit(Node node) { |
96 if (node == null) return '**** NULL ****'; | 96 if (node == null) return '**** NULL ****'; |
97 String s = node.accept(this); | 97 String s = node.accept(this); |
98 return decorator(node, s); | 98 return decorator(node, s); |
99 } | 99 } |
100 | 100 |
101 String formatThisParameter(Parameter thisParameter) { | 101 String formatOptionalParameter(Parameter parameter) { |
102 return thisParameter == null ? '()' : '(${visit(thisParameter)})'; | 102 return parameter == null ? '()' : '(${visit(parameter)})'; |
103 } | 103 } |
104 | 104 |
105 String visitFunctionDefinition(FunctionDefinition node) { | 105 String visitFunctionDefinition(FunctionDefinition node) { |
106 String name = node.element.name; | 106 String name = node.element.name; |
107 String thisParameter = formatThisParameter(node.thisParameter); | 107 String interceptorParameter = |
| 108 formatOptionalParameter(node.interceptorParameter); |
| 109 String thisParameter = formatOptionalParameter(node.receiverParameter); |
108 String parameters = node.parameters.map(visit).join(' '); | 110 String parameters = node.parameters.map(visit).join(' '); |
109 namer.setReturnContinuation(node.returnContinuation); | 111 namer.setReturnContinuation(node.returnContinuation); |
110 String body = indentBlock(() => visit(node.body)); | 112 String body = indentBlock(() => visit(node.body)); |
111 return '$indentation' | 113 return '$indentation' |
112 '(FunctionDefinition $name $thisParameter ($parameters) return\n' | 114 '(FunctionDefinition $name $interceptorParameter $thisParameter ' |
| 115 '($parameters) return\n' |
113 '$body)'; | 116 '$body)'; |
114 } | 117 } |
115 | 118 |
116 String visitLetPrim(LetPrim node) { | 119 String visitLetPrim(LetPrim node) { |
117 String name = newValueName(node.primitive); | 120 String name = newValueName(node.primitive); |
118 String value = visit(node.primitive); | 121 String value = visit(node.primitive); |
119 String bindings = '($name $value)'; | 122 String bindings = '($name $value)'; |
120 String skip = ' ' * '(LetPrim ('.length; | 123 String skip = ' ' * '(LetPrim ('.length; |
121 while (node.body is LetPrim) { | 124 while (node.body is LetPrim) { |
122 node = node.body; | 125 node = node.body; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 String name = visit(node.variable); | 175 String name = visit(node.variable); |
173 String value = access(node.valueRef); | 176 String value = access(node.valueRef); |
174 String body = indentBlock(() => visit(node.body)); | 177 String body = indentBlock(() => visit(node.body)); |
175 return '$indentation(LetMutable ($name $value)\n$body)'; | 178 return '$indentation(LetMutable ($name $value)\n$body)'; |
176 } | 179 } |
177 | 180 |
178 String formatArguments(CallStructure call, | 181 String formatArguments(CallStructure call, |
179 List<Reference<Primitive>> arguments, | 182 List<Reference<Primitive>> arguments, |
180 [CallingConvention callingConvention = CallingConvention.Normal]) { | 183 [CallingConvention callingConvention = CallingConvention.Normal]) { |
181 int positionalArgumentCount = call.positionalArgumentCount; | 184 int positionalArgumentCount = call.positionalArgumentCount; |
182 if (callingConvention == CallingConvention.Intercepted || | |
183 callingConvention == CallingConvention.DummyIntercepted) { | |
184 ++positionalArgumentCount; | |
185 } | |
186 List<String> args = | 185 List<String> args = |
187 arguments.take(positionalArgumentCount).map(access).toList(); | 186 arguments.take(positionalArgumentCount).map(access).toList(); |
188 List<String> argumentNames = call.getOrderedNamedArguments(); | 187 List<String> argumentNames = call.getOrderedNamedArguments(); |
189 for (int i = 0; i < argumentNames.length; ++i) { | 188 for (int i = 0; i < argumentNames.length; ++i) { |
190 String name = argumentNames[i]; | 189 String name = argumentNames[i]; |
191 String arg = access(arguments[positionalArgumentCount + i]); | 190 String arg = access(arguments[positionalArgumentCount + i]); |
192 args.add("($name: $arg)"); | 191 args.add("($name: $arg)"); |
193 } | 192 } |
194 // Constructors can have type parameter after the named arguments. | 193 // Constructors can have type parameter after the named arguments. |
195 args.addAll( | 194 args.addAll( |
196 arguments.skip(positionalArgumentCount + argumentNames.length) | 195 arguments.skip(positionalArgumentCount + argumentNames.length) |
197 .map(access)); | 196 .map(access)); |
198 return '(${args.join(' ')})'; | 197 return '(${args.join(' ')})'; |
199 } | 198 } |
200 | 199 |
201 String visitInvokeStatic(InvokeStatic node) { | 200 String visitInvokeStatic(InvokeStatic node) { |
202 String name = node.target.name; | 201 String name = node.target.name; |
203 String args = formatArguments(node.selector.callStructure, node.argumentRefs
); | 202 String args = formatArguments(node.selector.callStructure, node.argumentRefs
); |
204 return '(InvokeStatic $name $args)'; | 203 return '(InvokeStatic $name $args)'; |
205 } | 204 } |
206 | 205 |
207 String visitInvokeMethod(InvokeMethod node) { | 206 String visitInvokeMethod(InvokeMethod node) { |
208 String name = node.selector.name; | 207 String name = node.selector.name; |
209 String rcv = access(node.receiverRef); | 208 String interceptor = optionalAccess(node.interceptorRef); |
210 String args = formatArguments(node.selector.callStructure, node.argumentRefs
, | 209 String receiver = access(node.receiverRef); |
211 node.callingConvention); | 210 String arguments = formatArguments(node.selector.callStructure, |
212 return '(InvokeMethod $rcv $name $args)'; | 211 node.argumentRefs, node.callingConvention); |
| 212 return '(InvokeMethod $interceptor $receiver $name $arguments)'; |
213 } | 213 } |
214 | 214 |
215 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { | 215 String visitInvokeMethodDirectly(InvokeMethodDirectly node) { |
| 216 String interceptor = optionalAccess(node.interceptorRef); |
216 String receiver = access(node.receiverRef); | 217 String receiver = access(node.receiverRef); |
217 String name = node.selector.name; | 218 String name = node.selector.name; |
218 String args = formatArguments(node.selector.callStructure, node.argumentRefs
, | 219 String arguments = formatArguments(node.selector.callStructure, |
219 node.callingConvention); | 220 node.argumentRefs, node.callingConvention); |
220 return '(InvokeMethodDirectly $receiver $name $args)'; | 221 return '(InvokeMethodDirectly $interceptor $receiver $name $arguments)'; |
221 } | 222 } |
222 | 223 |
223 String visitInvokeConstructor(InvokeConstructor node) { | 224 String visitInvokeConstructor(InvokeConstructor node) { |
224 // TODO(karlklose): for illegal nodes constructed for tests or unresolved | 225 // TODO(karlklose): for illegal nodes constructed for tests or unresolved |
225 // constructor calls in the DartBackend, we get an element with no enclosing | 226 // constructor calls in the DartBackend, we get an element with no enclosing |
226 // class. Clean this up by introducing a name field to the node and | 227 // class. Clean this up by introducing a name field to the node and |
227 // removing [ErroneousElement]s from the IR. | 228 // removing [ErroneousElement]s from the IR. |
228 String name = node.dartType != null | 229 String name = node.dartType != null |
229 ? node.dartType.toString() | 230 ? node.dartType.toString() |
230 : node.target.enclosingClass.name; | 231 : node.target.enclosingClass.name; |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 void setReturnContinuation(Continuation node) { | 562 void setReturnContinuation(Continuation node) { |
562 assert(!_names.containsKey(node) || _names[node] == 'return'); | 563 assert(!_names.containsKey(node) || _names[node] == 'return'); |
563 _names[node] = 'return'; | 564 _names[node] = 'return'; |
564 } | 565 } |
565 | 566 |
566 String getName(Node node) { | 567 String getName(Node node) { |
567 if (!_names.containsKey(node)) return 'MISSING_NAME'; | 568 if (!_names.containsKey(node)) return 'MISSING_NAME'; |
568 return _names[node]; | 569 return _names[node]; |
569 } | 570 } |
570 } | 571 } |
OLD | NEW |