| OLD | NEW |
| 1 library dart2js.unsugar_cps; | 1 library dart2js.unsugar_cps; |
| 2 | 2 |
| 3 import '../../cps_ir/cps_ir_nodes.dart'; | 3 import '../../cps_ir/cps_ir_nodes.dart'; |
| 4 | 4 |
| 5 import '../../cps_ir/optimizers.dart' show Pass; | 5 import '../../cps_ir/optimizers.dart' show Pass; |
| 6 import '../../constants/values.dart'; | 6 import '../../constants/values.dart'; |
| 7 import '../../elements/elements.dart'; | 7 import '../../elements/elements.dart'; |
| 8 import '../../js_backend/codegen/glue.dart'; | 8 import '../../js_backend/codegen/glue.dart'; |
| 9 import '../../universe/selector.dart' show Selector; | 9 import '../../universe/selector.dart' show Selector; |
| 10 import '../../cps_ir/cps_fragment.dart'; | 10 import '../../cps_ir/cps_fragment.dart'; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 // body; | 100 // body; |
| 101 // | 101 // |
| 102 // with | 102 // with |
| 103 // | 103 // |
| 104 // if (identical(arg, null)) | 104 // if (identical(arg, null)) |
| 105 // return false; | 105 // return false; |
| 106 // else | 106 // else |
| 107 // body; | 107 // body; |
| 108 // | 108 // |
| 109 CpsFragment cps = new CpsFragment(); | 109 CpsFragment cps = new CpsFragment(); |
| 110 Primitive isNull = cps.applyBuiltin( | 110 Primitive isNull = cps.applyBuiltin(BuiltinOperator.Identical, |
| 111 BuiltinOperator.Identical, | |
| 112 <Primitive>[function.parameters.single, cps.makeNull()]); | 111 <Primitive>[function.parameters.single, cps.makeNull()]); |
| 113 CpsFragment trueBranch = cps.ifTruthy(isNull); | 112 CpsFragment trueBranch = cps.ifTruthy(isNull); |
| 114 trueBranch.invokeContinuation(function.returnContinuation, | 113 trueBranch.invokeContinuation( |
| 115 <Primitive>[trueBranch.makeFalse()]); | 114 function.returnContinuation, <Primitive>[trueBranch.makeFalse()]); |
| 116 cps.insertAbove(function.body); | 115 cps.insertAbove(function.body); |
| 117 } | 116 } |
| 118 | 117 |
| 119 /// Insert a static call to [function] immediately above [node]. | 118 /// Insert a static call to [function] immediately above [node]. |
| 120 Primitive insertStaticCallAbove(FunctionElement function, | 119 Primitive insertStaticCallAbove( |
| 121 List<Primitive> arguments, Expression node) { | 120 FunctionElement function, List<Primitive> arguments, Expression node) { |
| 122 // TODO(johnniwinther): Come up with an implementation of SourceInformation | 121 // TODO(johnniwinther): Come up with an implementation of SourceInformation |
| 123 // for calls such as this one that don't appear in the original source. | 122 // for calls such as this one that don't appear in the original source. |
| 124 InvokeStatic invoke = new InvokeStatic( | 123 InvokeStatic invoke = new InvokeStatic( |
| 125 function, new Selector.fromElement(function), arguments, null); | 124 function, new Selector.fromElement(function), arguments, null); |
| 126 new LetPrim(invoke).insertAbove(node); | 125 new LetPrim(invoke).insertAbove(node); |
| 127 return invoke; | 126 return invoke; |
| 128 } | 127 } |
| 129 | 128 |
| 130 @override | 129 @override |
| 131 Expression traverseLetHandler(LetHandler node) { | 130 Expression traverseLetHandler(LetHandler node) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 145 [new Parameter(null)], // Dummy argument, see below. | 144 [new Parameter(null)], // Dummy argument, see below. |
| 146 body); | 145 body); |
| 147 _exceptionParameter.replaceUsesWith(unwrapped); | 146 _exceptionParameter.replaceUsesWith(unwrapped); |
| 148 | 147 |
| 149 // Replace the dummy with the exception parameter. It must be set after | 148 // Replace the dummy with the exception parameter. It must be set after |
| 150 // replacing all uses of [_exceptionParameter]. | 149 // replacing all uses of [_exceptionParameter]. |
| 151 unwrapped.argumentRefs[0].changeTo(_exceptionParameter); | 150 unwrapped.argumentRefs[0].changeTo(_exceptionParameter); |
| 152 | 151 |
| 153 if (stackTraceParameter.hasAtLeastOneUse) { | 152 if (stackTraceParameter.hasAtLeastOneUse) { |
| 154 InvokeStatic stackTraceValue = insertStaticCallAbove( | 153 InvokeStatic stackTraceValue = insertStaticCallAbove( |
| 155 _glue.getTraceFromException(), | 154 _glue.getTraceFromException(), [_exceptionParameter], body); |
| 156 [_exceptionParameter], | |
| 157 body); | |
| 158 stackTraceParameter.replaceUsesWith(stackTraceValue); | 155 stackTraceParameter.replaceUsesWith(stackTraceValue); |
| 159 } | 156 } |
| 160 } | 157 } |
| 161 | 158 |
| 162 assert(stackTraceParameter.hasNoUses); | 159 assert(stackTraceParameter.hasNoUses); |
| 163 node.handler.parameters.removeLast(); | 160 node.handler.parameters.removeLast(); |
| 164 | 161 |
| 165 visit(node.handler); | 162 visit(node.handler); |
| 166 _exceptionParameter = previousExceptionParameter; | 163 _exceptionParameter = previousExceptionParameter; |
| 167 | 164 |
| 168 return node.body; | 165 return node.body; |
| 169 } | 166 } |
| 170 | 167 |
| 171 processThrow(Throw node) { | 168 processThrow(Throw node) { |
| 172 // The subexpression of throw is wrapped in the JavaScript output. | 169 // The subexpression of throw is wrapped in the JavaScript output. |
| 173 Primitive wrappedException = insertStaticCallAbove( | 170 Primitive wrappedException = insertStaticCallAbove( |
| 174 _glue.getWrapExceptionHelper(), | 171 _glue.getWrapExceptionHelper(), [node.value], node); |
| 175 [node.value], | |
| 176 node); | |
| 177 node.valueRef.changeTo(wrappedException); | 172 node.valueRef.changeTo(wrappedException); |
| 178 } | 173 } |
| 179 | 174 |
| 180 processRethrow(Rethrow node) { | 175 processRethrow(Rethrow node) { |
| 181 // Rethrow can only appear in a catch block. It throws that block's | 176 // Rethrow can only appear in a catch block. It throws that block's |
| 182 // (wrapped) caught exception. | 177 // (wrapped) caught exception. |
| 183 Throw replacement = new Throw(_exceptionParameter); | 178 Throw replacement = new Throw(_exceptionParameter); |
| 184 InteriorNode parent = node.parent; | 179 InteriorNode parent = node.parent; |
| 185 parent.body = replacement; | 180 parent.body = replacement; |
| 186 replacement.parent = parent; | 181 replacement.parent = parent; |
| 187 // The original rethrow does not have any references that we need to | 182 // The original rethrow does not have any references that we need to |
| 188 // worry about unlinking. | 183 // worry about unlinking. |
| 189 } | 184 } |
| 190 | 185 |
| 191 bool isNullConstant(Primitive prim) { | 186 bool isNullConstant(Primitive prim) { |
| 192 return prim is Constant && prim.value.isNull; | 187 return prim is Constant && prim.value.isNull; |
| 193 } | 188 } |
| 194 | 189 |
| 195 processInvokeMethod(InvokeMethod node) { | 190 processInvokeMethod(InvokeMethod node) { |
| 196 Selector selector = node.selector; | 191 Selector selector = node.selector; |
| 197 if (!_glue.isInterceptedSelector(selector)) return; | 192 if (!_glue.isInterceptedSelector(selector)) return; |
| 198 | 193 |
| 199 // Some platform libraries will compare non-interceptable objects against | 194 // Some platform libraries will compare non-interceptable objects against |
| 200 // null using the Dart == operator. These must be translated directly. | 195 // null using the Dart == operator. These must be translated directly. |
| 201 if (node.selector == Selectors.equals && | 196 if (node.selector == Selectors.equals && |
| 202 node.argumentRefs.length == 1 && | 197 node.argumentRefs.length == 1 && |
| 203 isNullConstant(node.argument(0))) { | 198 isNullConstant(node.argument(0))) { |
| 204 node.replaceWith(new ApplyBuiltinOperator( | 199 node.replaceWith(new ApplyBuiltinOperator(BuiltinOperator.Identical, |
| 205 BuiltinOperator.Identical, | 200 [node.receiver, node.argument(0)], node.sourceInformation)); |
| 206 [node.receiver, node.argument(0)], | |
| 207 node.sourceInformation)); | |
| 208 return; | 201 return; |
| 209 } | 202 } |
| 210 | 203 |
| 211 Primitive receiver = node.receiver; | 204 Primitive receiver = node.receiver; |
| 212 Primitive interceptor; | 205 Primitive interceptor; |
| 213 | 206 |
| 214 if (receiver == receiverParameter && receiverInterceptor != null) { | 207 if (receiver == receiverParameter && receiverInterceptor != null) { |
| 215 // TODO(asgerf): This could be done by GVN. | 208 // TODO(asgerf): This could be done by GVN. |
| 216 // If the receiver is 'this', we are calling a method in | 209 // If the receiver is 'this', we are calling a method in |
| 217 // the same interceptor: | 210 // the same interceptor: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 243 interceptor = new Interceptor(receiver, node.sourceInformation); | 236 interceptor = new Interceptor(receiver, node.sourceInformation); |
| 244 if (receiver.hint != null) { | 237 if (receiver.hint != null) { |
| 245 interceptor.hint = new InterceptorEntity(receiver.hint); | 238 interceptor.hint = new InterceptorEntity(receiver.hint); |
| 246 } | 239 } |
| 247 new LetPrim(interceptor).insertAbove(node.parent); | 240 new LetPrim(interceptor).insertAbove(node.parent); |
| 248 } | 241 } |
| 249 assert(node.interceptorRef == null); | 242 assert(node.interceptorRef == null); |
| 250 node.makeIntercepted(interceptor); | 243 node.makeIntercepted(interceptor); |
| 251 } | 244 } |
| 252 } | 245 } |
| OLD | NEW |