Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Convert RuntimeAssembly icalls to use QCallAssembly/ObjectHand… #63558

Merged
merged 4 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ private static void OnAssemblyLoad(RuntimeAssembly assembly)
}

// This method is called by the VM.
private static RuntimeAssembly? OnResourceResolve(RuntimeAssembly assembly, string resourceName)
internal static RuntimeAssembly? OnResourceResolve(RuntimeAssembly assembly, string resourceName)
{
return InvokeResolveEvent(ResourceResolve, assembly, resourceName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ namespace System.Reflection
[StructLayout(LayoutKind.Sequential)]
internal sealed class RuntimeAssembly : Assembly
{
private enum AssemblyInfoKind
{
Location = 1,
CodeBase = 2,
FullName = 3,
ImageRuntimeVersion = 4
}

private sealed class ResolveEventHolder
{
public event ModuleResolveEventHandler? ModuleResolve;
Expand Down Expand Up @@ -65,30 +73,26 @@ public unsafe UnmanagedMemoryStreamForModule(byte* pointer, long length, Module

private ResolveEventHolder? resolve_event_holder;

public extern override MethodInfo? EntryPoint
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}

public override bool ReflectionOnly => false;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetEntryPoint(QCallAssembly assembly, ObjectHandleOnStack res);

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override string? CodeBase
public override MethodInfo? EntryPoint
{
get
{
return get_code_base(this);
var this_assembly = this;
MethodInfo? res = null;
GetEntryPoint(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref res));
return res;
}
}

public override string? FullName
{
get
{
return get_fullname(this);
}
}
public override bool ReflectionOnly => false;

[RequiresAssemblyFiles(ThrowingMessageInRAF)]
public override string? CodeBase => GetInfo(AssemblyInfoKind.CodeBase);

public override string? FullName => GetInfo(AssemblyInfoKind.FullName);

//
// We can't store the event directly in this class, since the
Expand All @@ -106,22 +110,25 @@ public override event ModuleResolveEventHandler? ModuleResolve
}
}

public override Module ManifestModule => GetManifestModuleInternal();
public override Module ManifestModule
{
get
{
var this_assembly = this;
Module? res = null;
GetManifestModuleInternal(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref res));
return res!;
}
}

[Obsolete(Obsoletions.GlobalAssemblyCacheMessage, DiagnosticId = Obsoletions.GlobalAssemblyCacheDiagId, UrlFormat = Obsoletions.SharedUrlFormat)]
public override bool GlobalAssemblyCache => false;

public override long HostContext => 0;

public override string ImageRuntimeVersion => InternalImageRuntimeVersion(this);
public override string ImageRuntimeVersion => GetInfo(AssemblyInfoKind.ImageRuntimeVersion);

public override string Location
{
get
{
return get_location();
}
}
public override string Location => GetInfo(AssemblyInfoKind.Location);

// TODO: consider a dedicated icall instead
public override bool IsCollectible => AssemblyLoadContext.GetLoadContext((Assembly)this)!.IsCollectible;
Expand Down Expand Up @@ -150,23 +157,41 @@ public override string Location
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override string[] GetManifestResourceNames();
private static extern void GetManifestResourceNames(QCallAssembly assembly_h, ObjectHandleOnStack res);

public override string[] GetManifestResourceNames()
{
var this_assembly = this;
string[]? res = null;
GetManifestResourceNames(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref res));
return res!;
}

[RequiresUnreferencedCode("Types might be removed")]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override Type[] GetExportedTypes();
private static extern void GetExportedTypes(QCallAssembly assembly_h, ObjectHandleOnStack res);

[RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetExportedTypes()
{
var this_assembly = this;
Type[]? res = null;
GetExportedTypes(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref res));
return res!;
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Type[] GetTopLevelForwardedTypes();
private static extern void GetTopLevelForwardedTypes(QCallAssembly assembly_h, ObjectHandleOnStack res);

[RequiresUnreferencedCode("Types might be removed")]
public override Type[] GetForwardedTypes()
{
Type[] topLevelTypes = GetTopLevelForwardedTypes();
List<Type> forwardedTypes = new List<Type>(topLevelTypes);
var this_assembly = this;
Type[]? topLevelTypes = null;
GetTopLevelForwardedTypes(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref topLevelTypes));
List<Type> forwardedTypes = new List<Type>(topLevelTypes!);
List<Exception> exceptions = new List<Exception>();

foreach (Type t in topLevelTypes)
foreach (Type t in topLevelTypes!)
AddPublicNestedTypes(t, forwardedTypes, exceptions);

if (exceptions.Count > 0)
Expand Down Expand Up @@ -208,7 +233,8 @@ private static void AddPublicNestedTypes(Type type, List<Type> types, List<Excep
if (resourceName.Length == 0)
throw new ArgumentException("String cannot have zero length.");
ManifestResourceInfo result = new ManifestResourceInfo(null, null, 0);
bool found = GetManifestResourceInfoInternal(resourceName, result);
var this_assembly = this;
bool found = GetManifestResourceInfoInternal(new QCallAssembly(ref this_assembly), resourceName, result);
if (found)
return result;
else
Expand All @@ -226,13 +252,21 @@ private static void AddPublicNestedTypes(Type type, List<Type> types, List<Excep

unsafe
{
byte* data = (byte*)GetManifestResourceInternal(name, out int length, out Module resourceModule);
if (data == null)
return null;
int length;
Module? resourceModule = null;
RuntimeAssembly? assembly = this;
byte* data = (byte*)GetManifestResourceInternal(new QCallAssembly(ref assembly), name, out length, ObjectHandleOnStack.Create(ref resourceModule));
if (data == null) {
assembly = AssemblyLoadContext.OnResourceResolve(assembly!, name);
if (assembly != null)
data = (byte*)GetManifestResourceInternal(new QCallAssembly(ref assembly), name, out length, ObjectHandleOnStack.Create(ref resourceModule));
if (data == null)
return null;
}

// It cannot use SafeBuffer mode because not all methods are supported in this
// mode (e.g. UnmanagedMemoryStream.get_PositionPointer)
return new UnmanagedMemoryStreamForModule(data, length, resourceModule);
return new UnmanagedMemoryStreamForModule(data, length, resourceModule!);
}
}

Expand All @@ -252,7 +286,7 @@ private static void AddPublicNestedTypes(Type type, List<Type> types, List<Excep

public override AssemblyName GetName(bool copiedName)
{
return AssemblyName.Create(_mono_assembly, get_code_base (this));
return AssemblyName.Create(_mono_assembly, GetInfo(AssemblyInfoKind.CodeBase));
}

[RequiresUnreferencedCode("Types might be removed")]
Expand Down Expand Up @@ -306,7 +340,10 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit)

public override Module[] GetModules(bool getResourceModules)
{
Module[] modules = GetModulesInternal();
var this_assembly = this;
Module[]? tmp = null;
GetModulesInternal(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref tmp));
Module[] modules = tmp!;

if (!getResourceModules)
{
Expand All @@ -327,6 +364,7 @@ public override Module[] GetLoadedModules(bool getResourceModules)

internal static AssemblyName[] GetReferencedAssemblies(Assembly assembly)
{
// Can't use QCallAssembly as assembly can be an AssemblyBuilder
using (var nativeNames = new Mono.SafeGPtrArrayHandle(InternalGetReferencedAssemblies(assembly)))
{
int numAssemblies = nativeNames.Length;
Expand Down Expand Up @@ -463,37 +501,31 @@ internal static RuntimeAssembly InternalLoad(AssemblyName assemblyRef, ref Stack
return assembly;
}

// FIXME: Merge some of these

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern string get_location();

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern string? get_code_base(Assembly a);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern string get_fullname(Assembly a);
private static extern void GetInfo(QCallAssembly assembly, ObjectHandleOnStack res, AssemblyInfoKind kind);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern string InternalImageRuntimeVersion(Assembly a);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool GetManifestResourceInfoInternal(string name, ManifestResourceInfo info);
private string GetInfo(AssemblyInfoKind kind)
vargaz marked this conversation as resolved.
Show resolved Hide resolved
{
var this_assembly = this;
string? res = null;
GetInfo(new QCallAssembly(ref this_assembly), ObjectHandleOnStack.Create(ref res), kind);
return res!;
}

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern IntPtr /* byte* */ GetManifestResourceInternal(string name, out int size, out Module module);
private static extern bool GetManifestResourceInfoInternal(QCallAssembly assembly, string name, ManifestResourceInfo info);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Module GetManifestModuleInternal();
private static extern IntPtr /* byte* */ GetManifestResourceInternal(QCallAssembly assembly, string name, out int size, ObjectHandleOnStack module);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern Module[] GetModulesInternal();
private static extern void GetManifestModuleInternal(QCallAssembly assembly, ObjectHandleOnStack res);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern IntPtr InternalGetReferencedAssemblies(Assembly module);
private static extern void GetModulesInternal(QCallAssembly assembly, ObjectHandleOnStack res);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern object GetFilesInternal(string? name, bool getResourceModules);
private static extern IntPtr InternalGetReferencedAssemblies(Assembly assembly);

internal string? GetSimpleName()
{
Expand Down
22 changes: 9 additions & 13 deletions src/mono/mono/metadata/icall-def-netcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,20 +235,16 @@ HANDLES(MMETHI_2, "get_parameter_info", ves_icall_System_Reflection_MonoMethodIn
HANDLES(MMETHI_3, "get_retval_marshal", ves_icall_System_MonoMethodInfo_get_retval_marshal, MonoReflectionMarshalAsAttribute, 1, (MonoMethod_ptr))

ICALL_TYPE(RASSEM, "System.Reflection.RuntimeAssembly", RASSEM_1)
HANDLES(RASSEM_1, "GetExportedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetExportedTypes, MonoArray, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_1a, "GetFilesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetFilesInternal, MonoObject, 3, (MonoReflectionAssembly, MonoString, MonoBoolean))
HANDLES(RASSEM_2, "GetManifestModuleInternal", ves_icall_System_Reflection_Assembly_GetManifestModuleInternal, MonoReflectionModule, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_3, "GetManifestResourceInfoInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInfoInternal, MonoBoolean, 3, (MonoReflectionAssembly, MonoString, MonoManifestResourceInfo))
HANDLES(RASSEM_4, "GetManifestResourceInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInternal, gpointer, 4, (MonoReflectionAssembly, MonoString, gint32_ref, MonoReflectionModuleOut))
HANDLES(RASSEM_5, "GetManifestResourceNames", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceNames, MonoArray, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_6, "GetModulesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetModulesInternal, MonoArray, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_6b, "GetTopLevelForwardedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetTopLevelForwardedTypes, MonoArray, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_1, "GetEntryPoint", ves_icall_System_Reflection_RuntimeAssembly_GetEntryPoint, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_9, "GetExportedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetExportedTypes, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_13, "GetInfo", ves_icall_System_Reflection_RuntimeAssembly_GetInfo, void, 3, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack, guint32))
HANDLES(RASSEM_2, "GetManifestModuleInternal", ves_icall_System_Reflection_Assembly_GetManifestModuleInternal, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_3, "GetManifestResourceInfoInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInfoInternal, MonoBoolean, 3, (MonoQCallAssemblyHandle, MonoString, MonoManifestResourceInfo))
HANDLES(RASSEM_4, "GetManifestResourceInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInternal, gpointer, 4, (MonoQCallAssemblyHandle, MonoString, gint32_ref, MonoObjectHandleOnStack))
HANDLES(RASSEM_5, "GetManifestResourceNames", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceNames, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_6, "GetModulesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetModulesInternal, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_6b, "GetTopLevelForwardedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetTopLevelForwardedTypes, void, 2, (MonoQCallAssemblyHandle, MonoObjectHandleOnStack))
HANDLES(RASSEM_7, "InternalGetReferencedAssemblies", ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies, GPtrArray_ptr, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_8, "InternalImageRuntimeVersion", ves_icall_System_Reflection_RuntimeAssembly_InternalImageRuntimeVersion, MonoString, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_9, "get_EntryPoint", ves_icall_System_Reflection_RuntimeAssembly_get_EntryPoint, MonoReflectionMethod, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_10, "get_code_base", ves_icall_System_Reflection_RuntimeAssembly_get_code_base, MonoString, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_11, "get_fullname", ves_icall_System_Reflection_RuntimeAssembly_get_fullname, MonoString, 1, (MonoReflectionAssembly))
HANDLES(RASSEM_12, "get_location", ves_icall_System_Reflection_RuntimeAssembly_get_location, MonoString, 1, (MonoReflectionAssembly))

ICALL_TYPE(MCMETH, "System.Reflection.RuntimeConstructorInfo", MCMETH_1)
HANDLES(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_RuntimeMethodInfo_GetGenericMethodDefinition, MonoReflectionMethod, 1, (MonoReflectionMethod))
Expand Down
Loading