diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
index 000dd103d2189..23067f81ea601 100644
--- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
+++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs
@@ -64,7 +64,11 @@ internal static unsafe partial class Runtime
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void CancelPromise(nint gcHandle);
#endif
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern void SetEntryAssembly(Assembly assembly, int entryPointMetadataToken);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern void AssemblyGetEntryPoint(IntPtr assemblyNamePtr, int auto_insert_breakpoint, void** monoMethodPtrPtr);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern void BindAssemblyExports(IntPtr assemblyNamePtr);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern void GetAssemblyExport(IntPtr assemblyNamePtr, IntPtr namespacePtr, IntPtr classnamePtr, IntPtr methodNamePtr, IntPtr* monoMethodPtrPtr);
}
}
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx
index e77e419997996..9cb71cc66223a 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx
@@ -138,8 +138,8 @@
Managed entrypoint handle is not set.
-
- Cannot resolve managed entrypoint {0} in assembly {1}.
+
+ Cannot resolve managed entrypoint handle.
Return type '{0}' from main method in not supported.
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 9ec4a2400cd21..b244d69abdfb5 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -15,7 +15,7 @@ namespace System.Runtime.InteropServices.JavaScript
internal static unsafe partial class JavaScriptExports
{
// the marshaled signature is:
- // Task? CallEntrypoint(string mainAssemblyName, string[] args, bool waitForDebugger)
+ // Task? CallEntrypoint(char* assemblyNamePtr, string[] args)
public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
{
ref JSMarshalerArgument arg_exc = ref arguments_buffer[0]; // initialized by caller in alloc_stack_frame()
@@ -30,11 +30,11 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
arg_exc.AssertCurrentThreadContext();
#endif
- arg_1.ToManaged(out string? mainAssemblyName);
+ arg_1.ToManaged(out IntPtr assemblyNamePtr);
arg_2.ToManaged(out string?[]? args);
arg_3.ToManaged(out bool waitForDebugger);
- Task? result = JSHostImplementation.CallEntrypoint(mainAssemblyName, args, waitForDebugger);
+ Task? result = JSHostImplementation.CallEntrypoint(assemblyNamePtr, args, waitForDebugger);
arg_result.ToJS(result, (ref JSMarshalerArgument arg, int value) =>
{
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
index 7268951b68828..27a6d54886892 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
@@ -200,47 +200,19 @@ public static void LoadSatelliteAssembly(byte[] dllBytes)
AssemblyLoadContext.Default.LoadFromStream(new MemoryStream(dllBytes));
}
- [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "Dynamic access from JavaScript")]
- [UnconditionalSuppressMessage("Trimming", "IL2075", Justification = "Dynamic access from JavaScript")]
- public static Task? CallEntrypoint(string? assemblyName, string?[]? args, bool waitForDebugger)
+ public static unsafe Task? CallEntrypoint(IntPtr assemblyNamePtr, string?[]? args, bool waitForDebugger)
{
try
{
- if (string.IsNullOrEmpty(assemblyName))
- {
- throw new MissingMethodException(SR.MissingManagedEntrypointHandle);
- }
- if (!assemblyName.EndsWith(".dll", StringComparison.InvariantCultureIgnoreCase))
- {
- assemblyName += ".dll";
- }
- Assembly mainAssembly = Assembly.LoadFrom(assemblyName);
-
- MethodInfo? method = mainAssembly.EntryPoint;
+ void* ptr;
+ Interop.Runtime.AssemblyGetEntryPoint(assemblyNamePtr, waitForDebugger ? 1 : 0, &ptr);
+ RuntimeMethodHandle methodHandle = GetMethodHandleFromIntPtr((IntPtr)ptr);
+ // this would not work for generic types. But Main() could not be generic, so we are fine.
+ MethodInfo? method = MethodBase.GetMethodFromHandle(methodHandle) as MethodInfo;
if (method == null)
{
- throw new InvalidOperationException(string.Format(SR.CannotResolveManagedEntrypoint, "Main", assemblyName));
+ throw new InvalidOperationException(SR.CannotResolveManagedEntrypointHandle);
}
- if (method.IsSpecialName)
- {
- // we are looking for the original async method, rather than for the compiler generated wrapper like
- // because we need to yield to browser event loop
- var type = method.DeclaringType!;
- var name = method.Name;
- var asyncName = name + "$";
- method = type.GetMethod(asyncName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
- if (method == null)
- {
- asyncName = name.Substring(1, name.Length - 2);
- method = type.GetMethod(asyncName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
- }
- if (method == null)
- {
- throw new InvalidOperationException(string.Format(SR.CannotResolveManagedEntrypoint, asyncName, assemblyName));
- }
- }
-
- Interop.Runtime.SetEntryAssembly(mainAssembly, waitForDebugger ? method.MetadataToken : 0);
object[] argsToPass = System.Array.Empty