diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets index 203183c4dfdc3e..77c702193ad49c 100644 --- a/eng/testing/tests.browser.targets +++ b/eng/testing/tests.browser.targets @@ -30,6 +30,7 @@ _GetRuntimePackNuGetsToBuild;_GetNugetsForAOT;$(GetNuGetsToBuildForWorkloadTestingDependsOn) <_BundleAOTTestWasmAppForHelixDependsOn>$(_BundleAOTTestWasmAppForHelixDependsOn);PrepareForWasmBuildApp;_PrepareForAOTOnHelix + true @@ -126,6 +127,11 @@ + + + true diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index 848f426f9667c2..34cbaab41709a4 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -252,6 +252,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index 606ce13a347b5e..4e4ac9c91394e8 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -2,8 +2,6 @@ $(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent) true - true - $(DefineConstants);FEATURE_WASM_THREADS false @@ -11,6 +9,13 @@ $([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) SR.SystemRuntimeInteropServicesJavaScript_PlatformNotSupported + true + true + $(DefineConstants);FEATURE_WASM_THREADS + $(DefineConstants);ENABLE_LEGACY_JS_INTEROP + $(MonoProjectRoot)wasm\build\ILLink.Descriptors.LegacyJsInterop.xml @@ -22,15 +27,6 @@ - - - - - - - - - @@ -69,6 +65,18 @@ + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs index 36ea076bd4c5e1..fd7a9f6c6bde85 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs @@ -20,6 +20,7 @@ public static void MarshalPromise(Span arguments) } } +#if ENABLE_LEGACY_JS_INTEROP #region legacy public static object GetGlobalObject(string? str = null) @@ -30,7 +31,7 @@ public static object GetGlobalObject(string? str = null) if (exception != 0) throw new JSException(SR.Format(SR.ErrorResolvingFromGlobalThis, str)); - JSHostImplementation.ReleaseInFlight(jsObj); + LegacyHostImplementation.ReleaseInFlight(jsObj); return jsObj; } @@ -44,5 +45,6 @@ public static IntPtr CreateCSOwnedObject(string typeName, object[] parms) } #endregion +#endif } } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs index a73cca5fd482e2..431f83e9fff874 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs @@ -9,8 +9,7 @@ namespace System.Runtime.InteropServices.JavaScript { - // this maps to src\mono\wasm\runtime\legacy\corebindings.ts - // the public methods are protected from trimming by DynamicDependency on JSFunctionBinding.BindJSFunction + // the public methods are protected from trimming by ILLink.Descriptors.LegacyJsInterop.xml internal static unsafe partial class LegacyExports { public static void GetCSOwnedObjectByJSHandleRef(nint jsHandle, int shouldAddInflight, out JSObject? result) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs index a4a07ab5139bac..6b2518472d9c48 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs @@ -142,8 +142,6 @@ public static void InvokeJS(JSFunctionBinding signature, SpanThe method is executed on an architecture other than WebAssembly. // JavaScriptExports need to be protected from trimming because they are used from C/JS code which IL linker can't see [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "System.Runtime.InteropServices.JavaScript.JavaScriptExports", "System.Runtime.InteropServices.JavaScript")] - // TODO make this DynamicDependency conditional - [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "System.Runtime.InteropServices.JavaScript.LegacyExports", "System.Runtime.InteropServices.JavaScript")] public static JSFunctionBinding BindJSFunction(string functionName, string moduleName, ReadOnlySpan signatures) { if (RuntimeInformation.OSArchitecture != Architecture.Wasm) 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 c573311897eab3..cdb3c3ad3f4698 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 @@ -42,13 +42,6 @@ public static void ReleaseCSOwnedObject(nint jsHandle) throw new InvalidOperationException(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ReleaseInFlight(object obj) - { - JSObject? jsObj = obj as JSObject; - jsObj?.ReleaseInFlight(); - } - // A JSOwnedObject is a managed object with its lifetime controlled by javascript. // The managed side maintains a strong reference to the object, while the JS side // maintains a weak reference and notifies the managed side if the JS wrapper object diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs index 17622520a01a1d..0544ab4e2e8805 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs @@ -10,17 +10,18 @@ public partial class JSObject { internal nint JSHandle; +#if ENABLE_LEGACY_JS_INTEROP internal GCHandle? InFlight; internal int InFlightCounter; +#endif private bool _isDisposed; internal JSObject(IntPtr jsHandle) { JSHandle = jsHandle; - InFlight = null; - InFlightCounter = 0; } +#if ENABLE_LEGACY_JS_INTEROP internal void AddInFlight() { ObjectDisposedException.ThrowIf(IsDisposed, this); @@ -53,6 +54,7 @@ internal void ReleaseInFlight() } } } +#endif /// public override bool Equals([NotNullWhen(true)] object? obj) => obj is JSObject other && JSHandle == other.JSHandle; diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs index 00fa785a898468..987a2d2fd8bf0c 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs @@ -91,7 +91,7 @@ public object this[int i] if (exception != 0) throw new JSException((string)indexValue); - JSHostImplementation.ReleaseInFlight(indexValue); + LegacyHostImplementation.ReleaseInFlight(indexValue); return indexValue; } set diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs index 840d25acf5edce..d24a1decdff638 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs @@ -10,6 +10,13 @@ namespace System.Runtime.InteropServices.JavaScript [SupportedOSPlatform("browser")] internal static class LegacyHostImplementation { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ReleaseInFlight(object obj) + { + JSObject? jsObj = obj as JSObject; + jsObj?.ReleaseInFlight(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RegisterCSOwnedObject(JSObject proxy) { diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs index aba7806ff60f8e..13147c81020525 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs @@ -39,7 +39,7 @@ public static object Invoke(this JSObject self, string method, params object?[] Interop.Runtime.InvokeJSWithArgsRef(self.JSHandle, method, args, out int exception, out object res); if (exception != 0) throw new JSException((string)res); - JSHostImplementation.ReleaseInFlight(res); + LegacyHostImplementation.ReleaseInFlight(res); return res; } @@ -74,7 +74,7 @@ public static object GetObjectProperty(this JSObject self, string name) Interop.Runtime.GetObjectPropertyRef(self.JSHandle, name, out int exception, out object propertyValue); if (exception != 0) throw new JSException((string)propertyValue); - JSHostImplementation.ReleaseInFlight(propertyValue); + LegacyHostImplementation.ReleaseInFlight(propertyValue); return propertyValue; } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj index b310c819c66749..eae66e4e4a9c9a 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj @@ -5,8 +5,11 @@ true $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop 0612 + true + $(DefineConstants);ENABLE_LEGACY_JS_INTEROP - + + @@ -16,9 +19,12 @@ + + + + - diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj index 2db86ee5eb768e..f34edc44b25721 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj @@ -4,6 +4,8 @@ $(NetCoreAppCurrent)-browser true $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop + true + $(DefineConstants);ENABLE_LEGACY_JS_INTEROP true diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs index 49063ad5e76e67..30e97fe180a192 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs @@ -58,8 +58,10 @@ public unsafe void GlobalThis() [Fact] public unsafe void DotnetInstance() { +#if ENABLE_LEGACY_JS_INTEROP Assert.True(JSHost.DotnetInstance.HasProperty("MONO")); Assert.Equal("object", JSHost.DotnetInstance.GetTypeOfProperty("MONO")); +#endif JSHost.DotnetInstance.SetProperty("testBool", true); Assert.Equal("boolean", JSHost.DotnetInstance.GetTypeOfProperty("testBool")); diff --git a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj index f99071471c0ee9..55c5c211b895e7 100644 --- a/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj +++ b/src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj @@ -13,6 +13,7 @@ + diff --git a/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml b/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml new file mode 100644 index 00000000000000..eaa9ab362f1311 --- /dev/null +++ b/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index f0f20741ae15c6..a89540b1627a48 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -258,7 +258,6 @@ - diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 8eaecaf217364b..6cf8f68324760c 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -135,6 +135,10 @@ + + diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 3669e0349d2d86..6c511fe49347f2 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -4,9 +4,17 @@ "use strict"; -const monoWasmThreads = process.env.MonoWasmThreads == "true"; -const WasmEnableLegacyJsInterop = process.env.WasmEnableLegacyJsInterop === "true"; -const isPThread = monoWasmThreads ? "ENVIRONMENT_IS_PTHREAD" : "false"; +// USE_PTHREADS is emscripten's define symbol, which is passed to acorn optimizer, so we could use it here +#if USE_PTHREADS +const monoWasmThreads = true; +const isPThread = `ENVIRONMENT_IS_PTHREAD`; +#else +const monoWasmThreads = false; +const isPThread = "false"; +#endif + +// because we can't pass custom define symbols to acorn optimizer, we use environment variables to pass other build options +const WasmEnableLegacyJsInterop = process.env.WasmEnableLegacyJsInterop !== "false"; const DotnetSupportLib = { $DOTNET: {}, diff --git a/src/mono/wasm/runtime/net6-legacy/corebindings.ts b/src/mono/wasm/runtime/net6-legacy/corebindings.ts index 1850aeaa611a5d..97f660910a5c23 100644 --- a/src/mono/wasm/runtime/net6-legacy/corebindings.ts +++ b/src/mono/wasm/runtime/net6-legacy/corebindings.ts @@ -88,7 +88,7 @@ export function init_legacy_exports(): void { legacyHelpers.runtime_legacy_exports_classname = "LegacyExports"; legacyHelpers.runtime_legacy_exports_class = cwraps.mono_wasm_assembly_find_class(runtimeHelpers.runtime_interop_module, runtimeHelpers.runtime_interop_namespace, legacyHelpers.runtime_legacy_exports_classname); if (!legacyHelpers.runtime_legacy_exports_class) - throw "Can't find " + runtimeHelpers.runtime_interop_namespace + "." + runtimeHelpers.runtime_interop_exports_classname + " class"; + throw "Can't find " + runtimeHelpers.runtime_interop_namespace + "." + legacyHelpers.runtime_legacy_exports_classname + " class"; for (const sig of fn_signatures) { const wf: any = legacyManagedExports; diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 06f877690ff76e..348f2c1ca98c8d 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -20,13 +20,13 @@ true false true - true $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) false + true false emcc $(ArtifactsObjDir)wasm @@ -400,7 +400,7 @@ + EnvironmentVariables="WasmEnableLegacyJsInterop=$(WasmEnableLegacyJsInterop)" />