[netcore] Implement AssemblyLoadContext.InternalLoad (mono/mono#15753)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 23 Jul 2019 23:09:27 +0000 (19:09 -0400)
committerGitHub <noreply@github.com>
Tue, 23 Jul 2019 23:09:27 +0000 (19:09 -0400)
Fixes https://github.com/mono/mono/issues/14830

Commit migrated from https://github.com/mono/mono/commit/7467ce4369adecef24a9c65854e7e39228ac9637

src/mono/mono/metadata/appdomain.c
src/mono/mono/metadata/icall-def-netcore.h
src/mono/netcore/CoreFX.issues.rsp
src/mono/netcore/System.Private.CoreLib/src/System.Runtime.Loader/AssemblyLoadContext.cs

index 9f51044..106beb2 100644 (file)
@@ -2530,6 +2530,25 @@ leave:
 }
 #endif
 
+static MonoAssembly*
+mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *raw_assembly, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, gboolean refonly, MonoError *error);
+
+#ifdef ENABLE_NETCORE
+MonoReflectionAssemblyHandle
+ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream (gpointer native_alc, gpointer raw_assembly_ptr, gint32 raw_assembly_len, gpointer raw_symbols_ptr, gint32 raw_symbols_len, MonoError *error)
+{
+       MonoDomain *domain = mono_domain_get ();
+       MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
+       MonoAssembly *assm = NULL;
+       assm = mono_alc_load_raw_bytes ((MonoAssemblyLoadContext *)native_alc, (guint8 *)raw_assembly_ptr, raw_assembly_len, (guint8 *)raw_symbols_ptr, raw_symbols_len, FALSE, error);
+       goto_if_nok (error, leave);
+
+       result = mono_assembly_get_object_handle (domain, assm, error);
+
+leave:
+       return result;
+}
+#else
 MonoReflectionAssemblyHandle
 ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad, 
                                            MonoArrayHandle raw_assembly,
@@ -2540,11 +2559,10 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad,
        MonoAssembly *ass;
        MonoReflectionAssemblyHandle refass = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
        MonoDomain *domain = MONO_HANDLE_GETVAL(ad, data);
-       MonoImageOpenStatus status;
        guint32 raw_assembly_len = mono_array_handle_length (raw_assembly);
 
        /* Copy the data ourselves to unpin the raw assembly byte array as soon as possible */
-       char *assembly_data = (char*) g_try_malloc (raw_assembly_len);
+       guint8 *assembly_data = (guint8*) g_try_malloc (raw_assembly_len);
        if (!assembly_data) {
                mono_error_set_out_of_memory (error, "Could not allocate %ud bytes to copy raw assembly data", raw_assembly_len);
                return refass;
@@ -2556,21 +2574,43 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad,
        MONO_HANDLE_ASSIGN (raw_assembly, NULL_HANDLE); /* don't reference the data anymore */
        
        MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain);
-       MonoImage *image = mono_image_open_from_data_internal (alc, assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL);
 
-       if (!image) {
-               mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", raw_data);
-               return refass;
+       mono_byte *raw_symbol_data = NULL;
+       guint32 symbol_len = 0;
+       uint32_t symbol_gchandle = 0;
+       if (!MONO_HANDLE_IS_NULL (raw_symbol_store)) {
+               symbol_len = mono_array_handle_length (raw_symbol_store);
+               raw_symbol_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_symbol_store, mono_byte, 0, &symbol_gchandle);
        }
 
