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] Implement coreclr_create_delegate and move ComponentActivator to shared CoreLib #59962

Merged
merged 4 commits into from
Oct 6, 2021
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -111,9 +111,7 @@
<!-- Sources -->
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\Internal\Runtime\InteropServices\ComActivationContextInternal.cs" />
<Compile Include="$(BclSourcesRoot)\Internal\Runtime\InteropServices\ComponentActivator.cs" />
<Compile Include="$(BclSourcesRoot)\Internal\Runtime\InteropServices\InMemoryAssemblyLoader.cs" />
<Compile Include="$(BclSourcesRoot)\Internal\Runtime\InteropServices\IsolatedComponentLoadContext.cs" />
<Compile Include="$(BclSourcesRoot)\System\__Canon.cs" />
<Compile Include="$(BclSourcesRoot)\System\ArgIterator.cs" />
<Compile Include="$(BclSourcesRoot)\System\Array.CoreCLR.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,6 @@
<method name=".ctor" />
</type>

<!-- Native hosting accesses managed methods in the ComponentActivator class.
These are always rooted to ensure native calls get trimmer related errors
but will be trimmed away by the related feature switch -->
<type fullname="Internal.Runtime.InteropServices.ComponentActivator">
<method name="LoadAssemblyAndGetFunctionPointer" />
<method name="GetFunctionPointer" />
</type>

<!-- Enables the .NET IJW host to load an in-memory module as a .NET assembly.
These are always rooted to ensure native calls get trimmer related errors
but will be trimmed away by the related feature switch -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,5 @@
<type fullname="System.StartupHookProvider" feature="System.StartupHookProvider.IsSupported" featurevalue="false">
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
</type>
<type fullname="Internal.Runtime.InteropServices.ComponentActivator" feature="System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting" featurevalue="false">
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@
<property name="Target">M:System.StartupHookProvider.ProcessStartupHooks()</property>
<property name="Justification">This warning is left in the product so developers get an ILLink warning when trimming an app with System.StartupHookProvider.IsSupported=true.</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2026</argument>
<property name="Scope">member</property>
<property name="Target">M:Internal.Runtime.InteropServices.ComponentActivator.GetFunctionPointer(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)</property>
<property name="Justification">This warning is left in the product so developers get an ILLink warning when trimming an app with Internal.Runtime.InteropServices.ComponentActivator.IsSupported=true.</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2026</argument>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
https://github.com/mono/linker/pull/649 -->
<method name=".ctor" />
</type>

<!-- Native hosting accesses managed methods in the ComponentActivator class.
These are always rooted to ensure native calls get trimmer related errors
but will be trimmed away by the related feature switch -->
<type fullname="Internal.Runtime.InteropServices.ComponentActivator">
<method name="LoadAssemblyAndGetFunctionPointer" />
<method name="GetFunctionPointer" />
</type>
</assembly>

<!-- Properties and methods used by a debugger. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,8 @@
<type fullname="System.Reflection.NullabilityInfoContext" feature="System.Reflection.NullabilityInfoContext.IsSupported" featurevalue="false">
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
</type>
<type fullname="Internal.Runtime.InteropServices.ComponentActivator" feature="System.Runtime.InteropServices.EnableConsumingManagedCodeFromNativeHosting" featurevalue="false">
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
</type>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,12 @@
<property name="Target">M:System.Resources.ManifestBasedResourceGroveler.CreateResourceSet(System.IO.Stream,System.Reflection.Assembly)</property>
<property name="Justification">This warning is left in the product so developers get an ILLink warning when trimming an app with System.Resources.ResourceManager.AllowCustomResourceTypes=true.</property>
</attribute>
<attribute fullname="System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute">
<argument>ILLink</argument>
<argument>IL2026</argument>
<property name="Scope">member</property>
<property name="Target">M:Internal.Runtime.InteropServices.ComponentActivator.GetFunctionPointer(System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr,System.IntPtr)</property>
<property name="Justification">This warning is left in the product so developers get an ILLink warning when trimming an app with Internal.Runtime.InteropServices.ComponentActivator.IsSupported=true.</property>
</attribute>
</assembly>
</linker>
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;
using System.Runtime.Versioning;

