| 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 111 |
| 112 /// Invoke a built-in operator. | 112 /// Invoke a built-in operator. |
| 113 Primitive applyBuiltin(BuiltinOperator op, List<Primitive> args) { | 113 Primitive applyBuiltin(BuiltinOperator op, List<Primitive> args) { |
| 114 return letPrim(new ApplyBuiltinOperator(op, args, sourceInformation)); | 114 return letPrim(new ApplyBuiltinOperator(op, args, sourceInformation)); |
| 115 } | 115 } |
| 116 | 116 |
| 117 Primitive refine(Primitive value, TypeMask type) { | 117 Primitive refine(Primitive value, TypeMask type) { |
| 118 return letPrim(new Refinement(value, type)); | 118 return letPrim(new Refinement(value, type)); |
| 119 } | 119 } |
| 120 | 120 |
| 121 Primitive invokeBuiltin(BuiltinMethod method, | 121 Primitive invokeBuiltin( |
| 122 Primitive receiver, | 122 BuiltinMethod method, Primitive receiver, List<Primitive> arguments, |
| 123 List<Primitive> arguments, | 123 {bool receiverIsNotNull: false}) { |
| 124 {bool receiverIsNotNull: false}) { | |
| 125 ApplyBuiltinMethod apply = | 124 ApplyBuiltinMethod apply = |
| 126 new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation); | 125 new ApplyBuiltinMethod(method, receiver, arguments, sourceInformation); |
| 127 return letPrim(apply); | 126 return letPrim(apply); |
| 128 } | 127 } |
| 129 | 128 |
| 130 /// Inserts an invocation and returns a primitive holding the returned value. | 129 /// Inserts an invocation and returns a primitive holding the returned value. |
| 131 Primitive invokeMethod(Primitive receiver, | 130 Primitive invokeMethod(Primitive receiver, Selector selector, TypeMask mask, |
| 132 Selector selector, | |
| 133 TypeMask mask, | |
| 134 List<Primitive> arguments, | 131 List<Primitive> arguments, |
| 135 {Primitive interceptor, | 132 {Primitive interceptor, CallingConvention callingConvention}) { |
| 136 CallingConvention callingConvention}) { | 133 InvokeMethod invoke = new InvokeMethod(receiver, selector, mask, arguments, |
| 137 InvokeMethod invoke = | 134 sourceInformation: sourceInformation, |
| 138 new InvokeMethod(receiver, selector, mask, arguments, | 135 callingConvention: callingConvention, |
| 139 sourceInformation: sourceInformation, | 136 interceptor: interceptor); |
| 140 callingConvention: callingConvention, | |
| 141 interceptor: interceptor); | |
| 142 return letPrim(invoke); | 137 return letPrim(invoke); |
| 143 } | 138 } |
| 144 | 139 |
| 145 /// Inserts an invocation and returns a primitive holding the returned value. | 140 /// Inserts an invocation and returns a primitive holding the returned value. |
| 146 Primitive invokeStatic(FunctionElement target, List<Primitive> arguments) { | 141 Primitive invokeStatic(FunctionElement target, List<Primitive> arguments) { |
| 147 return letPrim(new InvokeStatic(target, new Selector.fromElement(target), | 142 return letPrim(new InvokeStatic(target, new Selector.fromElement(target), |
| 148 arguments, sourceInformation)); | 143 arguments, sourceInformation)); |
| 149 } | 144 } |
| 150 | 145 |
| 151 /// Inserts an invocation to a static function that throws an error. | 146 /// Inserts an invocation to a static function that throws an error. |
| 152 /// | 147 /// |
| 153 /// This closes the fragment; no more nodes may be added. | 148 /// This closes the fragment; no more nodes may be added. |
| 154 void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) { | 149 void invokeStaticThrower(FunctionElement target, List<Primitive> arguments) { |
| 155 invokeStatic(target, arguments); | 150 invokeStatic(target, arguments); |
| 156 put(new Unreachable()); | 151 put(new Unreachable()); |
| 157 } | 152 } |
| 158 | 153 |
| 159 /// Invoke a non-recursive continuation. | 154 /// Invoke a non-recursive continuation. |
| 160 /// | 155 /// |
| 161 /// This closes the fragment; no more nodes may be inserted. | 156 /// This closes the fragment; no more nodes may be inserted. |
| 162 void invokeContinuation(Continuation cont, [List<Primitive> arguments]) { | 157 void invokeContinuation(Continuation cont, [List<Primitive> arguments]) { |
| 163 if (arguments == null) arguments = <Primitive>[]; | 158 if (arguments == null) arguments = <Primitive>[]; |
| 164 put(new InvokeContinuation(cont, arguments)); | 159 put(new InvokeContinuation(cont, arguments)); |
| 165 } | 160 } |
| 166 | 161 |
| 167 /// Build a loop with the given loop variables and initial values. | 162 /// Build a loop with the given loop variables and initial values. |
| 168 /// Call [continueLoop] with the returned continuation to iterate the loop. | 163 /// Call [continueLoop] with the returned continuation to iterate the loop. |
| 169 /// | 164 /// |
| 170 /// The loop body becomes the new hole. | 165 /// The loop body becomes the new hole. |
| 171 Continuation beginLoop([List<Parameter> loopVars, | 166 Continuation beginLoop( |
| 172 List<Primitive> initialValues]) { | 167 [List<Parameter> loopVars, List<Primitive> initialValues]) { |
| 173 if (initialValues == null) { | 168 if (initialValues == null) { |
| 174 assert(loopVars == null); | 169 assert(loopVars == null); |
| 175 loopVars = <Parameter>[]; | 170 loopVars = <Parameter>[]; |
| 176 initialValues = <Primitive>[]; | 171 initialValues = <Primitive>[]; |
| 177 } | 172 } |
| 178 Continuation cont = new Continuation(loopVars); | 173 Continuation cont = new Continuation(loopVars); |
| 179 put(new LetCont(cont, new InvokeContinuation(cont, initialValues))); | 174 put(new LetCont(cont, new InvokeContinuation(cont, initialValues))); |
| 180 context = cont; | 175 context = cont; |
| 181 return cont; | 176 return cont; |
| 182 } | 177 } |
| 183 | 178 |
| 184 /// Continue a loop started by [beginLoop]. | 179 /// Continue a loop started by [beginLoop]. |
| 185 /// | 180 /// |
| 186 /// This closes the fragment; no more nodes may be inserted. | 181 /// This closes the fragment; no more nodes may be inserted. |
| 187 void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) { | 182 void continueLoop(Continuation cont, [List<Primitive> updatedLoopVariables]) { |
| 188 put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true)); | 183 put(new InvokeContinuation(cont, updatedLoopVariables, isRecursive: true)); |
| 189 } | 184 } |
| 190 | 185 |
| 191 /// Branch on [condition]. | 186 /// Branch on [condition]. |
| 192 /// | 187 /// |
| 193 /// Returns a new fragment for the 'then' branch, or the 'else' branch | 188 /// Returns a new fragment for the 'then' branch, or the 'else' branch |
| 194 /// if [negate] is true. | 189 /// if [negate] is true. |
| 195 /// | 190 /// |
| 196 /// The other branch becomes the new hole. | 191 /// The other branch becomes the new hole. |
| 197 CpsFragment branch(Primitive condition, | 192 CpsFragment branch(Primitive condition, |
| 198 {bool negate: false, | 193 {bool negate: false, bool strict: false}) { |
| 199 bool strict: false}) { | |
| 200 Continuation trueCont = new Continuation(<Parameter>[]); | 194 Continuation trueCont = new Continuation(<Parameter>[]); |
| 201 Continuation falseCont = new Continuation(<Parameter>[]); | 195 Continuation falseCont = new Continuation(<Parameter>[]); |
| 202 put(new LetCont.two(trueCont, falseCont, | 196 put(new LetCont.two( |
| 203 new Branch(condition, trueCont, falseCont, | 197 trueCont, |
| 204 sourceInformation, strict: strict))); | 198 falseCont, |
| 199 new Branch(condition, trueCont, falseCont, sourceInformation, |
| 200 strict: strict))); |
| 205 if (negate) { | 201 if (negate) { |
| 206 context = trueCont; | 202 context = trueCont; |
| 207 return new CpsFragment(sourceInformation, falseCont); | 203 return new CpsFragment(sourceInformation, falseCont); |
| 208 } else { | 204 } else { |
| 209 context = falseCont; | 205 context = falseCont; |
| 210 return new CpsFragment(sourceInformation, trueCont); | 206 return new CpsFragment(sourceInformation, trueCont); |
| 211 } | 207 } |
| 212 } | 208 } |
| 213 | 209 |
| 214 /// Branch on [condition]. | 210 /// Branch on [condition]. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 | 267 |
| 272 /// Inlines [target] at the current position, substituting the provided | 268 /// Inlines [target] at the current position, substituting the provided |
| 273 /// arguments. | 269 /// arguments. |
| 274 /// | 270 /// |
| 275 /// Returns a primitive containing the function's return value. | 271 /// Returns a primitive containing the function's return value. |
| 276 /// | 272 /// |
| 277 /// The new hole is the the point after [target] has returned. The fragment | 273 /// The new hole is the the point after [target] has returned. The fragment |
| 278 /// remains open, even if [target] never returns. | 274 /// remains open, even if [target] never returns. |
| 279 /// | 275 /// |
| 280 /// The [target] function is destroyed and should not be reused. | 276 /// The [target] function is destroyed and should not be reused. |
| 281 Primitive inlineFunction(FunctionDefinition target, | 277 Primitive inlineFunction( |
| 282 Primitive receiver, | 278 FunctionDefinition target, Primitive receiver, List<Primitive> arguments, |
| 283 List<Primitive> arguments, | 279 {Entity hint, Primitive interceptor}) { |
| 284 {Entity hint, | |
| 285 Primitive interceptor}) { | |
| 286 if (interceptor != null) { | 280 if (interceptor != null) { |
| 287 target.interceptorParameter.replaceUsesWith(interceptor); | 281 target.interceptorParameter.replaceUsesWith(interceptor); |
| 288 } | 282 } |
| 289 if (receiver != null) { | 283 if (receiver != null) { |
| 290 target.receiverParameter.replaceUsesWith(receiver); | 284 target.receiverParameter.replaceUsesWith(receiver); |
| 291 } | 285 } |
| 292 for (int i = 0; i < arguments.length; ++i) { | 286 for (int i = 0; i < arguments.length; ++i) { |
| 293 target.parameters[i].replaceUsesWith(arguments[i]); | 287 target.parameters[i].replaceUsesWith(arguments[i]); |
| 294 } | 288 } |
| 295 Continuation returnCont = target.returnContinuation; | 289 Continuation returnCont = target.returnContinuation; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 while (prim.firstRef != null) { | 365 while (prim.firstRef != null) { |
| 372 Refinement refine = prim.firstRef.parent; | 366 Refinement refine = prim.firstRef.parent; |
| 373 destroyRefinementsOfDeadPrimitive(refine); | 367 destroyRefinementsOfDeadPrimitive(refine); |
| 374 LetPrim letPrim = refine.parent; | 368 LetPrim letPrim = refine.parent; |
| 375 InteriorNode parent = letPrim.parent; | 369 InteriorNode parent = letPrim.parent; |
| 376 parent.body = letPrim.body; | 370 parent.body = letPrim.body; |
| 377 letPrim.body.parent = parent; | 371 letPrim.body.parent = parent; |
| 378 prim.firstRef.unlink(); | 372 prim.firstRef.unlink(); |
| 379 } | 373 } |
| 380 } | 374 } |
| OLD | NEW |