[dart2wasm] Move covariance checks from async inner to wrapper functions

New passing test: language/async/covariant_type_test

Fixes #51601

Change-Id: Id5e807b463db67d0e44842e375d35604e35398cd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286462
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2023-03-08 11:22:51 +00:00 committed by Commit Queue
parent 91ea353298
commit 0ad9f2ec66
2 changed files with 26 additions and 13 deletions

View file

@ -315,12 +315,21 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
w.Local stubArguments = stub.locals[0];
w.Local stubStack = stub.locals[1];
// Set up the type parameter to local mapping, in case a type parameter is
// used in the return type.
// Set up the parameter to local mapping, for type checks and in case a
// type parameter is used in the return type.
int paramIndex = parameterOffset;
for (TypeParameter typeParam in functionNode.typeParameters) {
typeLocals[typeParam] = paramLocals[paramIndex++];
}
for (VariableDeclaration param in functionNode.positionalParameters) {
locals[param] = paramLocals[paramIndex++];
}
for (VariableDeclaration param in functionNode.namedParameters) {
locals[param] = paramLocals[paramIndex++];
}
generateTypeChecks(functionNode.typeParameters, functionNode,
ParameterInfo.fromLocalFunction(functionNode));
// Push the type argument to the async helper, specifying the type argument
// of the returned `Future`.
@ -470,15 +479,12 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
}
}
void generateTypeChecks(Member member) {
void generateTypeChecks(List<TypeParameter> typeParameters,
FunctionNode function, ParameterInfo paramInfo) {
if (translator.options.omitTypeChecks) {
return;
}
final List<TypeParameter> typeParameters = member is Constructor
? member.enclosingClass.typeParameters
: member.function!.typeParameters;
for (TypeParameter typeParameter in typeParameters) {
if (typeParameter.isCovariantByClass &&
typeParameter.bound != translator.coreTypes.objectNullableRawType) {
@ -490,7 +496,6 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
// Local for the parameter type if any of the parameters need type checks
w.Local? parameterExpectedTypeLocal;
final ParameterInfo paramInfo = translator.paramInfoFor(reference);
final int parameterOffset = thisLocal == null ? 0 : 1;
final int implicitParams = parameterOffset + paramInfo.typeParamCount;
void generateValueParameterCheck(VariableDeclaration variable, int index) {
@ -509,13 +514,12 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
);
}
final List<VariableDeclaration> positional =
member.function!.positionalParameters;
final List<VariableDeclaration> positional = function.positionalParameters;
for (int i = 0; i < positional.length; i++) {
generateValueParameterCheck(positional[i], i);
}
final List<VariableDeclaration> named = member.function!.namedParameters;
final List<VariableDeclaration> named = function.namedParameters;
for (var param in named) {
generateValueParameterCheck(param, paramInfo.nameIndex[param.name]!);
}
@ -526,7 +530,15 @@ class CodeGenerator extends ExpressionVisitor1<w.ValueType, w.ValueType>
if (member is Constructor) {
generateInitializerList(member);
}
generateTypeChecks(member);
// Async function type checks are generated in the wrapper functions, in
// [generateAsyncWrapper].
if (member.function!.asyncMarker != AsyncMarker.Async) {
final List<TypeParameter> typeParameters = member is Constructor
? member.enclosingClass.typeParameters
: member.function!.typeParameters;
generateTypeChecks(
typeParameters, member.function!, translator.paramInfoFor(reference));
}
Statement? body = member.function!.body;
if (body != null) {
visitStatement(body);

View file

@ -208,7 +208,8 @@ class SyncStarCodeGenerator extends CodeGenerator {
void generate() {
closures = Closures(this);
setupParametersAndContexts(member);
generateTypeChecks(member);
generateTypeChecks(member.function!.typeParameters, member.function!,
translator.paramInfoFor(reference));
generateBodies(member.function!);
}