namespace Internal.Runtime.InteropServices
{
public static class ComponentActivator
{
private const string TrimIncompatibleWarningMessage = "Native hosting is not trim compatible and this warning will be seen if trimming is enabled.";

[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("maccatalyst")]
[UnsupportedOSPlatform("tvos")]
private static readonly Dictionary<string, IsolatedComponentLoadContext> s_assemblyLoadContexts = new Dictionary<string, IsolatedComponentLoadContext>(StringComparer.InvariantCulture);
private static readonly Dictionary<IntPtr, Delegate> s_delegates = new Dictionary<IntPtr, Delegate>();

Expand Down Expand Up @@ -47,6 +53,11 @@ private static string MarshalToString(IntPtr arg, string argName)
/// <param name="reserved">Extensibility parameter (currently unused)</param>
/// <param name="functionHandle">Pointer where to store the function pointer result</param>
[RequiresUnreferencedCode(TrimIncompatibleWarningMessage, Url = "https://aka.ms/dotnet-illink/nativehost")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("maccatalyst")]
[UnsupportedOSPlatform("tvos")]
[UnmanagedCallersOnly]
public static unsafe int LoadAssemblyAndGetFunctionPointer(IntPtr assemblyPathNative,
IntPtr typeNameNative,
Expand Down Expand Up @@ -142,6 +153,10 @@ public static unsafe int GetFunctionPointer(IntPtr typeNameNative,
}

[RequiresUnreferencedCode(TrimIncompatibleWarningMessage, Url = "https://aka.ms/dotnet-illink/nativehost")]
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("tvos")]
private static IsolatedComponentLoadContext GetIsolatedComponentLoadContext(string assemblyPath)
{
IsolatedComponentLoadContext? alc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.Loader;
using System.Runtime.Versioning;

namespace Internal.Runtime.InteropServices
{
Expand All @@ -13,6 +14,11 @@ namespace Internal.Runtime.InteropServices
/// or IJW components loaded from native. It provides a load context that uses an <see cref="AssemblyDependencyResolver" /> to resolve the component's
/// dependencies within the ALC and not pollute the default ALC.
///</summary>
[UnsupportedOSPlatform("android")]
[UnsupportedOSPlatform("browser")]
[UnsupportedOSPlatform("ios")]
[UnsupportedOSPlatform("maccatalyst")]
[UnsupportedOSPlatform("tvos")]
internal sealed class IsolatedComponentLoadContext : AssemblyLoadContext
{
private readonly AssemblyDependencyResolver _resolver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Internal\Console.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Internal\Padding.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Internal\Runtime\CompilerServices\Unsafe.cs" />
<Compile Include="$(MSBuildThisFileDirectory)\Internal\Runtime\InteropServices\ComponentActivator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)\Internal\Runtime\InteropServices\IsolatedComponentLoadContext.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleMinusOneIsInvalid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleZeroOrMinusOneIsInvalid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeHandleMinusOneIsInvalid.cs" />
Expand Down
3 changes: 1 addition & 2 deletions src/mono/mono/mini/main-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,5 @@ int STDAPICALLTYPE coreclr_create_delegate (void* hostHandle, unsigned int domai
const char* entryPointAssemblyName, const char* entryPointTypeName, const char* entryPointMethodName,
void** delegate)
{
g_error ("Not implemented");
return 0;
return monovm_create_delegate (entryPointAssemblyName, entryPointTypeName, entryPointMethodName, delegate);
}
87 changes: 87 additions & 0 deletions src/mono/mono/mini/monovm.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <mono/metadata/environment.h>
#include <mono/metadata/loader-internals.h>
#include <mono/metadata/native-library.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/mini/mini-runtime.h>
#include <mono/mini/mini.h>
#include <mono/utils/mono-logger-internals.h>
Expand Down Expand Up @@ -276,3 +277,89 @@ monovm_shutdown (int *latchedExitCode)

return 0;
}

static int
monovm_create_delegate_impl (const char* assemblyName, const char* typeName, const char *methodName, void **delegate);


int
monovm_create_delegate (const char *assemblyName, const char *typeName, const char *methodName, void **delegate)
{
int result;
/* monovm_create_delegate may be called instead of monovm_execute_assembly. Initialize the
* runtime if it isn't already. */
if (!mono_get_root_domain())
mini_init (assemblyName, "v4.0.30319");
MONO_ENTER_GC_UNSAFE;
result = monovm_create_delegate_impl (assemblyName, typeName, methodName, delegate);
MONO_EXIT_GC_UNSAFE;
return result;
}

int
monovm_create_delegate_impl (const char* assemblyName, const char* typeName, const char *methodName, void **delegate)
{
// Load an assembly and a type and a method from the type, then return a pointer to a native
// callable version of the method. See CorHost2::CreateDelegate
//
// We have to do this in general, but the CoreCLR hostpolicy only calls this with a handful
// of methods from the [CoreLib]Internal.Runtime.InteropServices.ComponentActivator
// class. See hostpolicy.cpp get_delegate()

ERROR_DECL (error);

const int failure = 0x80004005; /* E_FAIL */

if (!delegate)
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
return failure;
*delegate = NULL;

MonoAssemblyLoadContext *alc = mono_alc_get_default ();

MonoImage *image;
if (!strcmp (MONO_ASSEMBLY_CORLIB_NAME, assemblyName)) {
image = mono_defaults.corlib;
} else {
MonoAssemblyName aname = {0};
aname.name = assemblyName;
MonoAssemblyByNameRequest req;
mono_assembly_request_prepare_byname (&req, alc);
MonoImageOpenStatus status = MONO_IMAGE_OK;
MonoAssembly *assm = mono_assembly_request_byname (&aname, &req, &status);

if (!assm || status != MONO_IMAGE_OK)
return failure;
image = assm->image;
}

MonoType *t = mono_reflection_type_from_name_checked ((char*)typeName, alc, image, error);
goto_if_nok (error, fail);

g_assert (t);
MonoClass *klass = mono_class_from_mono_type_internal (t);


MonoMethod *method = mono_class_get_method_from_name_checked (klass, methodName, -1, 0, error);
goto_if_nok (error, fail);

if (!mono_method_has_unmanaged_callers_only_attribute (method)) {
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
mono_error_set_not_supported (error, "MonoVM only supports UnmanagedCallersOnly implementations of hostfxr_get_runtime_delegate delegate types");
goto fail;
}

MonoClass *delegate_klass = NULL;
MonoGCHandle target_handle = 0;
MonoMethod *wrapper = mono_marshal_get_managed_wrapper (method, delegate_klass, target_handle, error);
goto_if_nok (error, fail);

gpointer addr = mono_compile_method_checked (wrapper, error);
goto_if_nok (error, fail);

*delegate = addr;
Comment on lines +355 to +358
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vargaz I'm not sure if need to call mono_get_addr_from_ftnptr here or not.

return 0;

fail:
g_warning ("coreclr_create_delegate: failed due to %s", mono_error_get_message (error));
mono_error_cleanup (error);
return failure;
}
5 changes: 5 additions & 0 deletions src/mono/mono/mini/monovm.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ monovm_execute_assembly (int argc, const char **argv, const char *managedAssembl
MONO_API int
monovm_shutdown (int *latchedExitCode);

int
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved Hide resolved
monovm_create_delegate (const char *assemblyName, const char *typeName, const char *methodName, void **delegate);



#endif // _MONO_MINI_MONOVM_H_