- Added try-catch to assembly compilation call.
- Added empty list checks for metadata references building. - Made ACL cleanup more reliable. - Updated some GET functions in AssemblyManager to have better reliability and error handling.
This commit is contained in:
@@ -260,7 +260,8 @@ public class AssemblyManager
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
this.OnException?.Invoke($"{nameof(AssemblyManager)}::{nameof(GetTypesByName)}() | Error: {e.Message}", e);
|
this.OnException?.Invoke(
|
||||||
|
$"{nameof(AssemblyManager)}::{nameof(GetTypesByName)}() | Error: {e.Message}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -309,12 +310,16 @@ public class AssemblyManager
|
|||||||
OpsLockLoaded.EnterReadLock();
|
OpsLockLoaded.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return AssemblyLoadContext.Default.Assemblies
|
return _defaultContextTypes
|
||||||
.SelectMany(a => a.GetSafeTypes())
|
.Select(kvp => kvp.Value)
|
||||||
.Concat(LoadedACLs
|
.Concat(LoadedACLs
|
||||||
.SelectMany(kvp => kvp.Value.AssembliesTypes.Select(kv => kv.Value)))
|
.SelectMany(kvp => kvp.Value?.AssembliesTypes.Select(kv => kv.Value)))
|
||||||
.ToImmutableList();
|
.ToImmutableList();
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return ImmutableList<Type>.Empty;
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
OpsLockLoaded.ExitReadLock();
|
OpsLockLoaded.ExitReadLock();
|
||||||
@@ -332,8 +337,17 @@ public class AssemblyManager
|
|||||||
OpsLockLoaded.EnterReadLock();
|
OpsLockLoaded.EnterReadLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (LoadedACLs.IsEmpty)
|
||||||
|
{
|
||||||
|
return ImmutableList<LoadedACL>.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
return LoadedACLs.Select(kvp => kvp.Value).ToImmutableList();
|
return LoadedACLs.Select(kvp => kvp.Value).ToImmutableList();
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return ImmutableList<LoadedACL>.Empty;
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
OpsLockLoaded.ExitReadLock();
|
OpsLockLoaded.ExitReadLock();
|
||||||
@@ -387,8 +401,18 @@ public class AssemblyManager
|
|||||||
return AssemblyLoadingSuccessState.AlreadyLoaded;
|
return AssemblyLoadingSuccessState.AlreadyLoaded;
|
||||||
|
|
||||||
// compile
|
// compile
|
||||||
var state = acl.Acl.CompileAndLoadScriptAssembly(compiledAssemblyName, syntaxTree, externalMetadataReferences,
|
AssemblyLoadingSuccessState state;
|
||||||
compilationOptions, out var messages, externFileAssemblyRefs);
|
string messages;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
state = acl.Acl.CompileAndLoadScriptAssembly(compiledAssemblyName, syntaxTree, externalMetadataReferences,
|
||||||
|
compilationOptions, out messages, externFileAssemblyRefs);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
ModUtils.Logging.PrintError($"{nameof(AssemblyManager)}::{nameof(LoadAssemblyFromMemory)}() | Failed to compile and load assemblies for [ {compiledAssemblyName} / {friendlyName} ]! Details: {e.Message}");
|
||||||
|
return AssemblyLoadingSuccessState.InvalidAssembly;
|
||||||
|
}
|
||||||
|
|
||||||
// get types
|
// get types
|
||||||
if (state is AssemblyLoadingSuccessState.Success)
|
if (state is AssemblyLoadingSuccessState.Success)
|
||||||
@@ -654,7 +678,15 @@ public class AssemblyManager
|
|||||||
OpsLockUnloaded.EnterWriteLock();
|
OpsLockUnloaded.EnterWriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (id.Equals(Guid.Empty) || !LoadedACLs.ContainsKey(id) || LoadedACLs[id] is null)
|
if (LoadedACLs.ContainsKey(id) && LoadedACLs[id] == null)
|
||||||
|
{
|
||||||
|
if (!LoadedACLs.TryRemove(id, out _))
|
||||||
|
{
|
||||||
|
ModUtils.Logging.PrintWarning($"An ACL with the GUID {id.ToString()} was found as null. Unable to remove null ACL entry.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.Equals(Guid.Empty) || !LoadedACLs.ContainsKey(id))
|
||||||
{
|
{
|
||||||
return false; // nothing to dispose of
|
return false; // nothing to dispose of
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-25
@@ -143,7 +143,7 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
var externAssemblyRefs = externFileAssemblyReferences is not null ? externFileAssemblyReferences.ToImmutableList() : ImmutableList<Assembly>.Empty;
|
var externAssemblyRefs = externFileAssemblyReferences is not null ? externFileAssemblyReferences.ToImmutableList() : ImmutableList<Assembly>.Empty;
|
||||||
var externAssemblyNames = externAssemblyRefs.Any() ? externAssemblyRefs
|
var externAssemblyNames = !externAssemblyRefs.IsEmpty ? externAssemblyRefs
|
||||||
.Where(a => a.FullName is not null)
|
.Where(a => a.FullName is not null)
|
||||||
.Select(a => a.FullName).ToImmutableHashSet()
|
.Select(a => a.FullName).ToImmutableHashSet()
|
||||||
: ImmutableHashSet<string>.Empty;
|
: ImmutableHashSet<string>.Empty;
|
||||||
@@ -178,33 +178,37 @@ public class MemoryFileAssemblyContextLoader : AssemblyLoadContext
|
|||||||
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
||||||
).ToList());
|
).ToList());
|
||||||
|
|
||||||
// build metadata refs from ACL assemblies from files/disk.
|
ImmutableList<AssemblyManager.LoadedACL> loadedAcls = _assemblyManager.GetAllLoadedACLs().ToImmutableList();
|
||||||
foreach (AssemblyManager.LoadedACL loadedAcl in _assemblyManager.GetAllLoadedACLs())
|
if (!loadedAcls.IsEmpty)
|
||||||
{
|
{
|
||||||
if(loadedAcl.Acl.IsTemplateMode || loadedAcl.Acl.IsDisposed)
|
// build metadata refs from ACL assemblies from files/disk.
|
||||||
continue;
|
foreach (AssemblyManager.LoadedACL loadedAcl in loadedAcls)
|
||||||
metadataReferences.AddRange(loadedAcl.Acl.Assemblies
|
{
|
||||||
.Where(a =>
|
if(loadedAcl?.Acl is null || loadedAcl.Acl.IsTemplateMode || loadedAcl.Acl.IsDisposed)
|
||||||
{
|
continue;
|
||||||
if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit"))
|
metadataReferences.AddRange(loadedAcl.Acl.Assemblies
|
||||||
return false;
|
.Where(a =>
|
||||||
if (a.FullName is null)
|
{
|
||||||
return true;
|
if (a.IsDynamic || string.IsNullOrWhiteSpace(a.Location) || a.Location.Contains("xunit"))
|
||||||
return !externAssemblyNames.Contains(a.FullName); // exclude duplicates
|
return false;
|
||||||
})
|
if (a.FullName is null)
|
||||||
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
return true;
|
||||||
.Union(externAssemblyRefs // add custom supplied assemblies
|
return !externAssemblyNames.Contains(a.FullName); // exclude duplicates
|
||||||
.Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")))
|
})
|
||||||
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
||||||
).ToList());
|
.Union(externAssemblyRefs // add custom supplied assemblies
|
||||||
}
|
.Where(a => !(a.IsDynamic || string.IsNullOrEmpty(a.Location) || a.Location.Contains("xunit")))
|
||||||
|
.Select(a => MetadataReference.CreateFromFile(a.Location) as MetadataReference)
|
||||||
|
).ToList());
|
||||||
|
}
|
||||||
|
|
||||||
// build metadata refs from in-memory images
|
// build metadata refs from in-memory images
|
||||||
foreach (var loadedAcl in _assemblyManager.GetAllLoadedACLs())
|
foreach (var loadedAcl in loadedAcls)
|
||||||
{
|
{
|
||||||
if (loadedAcl.Acl.CompiledAssemblyImage is null || loadedAcl.Acl.CompiledAssemblyImage.Length == 0)
|
if (loadedAcl.Acl.CompiledAssemblyImage is null || loadedAcl.Acl.CompiledAssemblyImage.Length == 0)
|
||||||
continue;
|
continue;
|
||||||
metadataReferences.Add(MetadataReference.CreateFromImage(loadedAcl.Acl.CompiledAssemblyImage));
|
metadataReferences.Add(MetadataReference.CreateFromImage(loadedAcl.Acl.CompiledAssemblyImage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change inaccessible options to allow public access to restricted members
|
// Change inaccessible options to allow public access to restricted members
|
||||||
|
|||||||
Reference in New Issue
Block a user