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 | |
kasperl
2012/10/09 11:35:18
Where did the cache move? I guess the comment need
ngeoffray
2012/10/09 11:56:58
Done.
| |
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); | |
kasperl
2012/10/09 11:35:18
Wouldn't it be simpler to collect the new selector
ngeoffray
2012/10/09 11:56:58
Good point. Done.
| |
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 |