OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 /** | 5 /** |
6 * A function element that represents a closure call. The signature is copied | 6 * A function element that represents a closure call. The signature is copied |
7 * from the given element. | 7 * from the given element. |
8 */ | 8 */ |
9 class ClosureInvocationElement extends FunctionElement { | 9 class ClosureInvocationElement extends FunctionElement { |
10 ClosureInvocationElement(SourceString name, | 10 ClosureInvocationElement(SourceString name, |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 // (1) No stub generated, call is direct. | 469 // (1) No stub generated, call is direct. |
470 // (2) foo$2(a, b) => foo$4(a, b, null, null) | 470 // (2) foo$2(a, b) => foo$4(a, b, null, null) |
471 // (3) foo$3(a, b, c) => foo$4(a, b, c, null) | 471 // (3) foo$3(a, b, c) => foo$4(a, b, c, null) |
472 // (4) foo$3$c(a, b, c) => foo$4(a, b, c, null); | 472 // (4) foo$3$c(a, b, c) => foo$4(a, b, c, null); |
473 // (5) foo$3$d(a, b, d) => foo$4(a, b, null, d); | 473 // (5) foo$3$d(a, b, d) => foo$4(a, b, null, d); |
474 // (6) foo$4$c$d(a, b, c, d) => foo$4(a, b, c, d); | 474 // (6) foo$4$c$d(a, b, c, d) => foo$4(a, b, c, d); |
475 // (7) Same as (5). | 475 // (7) Same as (5). |
476 // | 476 // |
477 // We need to generate a stub for (5) because the order of the | 477 // We need to generate a stub for (5) because the order of the |
478 // stub arguments and the real method may be different. | 478 // stub arguments and the real method may be different. |
479 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; | |
480 if (selectors == null) return; | |
481 // Keep a cache of which stubs have already been generated, to | |
482 // avoid duplicates. Note that even if selectors are | |
483 // canonicalized, we would still need this cache: a typed selector | |
484 // on A and a typed selector on B could yield the same stub. | |
485 Set<String> generatedStubNames = new Set<String>(); | 479 Set<String> generatedStubNames = new Set<String>(); |
486 for (Selector selector in selectors) { | 480 if (compiler.enabledFunctionApply |
487 if (!selector.applies(member, compiler)) continue; | 481 && member.name == Namer.CLOSURE_INVOCATION_NAME) { |
488 addParameterStub( | 482 // If [Function.apply] is called, we pessimistically compile all |
489 member, selector, defineInstanceMember, generatedStubNames); | 483 // possible stubs for this closure. |
| 484 // TODO(5074): This functionality only supports the new |
| 485 // parameter specification, and this comment should be removed |
| 486 // once the old specification is not supported. |
| 487 FunctionSignature signature = member.computeSignature(compiler); |
| 488 Set<Selector> selectors = signature.optionalParametersAreNamed |
| 489 ? computeNamedSelectors(signature, member) |
| 490 : computeOptionalSelectors(signature, member); |
| 491 for (Selector selector in selectors) { |
| 492 addParameterStub( |
| 493 member, selector, defineInstanceMember, generatedStubNames); |
| 494 } |
| 495 } else { |
| 496 Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name]; |
| 497 if (selectors == null) return; |
| 498 // Keep a cache of which stubs have already been generated, to |
| 499 // avoid duplicates. Note that even if selectors are |
| 500 // canonicalized, we would still need this cache: a typed selector |
| 501 // on A and a typed selector on B could yield the same stub. |
| 502 for (Selector selector in selectors) { |
| 503 if (!selector.applies(member, compiler)) continue; |
| 504 addParameterStub( |
| 505 member, selector, defineInstanceMember, generatedStubNames); |
| 506 } |
490 } | 507 } |
491 } | 508 } |
492 | 509 |
| 510 /** |
| 511 * Compute the set of possible selectors in the presence of named |
| 512 * parameters. |
| 513 */ |
| 514 Set<Selector> computeNamedSelectors(FunctionSignature signature, |
| 515 FunctionElement element) { |
| 516 Set<Selector> selectors = new Set<Selector>(); |
| 517 // Add the selector that does not have any optional argument. |
| 518 selectors.add(new Selector(SelectorKind.CALL, |
| 519 element.name, |
| 520 element.getLibrary(), |
| 521 signature.requiredParameterCount, |
| 522 <SourceString>[])); |
| 523 |
| 524 // For each optional parameter, we iterator over the set of |
| 525 // already computed selectors and create new selectors with that |
| 526 // parameter now being passed. |
| 527 signature.forEachOptionalParameter((Element element) { |
| 528 // We will iterate over the set and add new selectors. Make a copy |
| 529 // of a set to not change it while iterating. |
| 530 Set<Selector> newSet = new Set<Selector>.from(selectors); |
| 531 newSet.forEach((Selector other) { |
| 532 List<SourceString> namedArguments = [element.name]; |
| 533 namedArguments.addAll(other.namedArguments); |
| 534 selectors.add(new Selector(other.kind, |
| 535 other.name, |
| 536 other.library, |
| 537 other.argumentCount + 1, |
| 538 namedArguments)); |
| 539 }); |
| 540 }); |
| 541 return selectors; |
| 542 } |
| 543 |
| 544 /** |
| 545 * Compute the set of possible selectors in the presence of optional |
| 546 * non-named parameters. |
| 547 */ |
| 548 Set<Selector> computeOptionalSelectors(FunctionSignature signature, |
| 549 FunctionElement element) { |
| 550 Set<Selector> selectors = new Set<Selector>(); |
| 551 // Add the selector that does not have any optional argument. |
| 552 selectors.add(new Selector(SelectorKind.CALL, |
| 553 element.name, |
| 554 element.getLibrary(), |
| 555 signature.requiredParameterCount, |
| 556 <SourceString>[])); |
| 557 |
| 558 // For each optional parameter, we increment the number of passed |
| 559 // argument. |
| 560 for (int i = 1; i <= signature.optionalParameterCount; i++) { |
| 561 selectors.add(new Selector(SelectorKind.CALL, |
| 562 element.name, |
| 563 element.getLibrary(), |
| 564 signature.requiredParameterCount + i, |
| 565 <SourceString>[])); |
| 566 } |
| 567 return selectors; |
| 568 } |
| 569 |
493 bool instanceFieldNeedsGetter(Element member) { | 570 bool instanceFieldNeedsGetter(Element member) { |
494 assert(member.isField()); | 571 assert(member.isField()); |
495 return compiler.codegenWorld.hasInvokedGetter(member, compiler); | 572 return compiler.codegenWorld.hasInvokedGetter(member, compiler); |
496 } | 573 } |
497 | 574 |
498 bool instanceFieldNeedsSetter(Element member) { | 575 bool instanceFieldNeedsSetter(Element member) { |
499 assert(member.isField()); | 576 assert(member.isField()); |
500 return (!member.modifiers.isFinalOrConst()) | 577 return (!member.modifiers.isFinalOrConst()) |
501 && compiler.codegenWorld.hasInvokedSetter(member, compiler); | 578 && compiler.codegenWorld.hasInvokedSetter(member, compiler); |
502 } | 579 } |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1435 const String HOOKS_API_USAGE = """ | 1512 const String HOOKS_API_USAGE = """ |
1436 // Generated by dart2js, the Dart to JavaScript compiler. | 1513 // Generated by dart2js, the Dart to JavaScript compiler. |
1437 // The code supports the following hooks: | 1514 // The code supports the following hooks: |
1438 // dartPrint(message) - if this function is defined it is called | 1515 // dartPrint(message) - if this function is defined it is called |
1439 // instead of the Dart [print] method. | 1516 // instead of the Dart [print] method. |
1440 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1517 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1441 // method will not be invoked directly. | 1518 // method will not be invoked directly. |
1442 // Instead, a closure that will invoke [main] is | 1519 // Instead, a closure that will invoke [main] is |
1443 // passed to [dartMainRunner]. | 1520 // passed to [dartMainRunner]. |
1444 """; | 1521 """; |
OLD | NEW |