| 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/universe.dart' show Selector; | 9 import '../universe/universe.dart' show Selector; |
| 10 import '../types/types.dart' show TypeMask; | 10 import '../types/types.dart' show TypeMask; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 /// Call `cont` with `obj.field + 1` as argument: | 26 /// Call `cont` with `obj.field + 1` as argument: |
| 27 /// | 27 /// |
| 28 /// CpsFragment cps = new CpsFragment(); | 28 /// CpsFragment cps = new CpsFragment(); |
| 29 /// var fieldValue = cps.letPrim(new GetField(obj, field)); | 29 /// var fieldValue = cps.letPrim(new GetField(obj, field)); |
| 30 /// var plusOne = cps.applyBuiltin(BuiltinOperator.NumAdd, | 30 /// var plusOne = cps.applyBuiltin(BuiltinOperator.NumAdd, |
| 31 /// [fieldValue, cps.makeOne()]); | 31 /// [fieldValue, cps.makeOne()]); |
| 32 /// cps.invokeContinuation(cont, [plusOne]); | 32 /// cps.invokeContinuation(cont, [plusOne]); |
| 33 /// | 33 /// |
| 34 /// If `condition` is true then invoke `cont1`, else `cont2`. | 34 /// If `condition` is true then invoke `cont1`, else `cont2`. |
| 35 /// | 35 /// |
| 36 /// cps.ifTrue(condition).invokeContinuation(cont1, []); | 36 /// cps.ifTruthy(condition).invokeContinuation(cont1, []); |
| 37 /// cps.invokeContinuation(cont2, []); | 37 /// cps.invokeContinuation(cont2, []); |
| 38 /// | 38 /// |
| 39 /// If `condition` is true then invoke `cont` with a bound primitive: | 39 /// If `condition` is true then invoke `cont` with a bound primitive: |
| 40 /// | 40 /// |
| 41 /// CpsFragment branch = cps.ifTrue(condition); | 41 /// CpsFragment branch = cps.ifTruthy(condition); |
| 42 /// branch.invokeContinuation(cont, [branch.letPrim(arg)]); | 42 /// branch.invokeContinuation(cont, [branch.letPrim(arg)]); |
| 43 /// | 43 /// |
| 44 /// Loop and call a method until it returns false: | 44 /// Loop and call a method until it returns false: |
| 45 /// | 45 /// |
| 46 /// Continuation loop = cps.beginLoop(); | 46 /// Continuation loop = cps.beginLoop(); |
| 47 /// var result = cps.invokeMethod(receiver, selector, ...); | 47 /// var result = cps.invokeMethod(receiver, selector, ...); |
| 48 /// cps.ifFalse(result).invokeContinuation(exit, []); | 48 /// cps.ifFalsy(result).invokeContinuation(exit, []); |
| 49 /// cps.continueLoop(loop); | 49 /// cps.continueLoop(loop); |
| 50 /// | 50 /// |
| 51 class CpsFragment { | 51 class CpsFragment { |
| 52 /// The root of the IR built using this fragment. | 52 /// The root of the IR built using this fragment. |
| 53 Expression root; | 53 Expression root; |
| 54 | 54 |
| 55 /// Node whose body is the hole in this CPS fragment. May be null. | 55 /// Node whose body is the hole in this CPS fragment. May be null. |
| 56 InteriorNode context; | 56 InteriorNode context; |
| 57 | 57 |
| 58 /// Source information to attach to every IR node created in the fragment. | 58 /// Source information to attach to every IR node created in the fragment. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 /// This closes the fragment; no more nodes may be inserted. | 191 /// This closes the fragment; no more nodes may be inserted. |
| 192 void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) { | 192 void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) { |
| 193 put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true)); | 193 put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true)); |
| 194 } | 194 } |
| 195 | 195 |
| 196 /// Branch on [condition]. | 196 /// Branch on [condition]. |
| 197 /// | 197 /// |
| 198 /// Returns a new fragment for the 'then' branch. | 198 /// Returns a new fragment for the 'then' branch. |
| 199 /// | 199 /// |
| 200 /// The 'else' branch becomes the new hole. | 200 /// The 'else' branch becomes the new hole. |
| 201 CpsFragment ifTrue(Primitive condition) { | 201 CpsFragment ifTruthy(Primitive condition) { |
| 202 Continuation trueCont = new Continuation(<Parameter>[]); | 202 Continuation trueCont = new Continuation(<Parameter>[]); |
| 203 Continuation falseCont = new Continuation(<Parameter>[]); | 203 Continuation falseCont = new Continuation(<Parameter>[]); |
| 204 put(new LetCont.two(trueCont, falseCont, | 204 put(new LetCont.two(trueCont, falseCont, |
| 205 new Branch(new IsTrue(condition), trueCont, falseCont))); | 205 new Branch.loose(condition, trueCont, falseCont))); |
| 206 context = falseCont; | 206 context = falseCont; |
| 207 return new CpsFragment(sourceInformation, trueCont); | 207 return new CpsFragment(sourceInformation, trueCont); |
| 208 } | 208 } |
| 209 | 209 |
| 210 /// Branch on [condition]. | 210 /// Branch on [condition]. |
| 211 /// | 211 /// |
| 212 /// Returns a new fragment for the 'else' branch. | 212 /// Returns a new fragment for the 'else' branch. |
| 213 /// | 213 /// |
| 214 /// The 'then' branch becomes the new hole. | 214 /// The 'then' branch becomes the new hole. |
| 215 CpsFragment ifFalse(Primitive condition) { | 215 CpsFragment ifFalsy(Primitive condition) { |
| 216 Continuation trueCont = new Continuation(<Parameter>[]); | 216 Continuation trueCont = new Continuation(<Parameter>[]); |
| 217 Continuation falseCont = new Continuation(<Parameter>[]); | 217 Continuation falseCont = new Continuation(<Parameter>[]); |
| 218 put(new LetCont.two(trueCont, falseCont, | 218 put(new LetCont.two(trueCont, falseCont, |
| 219 new Branch(new IsTrue(condition), trueCont, falseCont))); | 219 new Branch.loose(condition, trueCont, falseCont))); |
| 220 context = trueCont; | 220 context = trueCont; |
| 221 return new CpsFragment(sourceInformation, falseCont); | 221 return new CpsFragment(sourceInformation, falseCont); |
| 222 } | 222 } |
| 223 | 223 |
| 224 /// Create a new empty continuation and bind it here. | 224 /// Create a new empty continuation and bind it here. |
| 225 /// | 225 /// |
| 226 /// Convenient for making a join point where multiple branches | 226 /// Convenient for making a join point where multiple branches |
| 227 /// meet later. | 227 /// meet later. |
| 228 /// | 228 /// |
| 229 /// The LetCont body becomes the new hole. | 229 /// The LetCont body becomes the new hole. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 letPrim(new SetMutable(variable, value)); | 291 letPrim(new SetMutable(variable, value)); |
| 292 } | 292 } |
| 293 | 293 |
| 294 /// Declare a new mutable variable. | 294 /// Declare a new mutable variable. |
| 295 void letMutable(MutableVariable variable, Primitive initialValue) { | 295 void letMutable(MutableVariable variable, Primitive initialValue) { |
| 296 LetMutable let = new LetMutable(variable, initialValue); | 296 LetMutable let = new LetMutable(variable, initialValue); |
| 297 put(let); | 297 put(let); |
| 298 context = let; | 298 context = let; |
| 299 } | 299 } |
| 300 } | 300 } |
| OLD | NEW |