Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: lib/compiler/implementation/js_backend/emitter.dart

Issue 11093015: Implement Function.apply in dart2js. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/compiler/implementation/js_backend/emitter.dart
===================================================================
--- lib/compiler/implementation/js_backend/emitter.dart (revision 13403)
+++ lib/compiler/implementation/js_backend/emitter.dart (working copy)
@@ -476,20 +476,97 @@
//
// We need to generate a stub for (5) because the order of the
// stub arguments and the real method may be different.
- Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
- if (selectors == null) return;
+
// Keep a cache of which stubs have already been generated, to
// avoid duplicates. Note that even if selectors are
// canonicalized, we would still need this cache: a typed selector
// on A and a typed selector on B could yield the same stub.
Set<String> generatedStubNames = new Set<String>();
- for (Selector selector in selectors) {
- if (!selector.applies(member, compiler)) continue;
- addParameterStub(
- member, selector, defineInstanceMember, generatedStubNames);
+ if (compiler.enabledFunctionApply
+ && member.name == Namer.CLOSURE_INVOCATION_NAME) {
+ // If [Function.apply] is called, we pessimistically compile all
+ // possible stubs for this closure.
+ // TODO(5074): This functionality only supports the new
+ // parameter specification, and this comment should be removed
+ // once the old specification is not supported.
+ FunctionSignature signature = member.computeSignature(compiler);
+ Set<Selector> selectors = signature.optionalParametersAreNamed
+ ? computeNamedSelectors(signature, member)
+ : computeOptionalSelectors(signature, member);
+ for (Selector selector in selectors) {
+ addParameterStub(
+ member, selector, defineInstanceMember, generatedStubNames);
+ }
+ } else {
+ Set<Selector> selectors = compiler.codegenWorld.invokedNames[member.name];
+ if (selectors == null) return;
+ for (Selector selector in selectors) {
+ if (!selector.applies(member, compiler)) continue;
+ addParameterStub(
+ member, selector, defineInstanceMember, generatedStubNames);
+ }
}
}
+ /**
+ * Compute the set of possible selectors in the presence of named
+ * parameters.
+ */
+ Set<Selector> computeNamedSelectors(FunctionSignature signature,
+ FunctionElement element) {
+ Set<Selector> selectors = new Set<Selector>();
+ // Add the selector that does not have any optional argument.
+ selectors.add(new Selector(SelectorKind.CALL,
+ element.name,
+ element.getLibrary(),
+ signature.requiredParameterCount,
+ <SourceString>[]));
+
+ // For each optional parameter, we iterator over the set of
+ // already computed selectors and create new selectors with that
+ // parameter now being passed.
+ signature.forEachOptionalParameter((Element element) {
+ Set<Selector> newSet = new Set<Selector>();
+ selectors.forEach((Selector other) {
+ List<SourceString> namedArguments = [element.name];
+ namedArguments.addAll(other.namedArguments);
+ newSet.add(new Selector(other.kind,
+ other.name,
+ other.library,
+ other.argumentCount + 1,
+ namedArguments));
+ });
+ selectors.addAll(newSet);
+ });
+ return selectors;
+ }
+
+ /**
+ * Compute the set of possible selectors in the presence of optional
+ * non-named parameters.
+ */
+ Set<Selector> computeOptionalSelectors(FunctionSignature signature,
+ FunctionElement element) {
+ Set<Selector> selectors = new Set<Selector>();
+ // Add the selector that does not have any optional argument.
+ selectors.add(new Selector(SelectorKind.CALL,
+ element.name,
+ element.getLibrary(),
+ signature.requiredParameterCount,
+ <SourceString>[]));
+
+ // For each optional parameter, we increment the number of passed
+ // argument.
+ for (int i = 1; i <= signature.optionalParameterCount; i++) {
+ selectors.add(new Selector(SelectorKind.CALL,
+ element.name,
+ element.getLibrary(),
+ signature.requiredParameterCount + i,
+ <SourceString>[]));
+ }
+ return selectors;
+ }
+
bool instanceFieldNeedsGetter(Element member) {
assert(member.isField());
return compiler.codegenWorld.hasInvokedGetter(member, compiler);

Powered by Google App Engine
This is Rietveld 408576698