From 22b26e5a293d921b860421bbd7da042c2eeeea29 Mon Sep 17 00:00:00 2001 From: Alexander Markov Date: Mon, 3 Mar 2025 11:36:50 -0800 Subject: [PATCH] [vm, dynamic modules] Bugfixes in the bytecode reader and interpreter runtime * Never unbox fields loaded from bytecode as interpreter works with boxed fields only. * Ensure classes are allocate-finalized in AllocateObject runtime entry as interpreter may allocate instances of certain built-in classes (such as _Closure, _Double etc) without prior allocate-finalization. * Fix type arguments vector in constant instances when class doesn't have type parameters but extends a generic class (so its instances have type arguments vector). TEST=ci Change-Id: I488287f84572a79ca7f1fddbd53aed1c3a038cea Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412981 Commit-Queue: Alexander Markov Reviewed-by: Slava Egorov --- runtime/vm/bytecode_reader.cc | 9 ++++++--- runtime/vm/runtime_entry.cc | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/runtime/vm/bytecode_reader.cc b/runtime/vm/bytecode_reader.cc index 76bd79e0e29..4f308d0d763 100644 --- a/runtime/vm/bytecode_reader.cc +++ b/runtime/vm/bytecode_reader.cc @@ -1075,10 +1075,12 @@ ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) { const Type& type = Type::CheckedHandle(Z, ReadObject()); const Class& cls = Class::Handle(Z, type.type_class()); const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld)); - if (type.arguments() != TypeArguments::null()) { - const TypeArguments& type_args = - TypeArguments::Handle(Z, type.arguments()); + if (cls.NumTypeArguments() > 0) { + auto& type_args = TypeArguments::Handle(Z, type.arguments()); + type_args = cls.GetInstanceTypeArguments(thread_, type_args); obj.SetTypeArguments(type_args); + } else { + ASSERT(type.arguments() == TypeArguments::null()); } const intptr_t num_fields = reader_.ReadUInt(); Field& field = Field::Handle(Z); @@ -1549,6 +1551,7 @@ void BytecodeReaderHelper::ReadFieldDeclarations(const Class& cls, (flags & kIsReflectableFlag) != 0, is_late, script_class, type, position, end_position); + field.set_is_unboxed(false); field.set_has_pragma(has_pragma); field.set_is_covariant((flags & kIsCovariantFlag) != 0); field.set_is_generic_covariant_impl((flags & kIsCovariantByClassFlag) != 0); diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index 941a44f81c3..b60785144d7 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -536,6 +536,16 @@ static void ThrowIfError(const Object& result) { // Return value: newly allocated object. DEFINE_RUNTIME_ENTRY(AllocateObject, 2) { const Class& cls = Class::CheckedHandle(zone, arguments.ArgAt(0)); +#if defined(DART_DYNAMIC_MODULES) && !defined(DART_PRECOMPILED_RUNTIME) + if (!cls.is_allocate_finalized()) { + const Error& error = + Error::Handle(zone, cls.EnsureIsAllocateFinalized(thread)); + if (!error.IsNull()) { + Exceptions::PropagateError(error); + UNREACHABLE(); + } + } +#endif ASSERT(cls.is_allocate_finalized()); const Instance& instance = Instance::Handle( zone, Instance::NewAlreadyFinalized(cls, SpaceForRuntimeAllocation()));