| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 cps_ir.cps_fragment; | 5 library cps_ir.cps_fragment; |
| 6 | 6 |
| 7 import 'cps_ir_nodes.dart'; | 7 import 'cps_ir_nodes.dart'; |
| 8 import '../constants/values.dart'; | 8 import '../constants/values.dart'; |
| 9 import '../universe/selector.dart' show Selector; | 9 import '../universe/selector.dart' show Selector; |
| 10 import '../types/types.dart' show TypeMask; | 10 import '../types/types.dart' show TypeMask; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 Primitive invokeBuiltin(BuiltinMethod method, | 116 Primitive invokeBuiltin(BuiltinMethod method, |
| 117 Primitive receiver, | 117 Primitive receiver, |
| 118 List<Primitive> arguments, | 118 List<Primitive> arguments, |
| 119 {bool receiverIsNotNull: false}) { | 119 {bool receiverIsNotNull: false}) { |
| 120 ApplyBuiltinMethod apply = | 120 ApplyBuiltinMethod apply = |
| 121 new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation); | 121 new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation); |
| 122 apply.receiverIsNotNull = receiverIsNotNull; | 122 apply.receiverIsNotNull = receiverIsNotNull; |
| 123 return letPrim(apply); | 123 return letPrim(apply); |
| 124 } | 124 } |
| 125 | 125 |
| 126 /// Inserts an invocation. binds its continuation, and returns the | 126 /// Inserts an invocation and returns a primitive holding the returned value. |
| 127 /// continuation parameter (i.e. the return value of the invocation). | 127 Primitive invokeMethod(Primitive receiver, |
| 128 /// | |
| 129 /// The continuation body becomes the new hole. | |
| 130 Parameter invokeMethod(Primitive receiver, | |
| 131 Selector selector, | 128 Selector selector, |
| 132 TypeMask mask, | 129 TypeMask mask, |
| 133 List<Primitive> arguments) { | 130 List<Primitive> arguments) { |
| 134 Continuation cont = new Continuation(<Parameter>[new Parameter(null)]); | 131 return letPrim(new InvokeMethod(receiver, selector, mask, arguments, |
| 135 InvokeMethod invoke = | 132 sourceInformation)); |
| 136 new InvokeMethod(receiver, selector, mask, arguments, cont, | |
| 137 sourceInformation); | |
| 138 put(new LetCont(cont, invoke)); | |
| 139 context = cont; | |
| 140 return cont.parameters.single; | |
| 141 } | 133 } |
| 142 | 134 |
| 143 /// Inserts an invocation. binds its continuation, and returns the | 135 /// Inserts an invocation and returns a primitive holding the returned value. |
| 144 /// continuation parameter (i.e. the return value of the invocation). | 136 Primitive invokeStatic(FunctionElement target, List<Primitive> arguments) { |
| 145 /// | 137 return letPrim(new InvokeStatic(target, new Selector.fromElement(target), |
| 146 /// The continuation body becomes the new hole. | 138 arguments, sourceInformation)); |
| 147 Parameter invokeStatic(FunctionElement target, List<Primitive> arguments) { | |
| 148 Continuation cont = new Continuation(<Parameter>[new Parameter(null)]); | |
| 149 InvokeStatic invoke = | |
| 150 new InvokeStatic(target, new Selector.fromElement(target), arguments, | |
| 151 cont, sourceInformation); | |
| 152 put(new LetCont(cont, invoke)); | |
| 153 context = cont; | |
| 154 return cont.parameters.single; | |
| 155 } | 139 } |
| 156 | 140 |
| 157 /// Inserts an invocation to a static function that throws an error. | 141 /// Inserts an invocation to a static function that throws an error. |
| 158 /// | 142 /// |
| 159 /// This closes the fragment; no more nodes may be added. | 143 /// This closes the fragment; no more nodes may be added. |
| 160 void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) { | 144 void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) { |
| 161 invokeStatic(target, arguments); | 145 invokeStatic(target, arguments); |
| 162 put(new Unreachable()); | 146 put(new Unreachable()); |
| 163 } | 147 } |
| 164 | 148 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 /// // Build the fail branch | 230 /// // Build the fail branch |
| 247 /// cps.insideContinuation(fail) | 231 /// cps.insideContinuation(fail) |
| 248 /// ..invokeStaticThrower(...); | 232 /// ..invokeStaticThrower(...); |
| 249 /// | 233 /// |
| 250 /// // Go to the happy branch | 234 /// // Go to the happy branch |
| 251 /// cps.invokeContinuation(cont..) | 235 /// cps.invokeContinuation(cont..) |
| 252 /// | 236 /// |
| 253 Continuation letCont([List<Parameter> parameters]) { | 237 Continuation letCont([List<Parameter> parameters]) { |
| 254 if (parameters == null) parameters = <Parameter>[]; | 238 if (parameters == null) parameters = <Parameter>[]; |
| 255 Continuation cont = new Continuation(parameters); | 239 Continuation cont = new Continuation(parameters); |
| 240 bindContinuation(cont); |
| 241 return cont; |
| 242 } |
| 243 |
| 244 /// Binds an existing continuation at this position. |
| 245 /// |
| 246 /// The LetCont body becomes the new hole. |
| 247 void bindContinuation(Continuation cont) { |
| 256 LetCont let = new LetCont(cont, null); | 248 LetCont let = new LetCont(cont, null); |
| 257 put(let); | 249 put(let); |
| 258 context = let; | 250 context = let; |
| 259 return cont; | 251 } |
| 252 |
| 253 /// Inlines [target] at the current position, substituting the provided |
| 254 /// arguments. |
| 255 /// |
| 256 /// Returns a primitive containing the function's return value. |
| 257 /// |
| 258 /// The new hole is the the point after [target] has returned. The fragment |
| 259 /// remains open, even if [target] never returns. |
| 260 /// |
| 261 /// The [target] function is destroyed and should not be reused. |
| 262 Primitive inlineFunction(FunctionDefinition target, |
| 263 Primitive thisArgument, |
| 264 List<Primitive> arguments, |
| 265 {Entity hint}) { |
| 266 if (thisArgument != null) { |
| 267 target.thisParameter.replaceUsesWith(thisArgument); |
| 268 } |
| 269 for (int i = 0; i < arguments.length; ++i) { |
| 270 target.parameters[i].replaceUsesWith(arguments[i]); |
| 271 } |
| 272 Continuation returnCont = target.returnContinuation; |
| 273 bindContinuation(returnCont); |
| 274 put(target.body); |
| 275 Parameter returnValue = returnCont.parameters.single; |
| 276 returnValue.hint = hint; |
| 277 context = returnCont; |
| 278 return returnValue; |
| 260 } | 279 } |
| 261 | 280 |
| 262 /// Returns a fragment whose context is the body of the given continuation. | 281 /// Returns a fragment whose context is the body of the given continuation. |
| 263 /// | 282 /// |
| 264 /// Does not change the state of this CPS fragment. | 283 /// Does not change the state of this CPS fragment. |
| 265 /// | 284 /// |
| 266 /// Useful for building the body of a continuation created using [letCont]. | 285 /// Useful for building the body of a continuation created using [letCont]. |
| 267 CpsFragment insideContinuation(Continuation cont) { | 286 CpsFragment insideContinuation(Continuation cont) { |
| 268 return new CpsFragment(sourceInformation, cont); | 287 return new CpsFragment(sourceInformation, cont); |
| 269 } | 288 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 } | 334 } |
| 316 } | 335 } |
| 317 | 336 |
| 318 /// Removes [node], unlinking all its references and replaces it with [newNode]. | 337 /// Removes [node], unlinking all its references and replaces it with [newNode]. |
| 319 void destroyAndReplace(Expression node, Expression newNode) { | 338 void destroyAndReplace(Expression node, Expression newNode) { |
| 320 InteriorNode parent = node.parent; | 339 InteriorNode parent = node.parent; |
| 321 RemovalVisitor.remove(node); | 340 RemovalVisitor.remove(node); |
| 322 parent.body = newNode; | 341 parent.body = newNode; |
| 323 newNode.parent = parent; | 342 newNode.parent = parent; |
| 324 } | 343 } |
| OLD | NEW |