[CoreCLR] Add support for mono_assembly_open.

This includes going through all uses of mono_assembly_open, and make sure the release
the returned assembly.
This commit is contained in:
Rolf Bjarne Kvinge 2021-03-22 12:53:52 +01:00
Родитель 18ac48c5c8
Коммит a82575189b
9 изменённых файлов: 72 добавлений и 2 удалений

Просмотреть файл

@ -77,7 +77,9 @@ xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, G
void
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
{
xamarin_open_and_register (PRODUCT_DUAL_ASSEMBLY, exception_gchandle);
MonoAssembly *assembly;
assembly = xamarin_open_and_register (PRODUCT_DUAL_ASSEMBLY, exception_gchandle);
xamarin_mono_object_release (&assembly);
}
MonoClass *
@ -143,4 +145,19 @@ xamarin_mono_object_release (MonoObject **mobj_ref)
*mobj_ref = NULL;
}
/* Implementation of the Mono Embedding API */
// returns a retained MonoAssembly *
MonoAssembly *
mono_assembly_open (const char * filename, MonoImageOpenStatus * status)
{
assert (status == NULL);
MonoAssembly *rv = xamarin_find_assembly (filename);
LOG_CORECLR (stderr, "mono_assembly_open (%s, %p) => MonoObject=%p GCHandle=%p\n", filename, status, rv, rv->gchandle);
return rv;
}
#endif // CORECLR_RUNTIME

Просмотреть файл

@ -287,6 +287,14 @@
OnlyDynamicUsage = false,
},
new XDelegate ("MonoAssembly *", "IntPtr", "xamarin_find_assembly",
"const char *","IntPtr", "assembly_name"
) {
WrappedManagedFunction = "FindAssembly",
OnlyDynamicUsage = false,
OnlyCoreCLR = true,
},
};
delegates.CalculateLengths ();
#><#+

Просмотреть файл

@ -251,7 +251,9 @@
new Export ("MonoAssembly *", "mono_assembly_open",
"const char *", "filename",
"MonoImageOpenStatus *", "status"
),
) {
HasCoreCLRBridgeFunction = true,
},
new Export ("MonoImage *", "mono_assembly_get_image",
"MonoAssembly *", "assembly"

Просмотреть файл

@ -550,6 +550,8 @@ run_application_init (xamarin_initialize_data *data)
MonoImage *image = mono_assembly_get_image (assembly);
xamarin_mono_object_release (&assembly);
MonoClass *app_class = mono_class_from_name (image, "AppKit", "NSApplication");
if (!app_class)
xamarin_assertion_message ("Fatal error: failed to load the NSApplication class");

Просмотреть файл

@ -65,7 +65,12 @@ char *xamarin_get_mono_runtime_build_info (); // returns NULL if libmono couldn'
typedef int32_t mono_bool;
/* metadata/image.h */
#if defined (CORECLR_RUNTIME)
// In Mono, MonoAssembly is not related to MonoObject, but for the CoreCLR bridge we use the same memory representation for both types.
typedef struct _MonoObject MonoAssembly;
#else
typedef struct _MonoAssembly MonoAssembly;
#endif
typedef struct _MonoAssemblyName MonoAssemblyName;
typedef struct _MonoImage MonoImage;

Просмотреть файл

@ -472,5 +472,7 @@ xamarin_main (int argc, char *argv[], enum XamarinLaunchMode launch_mode)
break;
}
xamarin_mono_object_release (&assembly);
return rv;
}

Просмотреть файл

@ -143,6 +143,8 @@ void
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
{
xamarin_register_monoassembly (entry_assembly, exception_gchandle);
// We don't need the entry_assembly around anymore, so release it.
xamarin_mono_object_release (&entry_assembly);
}
MonoClass *

Просмотреть файл

@ -941,6 +941,7 @@ xamarin_file_exists (const char *path)
return stat (path, &buffer) == 0;
}
// Returns a retained MonoObject. Caller must release.
MonoAssembly *
xamarin_open_assembly (const char *name)
{
@ -996,6 +997,7 @@ xamarin_register_monoassembly (MonoAssembly *assembly, GCHandle *exception_gchan
return *exception_gchandle == INVALID_GCHANDLE;
}
// Returns a retained MonoObject. Caller must release.
MonoAssembly *
xamarin_open_and_register (const char *aname, GCHandle *exception_gchandle)
{

Просмотреть файл

@ -10,6 +10,7 @@
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
namespace ObjCRuntime {
@ -29,6 +30,35 @@ namespace ObjCRuntime {
xamarin_log (message);
}
// Returns a retained MonoObject. Caller must release.
static IntPtr FindAssembly (IntPtr assembly_name)
{
var path = Marshal.PtrToStringAuto (assembly_name);
var name = Path.GetFileNameWithoutExtension (path);
log_coreclr ($"Runtime.FindAssembly (0x{assembly_name.ToString ("x")} = {name})");
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies ()) {
log_coreclr ($" Assembly from app domain: {asm.GetName ().Name}");
if (asm.GetName ().Name == name) {
log_coreclr ($" Match!");
return GetMonoObject (asm);
}
}
log_coreclr ($" Did not find the assembly in the app domain's loaded assemblies. Will try to load it.");
var loadedAssembly = Assembly.LoadFrom (path);
if (loadedAssembly != null) {
log_coreclr ($" Loaded {loadedAssembly.GetName ().Name}");
return GetMonoObject (loadedAssembly);
}
log_coreclr ($" Found no assembly named {name}");
throw new InvalidOperationException ($"Could not find any assemblies named {name}");
}
// Returns a retained MonoObject. Caller must release.
static IntPtr GetMonoObject (object obj)
{