Fix crash when caching DebugCommands and classes cache gets modified

#4054
This commit is contained in:
2026-04-16 22:33:36 +02:00
parent 6db9116047
commit b6c7358953
6 changed files with 30 additions and 4 deletions
+2
View File
@@ -1626,7 +1626,9 @@ namespace FlaxEngine.Interop
// We need private types of this assembly too, DefinedTypes contains a lot of types from other assemblies...
var types = referencedTypes.Any() ? assembly.DefinedTypes.Where(x => !referencedTypes.Contains(x.FullName)).ToArray() : assembly.DefinedTypes.ToArray();
#if FLAX_EDITOR
Assert.IsTrue(Utils.GetAssemblies().Count(x => x.GetName().Name == "FlaxEngine.CSharp") == 1);
#endif
return types;
}
@@ -38,6 +38,7 @@ private:
mutable int32 _hasCachedClasses : 1;
mutable ClassesDictionary _classes;
mutable ClassesDictionary _typeClasses;
int32 _reloadCount;
StringAnsi _name;
@@ -234,6 +235,11 @@ public:
/// </summary>
const ClassesDictionary& GetClasses() const;
/// <summary>
/// Gets the classes lookup cache that includes runtime-cached types. Non-stable to iterate over due to dynamic types caching.
/// </summary>
ClassesDictionary& GetTypeClasses() const;
private:
bool LoadCorlib();
bool LoadImage(const String& assemblyPath, const StringView& nativePath);
+2 -1
View File
@@ -142,7 +142,8 @@ void MAssembly::Unload(bool isReloading)
_isLoaded = false;
_hasCachedClasses = false;
#if USE_NETCORE
ArenaAllocator::ClearDelete(_classes);
ArenaAllocator::ClearDelete(_typeClasses);
_classes.Clear();
#else
_classes.ClearDelete();
#endif
+10 -3
View File
@@ -355,7 +355,7 @@ void MCore::UnloadScriptingAssemblyLoadContext()
MAssembly* a = e.Value;
if (!a->IsLoaded() || !a->_hasCachedClasses)
continue;
for (const auto& q : a->GetClasses())
for (const auto& q : a->GetTypeClasses())
{
MClass* c = q.Value;
c->_hasCachedAttributes = false;
@@ -781,6 +781,7 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
MCore::GC::FreeMemory((void*)managedClasses[i].fullname);
MCore::GC::FreeMemory((void*)managedClasses[i].namespace_);
}
_typeClasses = _classes;
static void* RegisterManagedClassNativePointersPtr = GetStaticMethodPointer(TEXT("RegisterManagedClassNativePointers"));
CallStaticMethod<void, NativeClassDefinitions**, int>(RegisterManagedClassNativePointersPtr, &managedClasses, classCount);
@@ -799,6 +800,12 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
return _classes;
}
MAssembly::ClassesDictionary& MAssembly::GetTypeClasses() const
{
GetClasses();
return _typeClasses;
}
void GetAssemblyName(void* assemblyHandle, StringAnsi& name, StringAnsi& fullname)
{
static void* GetAssemblyNamePtr = GetStaticMethodPointer(TEXT("GetAssemblyName"));
@@ -828,7 +835,7 @@ DEFINE_INTERNAL_CALL(void) NativeInterop_CreateClass(NativeClassDefinitions* man
MClass* klass = assembly->Memory.New<MClass>(assembly, managedClass->typeHandle, managedClass->name, managedClass->fullname, managedClass->namespace_, managedClass->typeAttributes);
if (assembly != nullptr)
{
auto& classes = const_cast<MAssembly::ClassesDictionary&>(assembly->GetClasses());
auto& classes = assembly->GetTypeClasses();
MClass* oldKlass;
if (classes.TryGet(klass->GetFullName(), oldKlass))
{
@@ -1746,7 +1753,7 @@ MClass* GetOrCreateClass(MType* typeHandle)
klass = assembly->Memory.New<MClass>(assembly, classInfo.typeHandle, classInfo.name, classInfo.fullname, classInfo.namespace_, classInfo.typeAttributes);
if (assembly != nullptr)
{
auto& classes = const_cast<MAssembly::ClassesDictionary&>(assembly->GetClasses());
auto& classes = assembly->GetTypeClasses();
if (classes.ContainsKey(klass->GetFullName()))
{
LOG(Warning, "Class '{0}' was already added to assembly '{1}'", String(klass->GetFullName()), String(assembly->GetName()));
+5
View File
@@ -1091,6 +1091,11 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
return _classes;
}
const MAssembly::ClassesDictionary& MAssembly::GetTypeClasses() const
{
return GetClasses();
}
bool MAssembly::Load(MonoImage* monoImage)
{
if (IsLoaded())
+5
View File
@@ -303,6 +303,11 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
return _classes;
}
const MAssembly::ClassesDictionary& MAssembly::GetTypeClasses() const
{
return GetClasses();
}
bool MAssembly::LoadCorlib()
{
return false;