[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:
committed by
Commit Queue
parent
610097050c
commit
f46670e00c
@@ -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, \
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user