[vm,dyn_modules] Support instantiated tear-offs of generic instance methods in the interpreter

TEST=ci (co19/Language/Expressions/Property_Extraction/Generic_Method_Instantiation/generic_method_A02_t03)

Change-Id: I9b4862cdbaf6977230e1cce9f5f82c729464425f
Cq-Include-Trybots: luci.dart.try:vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try,vm-dyn-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/443638
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Alexander Markov
2025-08-06 06:09:29 -07:00
committed by Commit Queue
parent 610097050c
commit f46670e00c
4 changed files with 68 additions and 9 deletions
+11
View File
@@ -48,6 +48,17 @@ static const KBCInstr
KernelBytecode::kTrap,
};
static const KBCInstr kVMInternal_ImplicitInstanceClosureInstructions[] = {
KernelBytecode::kVMInternal_ImplicitInstanceClosure,
0,
0,
KernelBytecode::kReturnTOS,
};
static const KBCInstr kVMInternal_ImplicitInstanceClosure_WideInstructions[] = {
KernelBytecode::kTrap,
};
#define DECLARE_INSTRUCTIONS(name, fmt, kind, fmta, fmtb, fmtc) \
static const KBCInstr k##name##Instructions[] = { \
KernelBytecode::k##name, \
+5 -3
View File
@@ -205,11 +205,14 @@ namespace dart {
// These bytecodes are only generated within the VM. Reassigning their
// opcodes is not a breaking change.
#define INTERNAL_KERNEL_BYTECODES_WITH_CUSTOM_CODE(V) \
/* VMInternal_ImplicitConstructorClosure uses D_F encoding as it calls */ \
/* constructor and should be compatible with other ***Call instructions */ \
/* ImplicitConstructorClosure and ImplicitInstanceClosure instructions */ \
/* use D_F encoding as they may call target constructor or method and */ \
/* should be compatible with other ***Call instructions */ \
/* in order to support DecodeArgc when returning from a call. */ \
V(VMInternal_ImplicitConstructorClosure, D_F, ORDN, num, num, ___) \
V(VMInternal_ImplicitConstructorClosure_Wide, D_F, ORDN, num, num, ___) \
V(VMInternal_ImplicitInstanceClosure, D_F, ORDN, num, num, ___) \
V(VMInternal_ImplicitInstanceClosure_Wide, D_F, ORDN, num, num, ___) \
#define INTERNAL_KERNEL_BYTECODES_WITH_DEFAULT_CODE(V) \
V(VMInternal_ImplicitGetter, 0, ORDN, ___, ___, ___) \
@@ -221,7 +224,6 @@ namespace dart {
V(VMInternal_InvokeField, 0, ORDN, ___, ___, ___) \
V(VMInternal_ForwardDynamicInvocation, 0, ORDN, ___, ___, ___) \
V(VMInternal_ImplicitStaticClosure, 0, ORDN, ___, ___, ___) \
V(VMInternal_ImplicitInstanceClosure, 0, ORDN, ___, ___, ___) \
V(VMInternal_NoSuchMethodDispatcher, 0, ORDN, ___, ___, ___) \
#define INTERNAL_KERNEL_BYTECODES_LIST(V) \
+52 -2
View File
@@ -3757,7 +3757,7 @@ SwitchDispatch:
}
{
BYTECODE(VMInternal_ImplicitInstanceClosure, 0);
BYTECODE(VMInternal_ImplicitInstanceClosure, D_F);
FunctionPtr function = FrameFunction(FP);
ASSERT(Function::KindOf(function) ==
UntaggedFunction::kImplicitClosureFunction);
@@ -3770,10 +3770,60 @@ SwitchDispatch:
const intptr_t argc =
InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx;
ObjectPtr* argv = FrameArguments(FP, argc);
ClosurePtr closure = Closure::RawCast(argv[receiver_idx]);
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;
}
} else {
TypeArgumentsPtr delayed_type_arguments =
closure->untag()->delayed_type_arguments();
if (delayed_type_arguments != Object::empty_type_arguments().ptr()) {
if (type_args_len > 0) {
SP[1] = function;
goto NoSuchMethodFromPrologue;
}
// Type arguments.
*++SP = delayed_type_arguments;
ObjectPtr* call_base = SP;
// Captured receiver.
*++SP = closure->untag()->context();
// Copy the rest of the arguments.
for (intptr_t i = receiver_idx + 1; i < argc; i++) {
*++SP = argv[i];
}
const intptr_t new_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;
SP[5] = Smi::New(new_type_args_len);
Exit(thread, FP, SP + 6, pc);
INVOKE_RUNTIME(DRT_AdjustArgumentsDesciptorForImplicitClosure,
NativeArguments(thread, 3, SP + 3, SP + 2));
argdesc_ = Array::RawCast(SP[2]);
ObjectPtr* call_top = SP + 1;
if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) {
HANDLE_EXCEPTION;
}
DISPATCH();
}
}
// Replace closure receiver with captured receiver
// and call target function.
ClosurePtr closure = Closure::RawCast(argv[receiver_idx]);
argv[receiver_idx] = closure->untag()->context();
SP[1] = target;
-4
View File
@@ -1060,10 +1060,6 @@ DEFINE_RUNTIME_ENTRY(AdjustArgumentsDesciptorForImplicitClosure, 3) {
if (target.IsGenerativeConstructor()) {
// Type arguments are not passed to a generative constructor.
type_args_len = 0;
} else {
// No need to adjust arguments descriptor.
arguments.SetReturn(descriptor);
return;
}
}