@@ -213,15 +213,6 @@ abstract class AstCodeGenerator
213213 translator.membersBeingGenerated.remove (enclosingMember);
214214 }
215215
216- void addNestedClosuresToCompilationQueue () {
217- for (Lambda lambda in closures.lambdas.values) {
218- translator.compilationQueue.add (CompilationTask (
219- lambda.function,
220- getLambdaCodeGenerator (
221- translator, lambda, enclosingMember, closures)));
222- }
223- }
224-
225216 // Generate the body.
226217 void generateInternal ();
227218
@@ -2388,41 +2379,87 @@ abstract class AstCodeGenerator
23882379 expectedType);
23892380 }
23902381
2391- final Expression receiver = node.receiver;
2392- final Arguments arguments = node.arguments;
2393-
2394- int typeCount = arguments.types.length;
2395- int posArgCount = arguments.positional.length;
2396- List <String > argNames = arguments.named.map ((a) => a.name).toList ()..sort ();
2382+ List <String > argNames = node.arguments.named.map ((a) => a.name).toList ()
2383+ ..sort ();
23972384 ClosureRepresentation ? representation = translator.closureLayouter
2398- .getClosureRepresentation (typeCount, posArgCount, argNames);
2385+ .getClosureRepresentation (node.arguments.types.length,
2386+ node.arguments.positional.length, argNames);
23992387 if (representation == null ) {
24002388 // This is a dynamic function call with a signature that matches no
24012389 // functions in the program.
24022390 b.unreachable ();
24032391 return translator.topInfo.nullableType;
24042392 }
24052393
2394+ final SingleClosureTarget ? directClosureCall =
2395+ translator.singleClosureTarget (node, representation, typeContext);
2396+
2397+ if (directClosureCall != null ) {
2398+ return _generateDirectClosureCall (
2399+ node, representation, directClosureCall);
2400+ }
2401+
2402+ return _generateClosureInvocation (node, representation);
2403+ }
2404+
2405+ w.ValueType _generateDirectClosureCall (FunctionInvocation node,
2406+ ClosureRepresentation representation, SingleClosureTarget closureTarget) {
2407+ final closureStruct = representation.closureStruct;
2408+ final closureStructRef = w.RefType .def (closureStruct, nullable: false );
2409+ final signature = closureTarget.signature;
2410+ final paramInfo = closureTarget.paramInfo;
2411+ final member = closureTarget.member;
2412+ final lambdaFunction = closureTarget.lambdaFunction;
2413+
2414+ if (lambdaFunction == null ) {
2415+ if (paramInfo.takesContextOrReceiver) {
2416+ translateExpression (node.receiver, closureStructRef);
2417+ b.struct_get (closureStruct, FieldIndex .closureContext);
2418+ translator.convertType (
2419+ b,
2420+ closureStruct.fields[FieldIndex .closureContext].type.unpacked,
2421+ signature.inputs[0 ]);
2422+ _visitArguments (node.arguments, signature, paramInfo, 1 );
2423+ } else {
2424+ _visitArguments (node.arguments, signature, paramInfo, 0 );
2425+ }
2426+ return translator.outputOrVoid (call (member.reference));
2427+ } else {
2428+ assert (paramInfo.takesContextOrReceiver);
2429+ translateExpression (node.receiver, closureStructRef);
2430+ b.struct_get (closureStruct, FieldIndex .closureContext);
2431+ _visitArguments (node.arguments, signature, paramInfo, 1 );
2432+ return translator
2433+ .outputOrVoid (translator.callFunction (lambdaFunction, b));
2434+ }
2435+ }
2436+
2437+ w.ValueType _generateClosureInvocation (
2438+ FunctionInvocation node, ClosureRepresentation representation) {
2439+ final closureStruct = representation.closureStruct;
2440+
24062441 // Evaluate receiver
2407- w.StructType struct = representation.closureStruct;
2408- w. Local closureLocal = addLocal (w.RefType .def (struct , nullable: false ));
2409- translateExpression (receiver, closureLocal.type);
2442+ w.Local closureLocal =
2443+ addLocal (w.RefType .def (closureStruct , nullable: false ));
2444+ translateExpression (node. receiver, closureLocal.type);
24102445 b.local_tee (closureLocal);
2411- b.struct_get (struct , FieldIndex .closureContext);
2446+ b.struct_get (closureStruct , FieldIndex .closureContext);
24122447
24132448 // Type arguments
2414- for (DartType typeArg in arguments.types) {
2449+ for (DartType typeArg in node. arguments.types) {
24152450 types.makeType (this , typeArg);
24162451 }
24172452
24182453 // Positional arguments
2419- for (Expression arg in arguments.positional) {
2454+ for (Expression arg in node. arguments.positional) {
24202455 translateExpression (arg, translator.topInfo.nullableType);
24212456 }
24222457
24232458 // Named arguments
2459+ final List <String > argNames =
2460+ node.arguments.named.map ((a) => a.name).toList ()..sort ();
24242461 final Map <String , w.Local > namedLocals = {};
2425- for (final namedArg in arguments.named) {
2462+ for (final namedArg in node. arguments.named) {
24262463 final w.Local namedLocal = addLocal (translator.topInfo.nullableType);
24272464 namedLocals[namedArg.name] = namedLocal;
24282465 translateExpression (namedArg.value, namedLocal.type);
@@ -2432,15 +2469,17 @@ abstract class AstCodeGenerator
24322469 b.local_get (namedLocals[name]! );
24332470 }
24342471
2435- // Call entry point in vtable
2436- int vtableFieldIndex =
2437- representation.fieldIndexForSignature (posArgCount, argNames);
2438- w.FunctionType functionType =
2472+ final int vtableFieldIndex = representation.fieldIndexForSignature (
2473+ node.arguments.positional.length, argNames);
2474+ final w.FunctionType functionType =
24392475 representation.getVtableFieldType (vtableFieldIndex);
2476+
2477+ // Call entry point in vtable
24402478 b.local_get (closureLocal);
2441- b.struct_get (struct , FieldIndex .closureVtable);
2479+ b.struct_get (closureStruct , FieldIndex .closureVtable);
24422480 b.struct_get (representation.vtableStruct, vtableFieldIndex);
24432481 b.call_ref (functionType);
2482+
24442483 return translator.topInfo.nullableType;
24452484 }
24462485
@@ -3181,7 +3220,7 @@ class SynchronousProcedureCodeGenerator extends AstCodeGenerator {
31813220 return ;
31823221 }
31833222
3184- closures = Closures ( translator, member);
3223+ closures = translator. getClosures ( member);
31853224
31863225 setupParametersAndContexts (member, useUncheckedEntry: useUncheckedEntry);
31873226
@@ -3192,7 +3231,6 @@ class SynchronousProcedureCodeGenerator extends AstCodeGenerator {
31923231
31933232 _implicitReturn ();
31943233 b.end ();
3195- addNestedClosuresToCompilationQueue ();
31963234 }
31973235}
31983236
@@ -3209,7 +3247,7 @@ class TearOffCodeGenerator extends AstCodeGenerator {
32093247 // used by `makeType` below, when generating runtime types of type
32103248 // parameters of the function type, but the type parameters are not
32113249 // captured, always loaded from the `this` struct.
3212- closures = Closures ( translator, member, findCaptures: false );
3250+ closures = translator. getClosures ( member, findCaptures: false );
32133251
32143252 _initializeThis (member.reference);
32153253 Procedure procedure = member as Procedure ;
@@ -3242,7 +3280,7 @@ class TypeCheckerCodeGenerator extends AstCodeGenerator {
32423280 // Initialize [Closures] without [Closures.captures]: Similar to
32433281 // [TearOffCodeGenerator], type parameters will be loaded from the `this`
32443282 // struct.
3245- closures = Closures ( translator, member, findCaptures: false );
3283+ closures = translator. getClosures ( member, findCaptures: false );
32463284 if (member is Field ||
32473285 (member is Procedure && (member as Procedure ).isSetter)) {
32483286 _generateFieldSetterTypeCheckerMethod ();
@@ -3482,7 +3520,6 @@ class InitializerListCodeGenerator extends AstCodeGenerator {
34823520 generateInitializerList ();
34833521 }
34843522 b.end ();
3485- addNestedClosuresToCompilationQueue ();
34863523 }
34873524
34883525 // Generates a constructor's initializer list method, and returns:
@@ -3848,7 +3885,7 @@ class StaticFieldInitializerCodeGenerator extends AstCodeGenerator {
38483885 setSourceMapSourceAndFileOffset (source, field.fileOffset);
38493886
38503887 // Static field initializer function
3851- closures = Closures ( translator, field);
3888+ closures = translator. getClosures ( field);
38523889
38533890 w.Global global = translator.globals.getGlobalForStaticField (field);
38543891 w.Global ? flag = translator.globals.getGlobalInitializedFlag (field);
@@ -3861,7 +3898,6 @@ class StaticFieldInitializerCodeGenerator extends AstCodeGenerator {
38613898 b.global_get (global);
38623899 translator.convertType (b, global.type.type, outputs.single);
38633900 b.end ();
3864- addNestedClosuresToCompilationQueue ();
38653901 }
38663902}
38673903
@@ -3944,7 +3980,7 @@ class ImplicitFieldAccessorCodeGenerator extends AstCodeGenerator {
39443980 // that instantiates types uses closure information to see whether a type
39453981 // parameter was captured (and loads it from context chain) or not (and
39463982 // loads it directly from `this`).
3947- closures = Closures ( translator, field, findCaptures: false );
3983+ closures = translator. getClosures ( field, findCaptures: false );
39483984
39493985 final source = field.enclosingComponent! .uriToSource[field.fileUri]! ;
39503986 setSourceMapSourceAndFileOffset (source, field.fileOffset);
0 commit comments