[vm, dynamic_modules] Fix instantiated tear-offs of generic static methods and factories

TEST=language/function_subtype/bound_closure7_test
TEST=language/named_arguments_anywhere/order_side_effects_ok_test
TEST=language/regress/regress52243_test

Change-Id: I09765f5a272941388fccac65c083d2239da27b1c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/414320
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2025-03-12 07:47:40 -07:00
committed by Commit Queue
parent bc9723ffce
commit 151e9dd509
2 changed files with 49 additions and 20 deletions
+46 -18
View File
@@ -3568,33 +3568,60 @@ SwitchDispatch:
ClosureDataPtr data = ClosureData::RawCast(function->untag()->data());
FunctionPtr target = Function::RawCast(data->untag()->parent_function());
const intptr_t type_args_len =
InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
intptr_t type_args_len = InterpreterHelpers::ArgDescTypeArgsLen(argdesc_);
const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0;
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
ObjectPtr* argv = FrameArguments(FP, argc);
if (type_args_len > 0) {
// Replace closure receiver with type arguments.
argv[1] = argv[0];
} else if (Function::KindOf(target) == UntaggedFunction::kConstructor) {
// Factory constructors always take type arguments.
FunctionTypePtr signature =
FunctionType::RawCast(function->untag()->signature());
TypeParametersPtr type_params = signature->untag()->type_parameters();
TypeArgumentsPtr type_args = (type_params == null_value)
? TypeArguments::null()
: type_params->untag()->defaults();
argv[0] = type_args;
TypeParametersPtr type_params =
FunctionType::RawCast(function->untag()->signature())
->untag()
->type_parameters();
if (type_params == null_value) {
if (type_args_len > 0) {
SP[1] = function;
goto NoSuchMethodFromPrologue;
}
if (Function::KindOf(target) == UntaggedFunction::kConstructor) {
// Factory constructors always take type arguments.
// Replace closure receiver with type arguments.
argv[0] = TypeArguments::null();
}
} else {
TypeArgumentsPtr delayed_type_arguments =
Closure::RawCast(argv[receiver_idx])
->untag()
->delayed_type_arguments();
if (delayed_type_arguments != Object::empty_type_arguments().ptr()) {
if (type_args_len > 0) {
SP[1] = function;
goto NoSuchMethodFromPrologue;
}
// Replace closure receiver with type arguments.
argv[0] = delayed_type_arguments;
type_args_len =
Smi::Value(type_params->untag()->names()->untag()->length());
} else if (type_args_len > 0) {
// Replace closure receiver with type arguments.
argv[1] = argv[0];
} else if (Function::KindOf(target) == UntaggedFunction::kConstructor) {
// Factory constructors always take type arguments.
// Replace closure receiver with type arguments.
argv[0] = type_params->untag()->defaults();
type_args_len =
Smi::Value(type_params->untag()->names()->untag()->length());
}
}
SP[1] = target;
SP[2] = 0; // Space for result.
SP[3] = argdesc_;
SP[4] = target;
Exit(thread, FP, SP + 5, pc);
SP[5] = Smi::New(type_args_len);
Exit(thread, FP, SP + 6, pc);
INVOKE_RUNTIME(DRT_AdjustArgumentsDesciptorForImplicitClosure,
NativeArguments(thread, 2, SP + 3, SP + 2));
NativeArguments(thread, 3, SP + 3, SP + 2));
argdesc_ = Array::RawCast(SP[2]);
goto TailCallSP1;
@@ -3703,9 +3730,10 @@ SwitchDispatch:
SP[2] = 0; // Space for result.
SP[3] = argdesc_;
SP[4] = SP[1]; // Target.
Exit(thread, FP, SP + 5, pc);
SP[5] = 0; // New type_args_len.
Exit(thread, FP, SP + 6, pc);
INVOKE_RUNTIME(DRT_AdjustArgumentsDesciptorForImplicitClosure,
NativeArguments(thread, 2, SP + 3, SP + 2));
NativeArguments(thread, 3, SP + 3, SP + 2));
argdesc_ = Array::RawCast(SP[2]);
}
+3 -2
View File
@@ -931,14 +931,15 @@ DEFINE_RUNTIME_ENTRY(GetFieldForDispatch, 2) {
// into an arguments descriptor for the target function.
// Arg0: implicit closure arguments descriptor
// Arg1: target function
// Arg2: new type args length
// Return value: target arguments descriptor
DEFINE_RUNTIME_ENTRY(AdjustArgumentsDesciptorForImplicitClosure, 2) {
DEFINE_RUNTIME_ENTRY(AdjustArgumentsDesciptorForImplicitClosure, 3) {
#if defined(DART_DYNAMIC_MODULES)
const auto& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(0));
const auto& target = Function::CheckedHandle(zone, arguments.ArgAt(1));
intptr_t type_args_len = Smi::CheckedHandle(zone, arguments.ArgAt(2)).Value();
const ArgumentsDescriptor args_desc(descriptor);
intptr_t type_args_len = args_desc.TypeArgsLen();
intptr_t num_arguments = args_desc.Count();
if (target.is_static()) {