[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:
Родитель
18ac48c5c8
Коммит
a82575189b
|
@ -77,7 +77,9 @@ xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, G
|
||||||
void
|
void
|
||||||
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
|
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 *
|
MonoClass *
|
||||||
|
@ -143,4 +145,19 @@ xamarin_mono_object_release (MonoObject **mobj_ref)
|
||||||
*mobj_ref = NULL;
|
*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
|
#endif // CORECLR_RUNTIME
|
||||||
|
|
|
@ -287,6 +287,14 @@
|
||||||
OnlyDynamicUsage = false,
|
OnlyDynamicUsage = false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
new XDelegate ("MonoAssembly *", "IntPtr", "xamarin_find_assembly",
|
||||||
|
"const char *","IntPtr", "assembly_name"
|
||||||
|
) {
|
||||||
|
WrappedManagedFunction = "FindAssembly",
|
||||||
|
OnlyDynamicUsage = false,
|
||||||
|
OnlyCoreCLR = true,
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
delegates.CalculateLengths ();
|
delegates.CalculateLengths ();
|
||||||
#><#+
|
#><#+
|
||||||
|
|
|
@ -251,7 +251,9 @@
|
||||||
new Export ("MonoAssembly *", "mono_assembly_open",
|
new Export ("MonoAssembly *", "mono_assembly_open",
|
||||||
"const char *", "filename",
|
"const char *", "filename",
|
||||||
"MonoImageOpenStatus *", "status"
|
"MonoImageOpenStatus *", "status"
|
||||||
),
|
) {
|
||||||
|
HasCoreCLRBridgeFunction = true,
|
||||||
|
},
|
||||||
|
|
||||||
new Export ("MonoImage *", "mono_assembly_get_image",
|
new Export ("MonoImage *", "mono_assembly_get_image",
|
||||||
"MonoAssembly *", "assembly"
|
"MonoAssembly *", "assembly"
|
||||||
|
|
|
@ -550,6 +550,8 @@ run_application_init (xamarin_initialize_data *data)
|
||||||
|
|
||||||
MonoImage *image = mono_assembly_get_image (assembly);
|
MonoImage *image = mono_assembly_get_image (assembly);
|
||||||
|
|
||||||
|
xamarin_mono_object_release (&assembly);
|
||||||
|
|
||||||
MonoClass *app_class = mono_class_from_name (image, "AppKit", "NSApplication");
|
MonoClass *app_class = mono_class_from_name (image, "AppKit", "NSApplication");
|
||||||
if (!app_class)
|
if (!app_class)
|
||||||
xamarin_assertion_message ("Fatal error: failed to load the NSApplication 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;
|
typedef int32_t mono_bool;
|
||||||
|
|
||||||
/* metadata/image.h */
|
/* 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;
|
typedef struct _MonoAssembly MonoAssembly;
|
||||||
|
#endif
|
||||||
typedef struct _MonoAssemblyName MonoAssemblyName;
|
typedef struct _MonoAssemblyName MonoAssemblyName;
|
||||||
typedef struct _MonoImage MonoImage;
|
typedef struct _MonoImage MonoImage;
|
||||||
|
|
||||||
|
|
|
@ -472,5 +472,7 @@ xamarin_main (int argc, char *argv[], enum XamarinLaunchMode launch_mode)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xamarin_mono_object_release (&assembly);
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,8 @@ void
|
||||||
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
|
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
|
||||||
{
|
{
|
||||||
xamarin_register_monoassembly (entry_assembly, 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 *
|
MonoClass *
|
||||||
|
|
|
@ -941,6 +941,7 @@ xamarin_file_exists (const char *path)
|
||||||
return stat (path, &buffer) == 0;
|
return stat (path, &buffer) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a retained MonoObject. Caller must release.
|
||||||
MonoAssembly *
|
MonoAssembly *
|
||||||
xamarin_open_assembly (const char *name)
|
xamarin_open_assembly (const char *name)
|
||||||
{
|
{
|
||||||
|
@ -996,6 +997,7 @@ xamarin_register_monoassembly (MonoAssembly *assembly, GCHandle *exception_gchan
|
||||||
return *exception_gchandle == INVALID_GCHANDLE;
|
return *exception_gchandle == INVALID_GCHANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a retained MonoObject. Caller must release.
|
||||||
MonoAssembly *
|
MonoAssembly *
|
||||||
xamarin_open_and_register (const char *aname, GCHandle *exception_gchandle)
|
xamarin_open_and_register (const char *aname, GCHandle *exception_gchandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace ObjCRuntime {
|
namespace ObjCRuntime {
|
||||||
|
@ -29,6 +30,35 @@ namespace ObjCRuntime {
|
||||||
xamarin_log (message);
|
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.
|
// Returns a retained MonoObject. Caller must release.
|
||||||
static IntPtr GetMonoObject (object obj)
|
static IntPtr GetMonoObject (object obj)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче