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 26645c6476f349..a75c897458d04c 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 @@ -283,8 +283,6 @@ public static unsafe JSFunctionBinding BindManagedFunction(string fullyQualified { var (assemblyName, nameSpace, shortClassName, methodName) = ParseFQN(fullyQualifiedName); - var dllName = assemblyName + ".dll"; - IntPtr monoMethod; Interop.Runtime.GetAssemblyExport( // FIXME: Pass UTF-16 through directly so C can work with it, doing the conversion @@ -292,7 +290,7 @@ public static unsafe JSFunctionBinding BindManagedFunction(string fullyQualified // I tested removing the UTF8 conversion from this specific call, but other parts // of startup I can't identify still pull in UTF16->UTF8 conversion, so it's not // worth it to do that yet. - Marshal.StringToCoTaskMemUTF8(dllName), + Marshal.StringToCoTaskMemUTF8(assemblyName), Marshal.StringToCoTaskMemUTF8(nameSpace), Marshal.StringToCoTaskMemUTF8(shortClassName), Marshal.StringToCoTaskMemUTF8(methodName), diff --git a/src/mono/browser/runtime/invoke-cs.ts b/src/mono/browser/runtime/invoke-cs.ts index 3b7a869e8661c3..89da4c4c04b0e2 100644 --- a/src/mono/browser/runtime/invoke-cs.ts +++ b/src/mono/browser/runtime/invoke-cs.ts @@ -123,7 +123,8 @@ function bind_fn_0V (closure: BindingClosure) { // call C# side invoke_sync_jsexport(method, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -147,7 +148,8 @@ function bind_fn_1V (closure: BindingClosure) { // call C# side invoke_sync_jsexport(method, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -175,7 +177,8 @@ function bind_fn_1R (closure: BindingClosure) { const js_result = res_converter(args); return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -208,7 +211,8 @@ function bind_fn_1RA (closure: BindingClosure) { return promise; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -238,7 +242,8 @@ function bind_fn_2R (closure: BindingClosure) { const js_result = res_converter(args); return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -273,7 +278,8 @@ function bind_fn_2RA (closure: BindingClosure) { return promise; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; @@ -325,7 +331,8 @@ function bind_fn (closure: BindingClosure) { } return js_result; } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + endMeasure(mark, MeasuredBlock.callCsFunction, fqn); } }; diff --git a/src/mono/browser/runtime/managed-exports.ts b/src/mono/browser/runtime/managed-exports.ts index 472c47708c4739..159b250d58f1e0 100644 --- a/src/mono/browser/runtime/managed-exports.ts +++ b/src/mono/browser/runtime/managed-exports.ts @@ -74,7 +74,8 @@ export function call_entry_point (main_assembly_name: string, program_args: stri return promise; } finally { - Module.stackRestore(sp); // synchronously + // synchronously + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); } } @@ -90,7 +91,8 @@ export function load_satellite_assembly (dll: Uint8Array): void { marshal_array_to_cs(arg1, dll, MarshalerType.Byte); invoke_sync_jsexport(managedExports.LoadSatelliteAssembly, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -109,7 +111,8 @@ export function load_lazy_assembly (dll: Uint8Array, pdb: Uint8Array | null): vo marshal_array_to_cs(arg2, pdb, MarshalerType.Byte); invoke_sync_jsexport(managedExports.LoadLazyAssembly, args); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -132,7 +135,8 @@ export function release_js_owned_object_by_gc_handle (gc_handle: GCHandle) { invoke_async_jsexport(runtimeHelpers.ioThreadTID, managedExports.ReleaseJSOwnedObjectByGCHandle, args, size); } } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -157,7 +161,8 @@ export function complete_task (holder_gc_handle: GCHandle, error?: any, data?: a } invoke_async_jsexport(runtimeHelpers.ioThreadTID, managedExports.CompleteTask, args, size); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -203,7 +208,8 @@ export function call_delegate (callback_gc_handle: GCHandle, arg1_js: any, arg2_ return res_converter(res); } } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -223,7 +229,8 @@ export function get_managed_stack_trace (exception_gc_handle: GCHandle) { const res = get_arg(args, 1); return marshal_string_to_js(res); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } @@ -341,7 +348,8 @@ export function bind_assembly_exports (assemblyName: string): Promise { } return promise; } finally { - Module.stackRestore(sp); // synchronously + // synchronously + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); } } diff --git a/src/mono/browser/runtime/memory.ts b/src/mono/browser/runtime/memory.ts index 0f9f751854de17..3497f05b8b99bc 100644 --- a/src/mono/browser/runtime/memory.ts +++ b/src/mono/browser/runtime/memory.ts @@ -6,7 +6,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads"; import { MemOffset, NumberOrPointer } from "./types/internal"; import { VoidPtr, CharPtr } from "./types/emscripten"; import cwraps, { I52Error } from "./cwraps"; -import { Module, mono_assert, runtimeHelpers } from "./globals"; +import { loaderHelpers, Module, mono_assert, runtimeHelpers } from "./globals"; import { utf8ToString } from "./strings"; import { mono_log_warn, mono_log_error } from "./logging"; @@ -327,7 +327,8 @@ export function withStackAlloc (bytesWanted: number, f: (pt try { return f(ptr, ud1, ud2, ud3); } finally { - Module.stackRestore(sp); + if (loaderHelpers.is_runtime_running()) Module.stackRestore(sp); + } } diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs index c8d85406412f8e..f7f50858f7c3c3 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/LazyLoadingTest.cs @@ -5,10 +5,12 @@ using System; using System.Text.Json; using System.Runtime.InteropServices.JavaScript; +using System.Diagnostics.CodeAnalysis; public partial class LazyLoadingTest { [JSExport] + [DynamicDependency(DynamicallyAccessedMemberTypes.All, "LazyLibrary.Foo", "LazyLibrary")] public static void Run() { // System.Text.Json is marked as lazy loaded in the csproj ("BlazorWebAssemblyLazyLoad"), this method can be called only after the assembly is lazy loaded diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj index bd3c5a2643952f..e0896482e58925 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj @@ -20,11 +20,13 @@ + + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 050206bdd42bd9..90595ef290f8e3 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -209,9 +209,16 @@ try { } await INTERNAL.loadLazyAssembly(`Json${lazyAssemblyExtension}`); + exports.LazyLoadingTest.Run(); + await INTERNAL.loadLazyAssembly(`LazyLibrary${lazyAssemblyExtension}`); + const { LazyLibrary } = await getAssemblyExports("LazyLibrary"); + const resLazy = LazyLibrary.Foo.Bar(); + exit(resLazy == 42 ? 0 : 1); + } + else { + exports.LazyLoadingTest.Run(); + exit(0); } - exports.LazyLoadingTest.Run(); - exit(0); break; case "LibraryInitializerTest": exit(0); diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs new file mode 100644 index 00000000000000..a10afc9fd393c1 --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices.JavaScript; + +[assembly:System.Runtime.Versioning.SupportedOSPlatform("browser")] + +namespace LazyLibrary; + +public partial class Foo +{ + [JSExport] + public static int Bar() + { + Console.WriteLine("Hello from Foo.Bar!"); + return 42; + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj new file mode 100644 index 00000000000000..7861a9e9795585 --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/LazyLibrary/LazyLibrary.csproj @@ -0,0 +1,8 @@ + + + net10.0 + browser-wasm + Library + true + + diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs index 0e888b4bb7eec5..bc78ae7638e9fe 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/GenerateWasmBootJson.cs @@ -388,7 +388,7 @@ private void WriteBootConfig(string entryAssemblyName) endLineNumber: 0, endColumnNumber: 0, message: message, - string.Join(";", LazyLoadedAssemblies.Select(a => a.ItemSpec))); + string.Join(";", remainingLazyLoadAssemblies.Select(a => a.ItemSpec))); return; }