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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 class ParameterStubGenerator { | 7 class ParameterStubGenerator { |
8 static final Set<Selector> emptySelectorSet = new Set<Selector>(); | 8 static final Set<Selector> emptySelectorSet = new Set<Selector>(); |
9 | 9 |
10 final Namer namer; | 10 final Namer namer; |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 compiler.internalError(cls.methodElement, 'Bound closure1.'); | 193 compiler.internalError(cls.methodElement, 'Bound closure1.'); |
194 } | 194 } |
195 if (cls.methodElement.isInstanceMember) { | 195 if (cls.methodElement.isInstanceMember) { |
196 compiler.internalError(cls.methodElement, 'Bound closure2.'); | 196 compiler.internalError(cls.methodElement, 'Bound closure2.'); |
197 } | 197 } |
198 } | 198 } |
199 | 199 |
200 // The set of selectors that apply to `member`. For example, for | 200 // The set of selectors that apply to `member`. For example, for |
201 // a member `foo(x, [y])` the following selectors may apply: | 201 // a member `foo(x, [y])` the following selectors may apply: |
202 // `foo(x)`, and `foo(x, y)`. | 202 // `foo(x)`, and `foo(x, y)`. |
203 Map<Selector, TypeMaskSet> selectors; | 203 Set<Selector> selectors; |
204 // The set of selectors that apply to `member` if it's name was `call`. | 204 // The set of selectors that apply to `member` if it's name was `call`. |
205 // This happens when a member is torn off. In that case calls to the | 205 // This happens when a member is torn off. In that case calls to the |
206 // function use the name `call`, and we must be able to handle every | 206 // function use the name `call`, and we must be able to handle every |
207 // `call` invocation that matches the signature. For example, for | 207 // `call` invocation that matches the signature. For example, for |
208 // a member `foo(x, [y])` the following selectors would be possible | 208 // a member `foo(x, [y])` the following selectors would be possible |
209 // call-selectors: `call(x)`, and `call(x, y)`. | 209 // call-selectors: `call(x)`, and `call(x, y)`. |
210 Map<Selector, TypeMaskSet> callSelectors; | 210 Set<Selector> callSelectors; |
211 | 211 |
212 // Only instance members (not static methods) need stubs. | 212 // Only instance members (not static methods) need stubs. |
213 if (member.isInstanceMember) { | 213 if (member.isInstanceMember) { |
214 selectors = compiler.codegenWorld.invocationsByName(member.name); | 214 selectors = compiler.codegenWorld.invokedNames[member.name]; |
215 } | 215 } |
216 | 216 |
217 if (canTearOff) { | 217 if (canTearOff) { |
218 String call = namer.closureInvocationSelectorName; | 218 String call = namer.closureInvocationSelectorName; |
219 callSelectors = compiler.codegenWorld.invocationsByName(call); | 219 callSelectors = compiler.codegenWorld.invokedNames[call]; |
220 } | 220 } |
221 | 221 |
222 assert(emptySelectorSet.isEmpty); | 222 assert(emptySelectorSet.isEmpty); |
223 if (selectors == null) selectors = const <Selector, TypeMaskSet>{}; | 223 if (selectors == null) selectors = emptySelectorSet; |
224 if (callSelectors == null) callSelectors = const <Selector, TypeMaskSet>{}; | 224 if (callSelectors == null) callSelectors = emptySelectorSet; |
225 | 225 |
226 List<ParameterStubMethod> stubs = <ParameterStubMethod>[]; | 226 List<ParameterStubMethod> stubs = <ParameterStubMethod>[]; |
227 | 227 |
228 if (selectors.isEmpty && callSelectors.isEmpty) { | 228 if (selectors.isEmpty && callSelectors.isEmpty) { |
229 return stubs; | 229 return stubs; |
230 } | 230 } |
231 | 231 |
232 // For every call-selector the corresponding selector with the name of the | 232 // For every call-selector the corresponding selector with the name of the |
233 // member. | 233 // member. |
234 // | 234 // |
235 // For example, for the call-selector `call(x, y)` the renamed selector | 235 // For example, for the call-selector `call(x, y)` the renamed selector |
236 // for member `foo` would be `foo(x, y)`. | 236 // for member `foo` would be `foo(x, y)`. |
237 Set<Selector> renamedCallSelectors = | 237 Set<Selector> renamedCallSelectors = |
238 callSelectors.isEmpty ? emptySelectorSet : new Set<Selector>(); | 238 callSelectors.isEmpty ? emptySelectorSet : new Set<Selector>(); |
239 | 239 |
240 Set<Selector> untypedSelectors = new Set<Selector>(); | 240 Set<Selector> untypedSelectors = new Set<Selector>(); |
241 | 241 |
242 // Start with the callSelectors since they imply the generation of the | 242 // Start with the callSelectors since they imply the generation of the |
243 // non-call version. | 243 // non-call version. |
244 for (Selector selector in callSelectors.keys) { | 244 for (Selector selector in callSelectors) { |
245 Selector renamedSelector = new Selector( | 245 Selector renamedSelector = new Selector( |
246 SelectorKind.CALL, | 246 SelectorKind.CALL, |
247 member.memberName, | 247 member.memberName, |
248 selector.callStructure); | 248 selector.callStructure); |
249 renamedCallSelectors.add(renamedSelector); | 249 renamedCallSelectors.add(renamedSelector); |
250 | 250 |
251 if (!renamedSelector.appliesUnnamed(member, compiler.world)) continue; | 251 if (!renamedSelector.appliesUnnamed(member, compiler.world)) continue; |
252 | 252 |
253 if (untypedSelectors.add(renamedSelector)) { | 253 if (untypedSelectors.add(renamedSelector.asUntyped)) { |
254 ParameterStubMethod stub = | 254 ParameterStubMethod stub = |
255 generateParameterStub(member, renamedSelector, selector); | 255 generateParameterStub(member, renamedSelector, selector); |
256 if (stub != null) { | 256 if (stub != null) { |
257 stubs.add(stub); | 257 stubs.add(stub); |
258 } | 258 } |
259 } | 259 } |
260 } | 260 } |
261 | 261 |
262 // Now run through the actual member selectors (eg. `foo$2(x, y)` and not | 262 // Now run through the actual member selectors (eg. `foo$2(x, y)` and not |
263 // `call$2(x, y)`. Some of them have already been generated because of the | 263 // `call$2(x, y)`. Some of them have already been generated because of the |
264 // call-selectors (and they are in the renamedCallSelectors set. | 264 // call-selectors (and they are in the renamedCallSelectors set. |
265 for (Selector selector in selectors.keys) { | 265 for (Selector selector in selectors) { |
266 if (renamedCallSelectors.contains(selector)) continue; | 266 if (renamedCallSelectors.contains(selector)) continue; |
267 if (!selector.appliesUnnamed(member, compiler.world)) continue; | 267 if (!selector.appliesUnnamed(member, compiler.world)) continue; |
268 if (!selectors[selector].applies(member, selector, compiler.world)) { | |
269 continue; | |
270 } | |
271 | 268 |
272 if (untypedSelectors.add(selector)) { | 269 if (untypedSelectors.add(selector.asUntyped)) { |
273 ParameterStubMethod stub = | 270 ParameterStubMethod stub = |
274 generateParameterStub(member, selector, null); | 271 generateParameterStub(member, selector, null); |
275 if (stub != null) { | 272 if (stub != null) { |
276 stubs.add(stub); | 273 stubs.add(stub); |
277 } | 274 } |
278 } | 275 } |
279 } | 276 } |
280 | 277 |
281 return stubs; | 278 return stubs; |
282 } | 279 } |
283 } | 280 } |
OLD | NEW |