-       if (!MONO_HANDLE_IS_NULL(raw_symbol_store)) {
-               guint32 symbol_len = mono_array_handle_length (raw_symbol_store);
-               uint32_t symbol_gchandle;
-               mono_byte *raw_symbol_data = (mono_byte*) MONO_ARRAY_HANDLE_PIN (raw_symbol_store, mono_byte, 0, &symbol_gchandle);
-               mono_debug_open_image_from_memory (image, raw_symbol_data, symbol_len);
-               mono_gchandle_free_internal (symbol_gchandle);
+       ass = mono_alc_load_raw_bytes (alc, assembly_data, raw_assembly_len, raw_symbol_data, symbol_len, refonly, error);
+       mono_gchandle_free_internal (symbol_gchandle);
+       goto_if_nok (error, leave);
+
+       refass = mono_assembly_get_object_handle (domain, ass, error);
+       if (!MONO_HANDLE_IS_NULL (refass))
+               MONO_HANDLE_SET (refass, evidence, evidence);
+
+leave:
+       return refass;
+}
+#endif /* ENABLE_NETCORE */
+
+static MonoAssembly*
+mono_alc_load_raw_bytes (MonoAssemblyLoadContext *alc, guint8 *assembly_data, guint32 raw_assembly_len, guint8 *raw_symbol_data, guint32 raw_symbol_len, gboolean refonly, MonoError *error)
+{
+       MonoAssembly *ass = NULL;
+       MonoImageOpenStatus status;
+       MonoImage *image = mono_image_open_from_data_internal (alc, (char*)assembly_data, raw_assembly_len, FALSE, NULL, refonly, FALSE, NULL);
+
+       if (!image) {
+               mono_error_set_bad_image_by_name (error, "In memory assembly", "0x%p", assembly_data);
+               return ass;
        }
 
+       if (raw_symbol_data)
+               mono_debug_open_image_from_memory (image, raw_symbol_data, raw_symbol_len);
+
        MonoAssembly* redirected_asm = NULL;
        MonoImageOpenStatus new_status = MONO_IMAGE_OK;
        if ((redirected_asm = mono_assembly_binding_applies_to_image (image, &new_status))) {
@@ -2580,26 +2620,24 @@ ves_icall_System_AppDomain_LoadAssemblyRaw (MonoAppDomainHandle ad,
        } else if (new_status != MONO_IMAGE_OK) {
                mono_image_close (image);
                mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p was assembly binding redirected to another assembly that failed to load", assembly_data);
-               return refass;
+               return ass;
        }
 
        MonoAssemblyLoadRequest req;
        mono_assembly_request_prepare (&req, sizeof (req), refonly? MONO_ASMCTX_REFONLY : MONO_ASMCTX_INDIVIDUAL);
+       req.alc = alc;
        ass = mono_assembly_request_load_from (image, "", &req, &status);
 
        if (!ass) {
                mono_image_close (image);
                mono_error_set_bad_image_by_name (error, "In Memory assembly", "0x%p", assembly_data);
-               return refass; 
+               return ass;
        }
 
        /* Clear the reference added by mono_image_open_from_data_internal above */
        mono_image_close (image);
 
-       refass = mono_assembly_get_object_handle (domain, ass, error);
-       if (!MONO_HANDLE_IS_NULL(refass))
-               MONO_HANDLE_SET (refass, evidence, evidence);
-       return refass;
+       return ass;
 }
 
 MonoReflectionAssemblyHandle
index e9001e7..9d1a876 100644 (file)
@@ -373,6 +373,7 @@ HANDLES(MARSHAL_42, "copy_to_unmanaged_fixed", ves_icall_System_Runtime_InteropS
 ICALL_TYPE(ALC, "System.Runtime.Loader.AssemblyLoadContext", ALC_2)
 HANDLES(ALC_2, "InternalInitializeNativeALC", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalInitializeNativeALC, gpointer, 3, (gpointer, MonoBoolean, MonoBoolean))
 HANDLES(ALC_1, "InternalLoadFile", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFile, MonoReflectionAssembly, 3, (gpointer, MonoString, MonoStackCrawlMark_ptr))
+HANDLES(ALC_3, "InternalLoadFromStream", ves_icall_System_Runtime_Loader_AssemblyLoadContext_InternalLoadFromStream, MonoReflectionAssembly, 5, (gpointer, gpointer, gint32, gpointer, gint32))
 
 ICALL_TYPE(RUNIMPORT, "System.Runtime.RuntimeImports", RUNIMPORT_1)
 NOHANDLES(ICALL(RUNIMPORT_1, "RhBulkMoveWithWriteBarrier", ves_icall_System_Runtime_RuntimeImports_RhBulkMoveWithWriteBarrier))
index 8988884..4259011 100644 (file)
 # https://github.com/mono/mono/issues/15037
 -nomethod System.Reflection.Tests.ParameterInfoTests.RawDefaultValueFromAttribute
 
-# AssemblyLoadContext.InternalLoad not implemented
-# https://github.com/mono/mono/issues/14830
--nomethod System.Reflection.Tests.AssemblyTests.AssemblyLoadFromBytes
--nomethod System.Reflection.Tests.AssemblyTests.AssemblyLoadFromBytesWithSymbols
-
 # Need to set ProcessorArchitecture in AssemblyName
 # https://github.com/mono/mono/issues/15068
 -nomethod System.Reflection.Tests.AssemblyNameTests.Ctor_ValidArchitectureName_Succeeds
index 6e68962..9058559 100644 (file)
@@ -43,7 +43,14 @@ namespace System.Runtime.Loader
 
                internal Assembly InternalLoad (byte[] arrAssembly, byte[] arrSymbols)
                {
-                       throw new NotImplementedException ();
+                       unsafe {
+                               int symbolsLength = arrSymbols?.Length ?? 0;
+                               fixed (byte* ptrAssembly = arrAssembly, ptrSymbols = arrSymbols)
+                               {
+                                       return InternalLoadFromStream (NativeALC, new IntPtr (ptrAssembly), arrAssembly.Length,
+                                                                      new IntPtr (ptrSymbols), symbolsLength);
+                               }
+                       }
                }
 
                public static Assembly[] GetLoadedAssemblies ()
@@ -70,6 +77,9 @@ namespace System.Runtime.Loader
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static IntPtr InternalInitializeNativeALC (IntPtr thisHandlePtr, bool representsTPALoadContext, bool isCollectible);
 
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               extern static Assembly InternalLoadFromStream (IntPtr nativeAssemblyLoadContext, IntPtr assm, int assmLength, IntPtr symbols, int symbolsLength);
+
                internal static Assembly DoAssemblyResolve (string name)
                {
                        return AssemblyResolve (null, new ResolveEventArgs (name));