From 8b7ea8c2469bb658e61edbb1c168484b57b02a6d Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Thu, 13 Apr 2023 11:37:09 +0200 Subject: [PATCH 1/2] rebase --- eng/testing/tests.browser.targets | 20 ++++++++++++---- .../Directory.Build.props | 2 +- ....Runtime.InteropServices.JavaScript.csproj | 7 ++---- .../JavaScript/Interop/JavaScriptImports.cs | 2 +- .../JavaScript/Interop/LegacyExports.cs | 20 +++++++++++++++- .../JavaScript/JSFunctionBinding.cs | 2 -- .../JavaScript/JSObject.References.cs | 4 ++-- ...ervices.JavaScript.Legacy.UnitTests.csproj | 4 ++-- ...me.InteropServices.JavaScript.Tests.csproj | 6 +++-- .../JavaScript/JSImportExportTest.cs | 2 +- .../WorkloadManifest.targets.in | 2 +- .../Wasm.Advanced.Sample.csproj | 1 + src/mono/sample/wasm/browser-advanced/main.js | 4 ++-- .../ILLink.Descriptors.LegacyJsInterop.xml | 24 ------------------- .../ILLink.Substitutions.LegacyJsInterop.xml | 7 ++++++ src/mono/wasm/build/WasmApp.Native.targets | 12 +++++++++- src/mono/wasm/build/WasmApp.targets | 5 +--- src/mono/wasm/runtime/CMakeLists.txt | 2 +- src/mono/wasm/runtime/corebindings.c | 8 +++---- src/mono/wasm/runtime/cwraps.ts | 16 +++++++------ src/mono/wasm/runtime/driver.c | 8 +++---- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 7 +++--- src/mono/wasm/runtime/exports.ts | 10 ++++---- src/mono/wasm/runtime/imports.ts | 5 ++++ src/mono/wasm/runtime/rollup.config.js | 2 +- src/mono/wasm/runtime/startup.ts | 6 ++--- src/mono/wasm/runtime/types.ts | 1 + src/mono/wasm/runtime/wasm-config.h.in | 4 ++-- src/mono/wasm/wasm.proj | 11 +++++---- 29 files changed, 116 insertions(+), 88 deletions(-) delete mode 100644 src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml create mode 100644 src/mono/wasm/build/ILLink.Substitutions.LegacyJsInterop.xml diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets index 9cd1c6fe4998f6..6b561bdefb60c2 100644 --- a/eng/testing/tests.browser.targets +++ b/eng/testing/tests.browser.targets @@ -41,6 +41,21 @@ true + + + <_ExtraTrimmerArgs Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">$(_ExtraTrimmerArgs) --substitutions "$(MonoProjectRoot)\wasm\build\ILLink.Substitutions.LegacyJsInterop.xml" + + + - - - 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 21b7023bcce08b..8c1d243d6bbb5f 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -253,7 +253,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 4e4ac9c91394e8..a77e9bf07b3400 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 @@ -12,10 +12,7 @@ true true $(DefineConstants);FEATURE_WASM_THREADS - $(DefineConstants);ENABLE_LEGACY_JS_INTEROP - $(MonoProjectRoot)wasm\build\ILLink.Descriptors.LegacyJsInterop.xml + $(DefineConstants);DISABLE_LEGACY_JS_INTEROP @@ -66,7 +63,7 @@ - + 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 fd7a9f6c6bde85..79805b1b2df029 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,7 +20,7 @@ public static void MarshalPromise(Span arguments) } } -#if ENABLE_LEGACY_JS_INTEROP +#if !DISABLE_LEGACY_JS_INTEROP #region legacy public static object GetGlobalObject(string? str = null) 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 431f83e9fff874..10092d5971bb4f 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 @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; @@ -9,9 +10,26 @@ namespace System.Runtime.InteropServices.JavaScript { - // the public methods are protected from trimming by ILLink.Descriptors.LegacyJsInterop.xml + internal static unsafe partial class LegacyExportsTrimmingRoot + { + // the public methods are used from JavaScript, but the trimmer doesn't know about it. + // It's protected by DynamicDependencyAttribute on JSFunctionBinding.BindJSFunction. + public static void TrimWhenNotWasmEnableLegacyJsInterop() + { + // if MSBuild property WasmEnableLegacyJsInterop==false this call would be substituted away and LegacyExports would be trimmed. + LegacyExports.PreventTrimming(); + } + } + internal static unsafe partial class LegacyExports { + // the public methods of this class are used from JavaScript, but the trimmer doesn't know about it. + // They are protected by LegacyExportsTrimmingRoot.PreventTrimming and JSFunctionBinding.BindJSFunction. + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(LegacyExports))] + internal static void PreventTrimming() + { + } + public static void GetCSOwnedObjectByJSHandleRef(nint jsHandle, int shouldAddInflight, out JSObject? result) { lock (JSHostImplementation.s_csOwnedObjects) 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 0fdd142569526c..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 again, see https://github.com/dotnet/runtime/pull/82826 - [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/JSObject.References.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs index 0544ab4e2e8805..d731a48392b1e1 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,7 +10,7 @@ public partial class JSObject { internal nint JSHandle; -#if ENABLE_LEGACY_JS_INTEROP +#if !DISABLE_LEGACY_JS_INTEROP internal GCHandle? InFlight; internal int InFlightCounter; #endif @@ -21,7 +21,7 @@ internal JSObject(IntPtr jsHandle) JSHandle = jsHandle; } -#if ENABLE_LEGACY_JS_INTEROP +#if !DISABLE_LEGACY_JS_INTEROP internal void AddInFlight() { ObjectDisposedException.ThrowIf(IsDisposed, this); 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 eae66e4e4a9c9a..1afaf6178ad2ee 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 @@ -6,10 +6,10 @@ $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop 0612 true - $(DefineConstants);ENABLE_LEGACY_JS_INTEROP + $(DefineConstants);DISABLE_LEGACY_JS_INTEROP - + 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 f34edc44b25721..b3f923ae5c26f5 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,8 +4,10 @@ $(NetCoreAppCurrent)-browser true $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop - true - $(DefineConstants);ENABLE_LEGACY_JS_INTEROP + true + true + false + $(DefineConstants);DISABLE_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 30e97fe180a192..df2c3d67f091fa 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,7 +58,7 @@ public unsafe void GlobalThis() [Fact] public unsafe void DotnetInstance() { -#if ENABLE_LEGACY_JS_INTEROP +#if !DISABLE_LEGACY_JS_INTEROP Assert.True(JSHost.DotnetInstance.HasProperty("MONO")); Assert.Equal("object", JSHost.DotnetInstance.GetTypeOfProperty("MONO")); #endif diff --git a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in index c9a2c7494450fd..c1be784f8bb2f4 100644 --- a/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in +++ b/src/mono/nuget/Microsoft.NET.Workload.Mono.Toolchain.Current.Manifest/WorkloadManifest.targets.in @@ -38,7 +38,7 @@ - <_WasmNativeWorkloadNeeded Condition="'$(RunAOTCompilation)' == 'true' or '$(WasmEnableSIMD)' == 'true' or '$(WasmBuildNative)' == 'true' or + <_WasmNativeWorkloadNeeded Condition="'$(RunAOTCompilation)' == 'true' or '$(WasmEnableSIMD)' == 'true' or '$(WasmEnableLegacyJsInterop)' == 'false' or '$(WasmBuildNative)' == 'true' or '$(WasmGenerateAppBundle)' == 'true' or '$(UsingMicrosoftNETSdkBlazorWebAssembly)' != 'true'" >true false diff --git a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj index 61399832ef2e5e..006e3c3a7aae5b 100644 --- a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj +++ b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj @@ -3,6 +3,7 @@ true true + false true true true diff --git a/src/mono/sample/wasm/browser-advanced/main.js b/src/mono/sample/wasm/browser-advanced/main.js index 175a26d6d137f1..b6e0ef0a8d1a92 100644 --- a/src/mono/sample/wasm/browser-advanced/main.js +++ b/src/mono/sample/wasm/browser-advanced/main.js @@ -29,11 +29,11 @@ try { fetch: (url, fetchArgs) => { console.log("fetching " + url); // we are testing that we can retry loading of the assembly - if (testAbort && url.indexOf('System.Private.Uri.dll') != -1) { + if (testAbort && url.indexOf('System.Private.CoreLib') != -1) { testAbort = false; return fetch(url + "?testAbort=true", fetchArgs); } - if (testError && url.indexOf('System.Console.dll') != -1) { + if (testError && url.indexOf('System.Console') != -1) { testError = false; return fetch(url + "?testError=true", fetchArgs); } diff --git a/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml b/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml deleted file mode 100644 index eaa9ab362f1311..00000000000000 --- a/src/mono/wasm/build/ILLink.Descriptors.LegacyJsInterop.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/mono/wasm/build/ILLink.Substitutions.LegacyJsInterop.xml b/src/mono/wasm/build/ILLink.Substitutions.LegacyJsInterop.xml new file mode 100644 index 00000000000000..523a1d947c5f16 --- /dev/null +++ b/src/mono/wasm/build/ILLink.Substitutions.LegacyJsInterop.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 15c8143f7f0966..d7afe274a1cb2f 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -113,6 +113,9 @@ true + + true + true false @@ -124,6 +127,9 @@ true true + + true + false @@ -188,6 +194,7 @@ $(EmccTotalMemory) 5MB false + true @@ -217,6 +224,8 @@ <_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" /> <_EmccCFlags Include="-DENABLE_AOT_PROFILER=1" Condition="$(WasmProfilers.Contains('aot'))" /> <_EmccCFlags Include="-DENABLE_BROWSER_PROFILER=1" Condition="$(WasmProfilers.Contains('browser'))" /> + <_EmccCFlags Include="-DDISABLE_LEGACY_JS_INTEROP=1" Condition="'$(WasmEnableLegacyJsInterop)' == 'false'" /> + <_EmccCFlags Include="-DGEN_PINVOKE=1" /> <_EmccCFlags Include="-emit-llvm" /> @@ -256,7 +265,8 @@ - + + diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 22f26139e3be26..7833e086417c14 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -124,6 +124,7 @@ full <_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' == 'true' and '$(RunAOTCompilation)' == 'true'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.WasmIntrinsics.xml" <_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true' or '$(RunAOTCompilation)' != 'true'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.NoWasmIntrinsics.xml" + <_ExtraTrimmerArgs Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.LegacyJsInterop.xml" false @@ -141,10 +142,6 @@ - - diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 47bda408d75343..4fcf86852c715a 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -4,7 +4,7 @@ project(mono-wasm-runtime C) option(DISABLE_THREADS "defined if the build does NOT support multithreading" ON) option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threads to be created in a multithreaded build" OFF) -option(ENABLE_LEGACY_JS_INTEROP "defined if the build supports legacy JavaScript interop" ON) +option(DISABLE_LEGACY_JS_INTEROP "defined if the build does not support legacy JavaScript interop" OFF) set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(dotnet corebindings.c driver.c pinvoke.c) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index d07e106668c3e4..ded8b022d7ddff 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -27,7 +27,7 @@ extern void mono_wasm_marshal_promise(void *data); typedef void (*background_job_cb)(void); void mono_threads_schedule_background_job (background_job_cb cb); -#ifdef ENABLE_LEGACY_JS_INTEROP +#ifndef DISABLE_LEGACY_JS_INTEROP extern void mono_wasm_invoke_js_with_args_ref (int js_handle, MonoString **method, MonoArray **args, int *is_exception, MonoObject **result); extern void mono_wasm_get_object_property_ref (int js_handle, MonoString **propertyName, int *is_exception, MonoObject **result); extern void mono_wasm_set_object_property_ref (int js_handle, MonoString **propertyName, MonoObject **value, int createIfNotExist, int hasOwnProperty, int *is_exception, MonoObject **result); @@ -40,7 +40,7 @@ extern void mono_wasm_typed_array_from_ref (int ptr, int begin, int end, int byt // Blazor specific custom routines - see dotnet_support.js for backing code extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *callInfo, void* arg0, void* arg1, void* arg2); -#endif /* ENABLE_LEGACY_JS_INTEROP */ +#endif /* DISABLE_LEGACY_JS_INTEROP */ // HybridGlobalization extern void mono_wasm_change_case_invariant(MonoString **exceptionMessage, const uint16_t* src, int32_t srcLength, uint16_t* dst, int32_t dstLength, mono_bool bToUpper); @@ -59,7 +59,7 @@ void bindings_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::MarshalPromise", mono_wasm_marshal_promise); mono_add_internal_call ("Interop/Runtime::RegisterGCRoot", mono_wasm_register_root); mono_add_internal_call ("Interop/Runtime::DeregisterGCRoot", mono_wasm_deregister_root); -#ifdef ENABLE_LEGACY_JS_INTEROP +#ifndef DISABLE_LEGACY_JS_INTEROP // legacy mono_add_internal_call ("Interop/Runtime::InvokeJSWithArgsRef", mono_wasm_invoke_js_with_args_ref); mono_add_internal_call ("Interop/Runtime::GetObjectPropertyRef", mono_wasm_get_object_property_ref); @@ -73,7 +73,7 @@ void bindings_initialize_internals (void) // Blazor specific custom routines - see dotnet_support.js for backing code mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJS", mono_wasm_invoke_js_blazor); -#endif /* ENABLE_LEGACY_JS_INTEROP */ +#endif /* DISABLE_LEGACY_JS_INTEROP */ mono_add_internal_call ("Interop/JsGlobalization::ChangeCaseInvariant", mono_wasm_change_case_invariant); mono_add_internal_call ("Interop/JsGlobalization::ChangeCase", mono_wasm_change_case); mono_add_internal_call ("Interop/JsGlobalization::CompareString", mono_wasm_compare_string); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 586dc1148dbcaa..4dfa75641a0f9b 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -1,18 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; -import { +import type { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments } from "./types"; -import { Module } from "./imports"; -import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; +import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; +import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; +import { disableLegacyJsInterop, Module } from "./imports"; type SigLine = [lazy: boolean, name: string, returnType: string | null, argTypes?: string[], opts?: any]; -const legacy_interop_cwraps: SigLine[] = !WasmEnableLegacyJsInterop ? [] : [ +const legacy_interop_cwraps: SigLine[] = WasmEnableLegacyJsInterop ? [ [true, "mono_wasm_array_get_ref", "void", ["number", "number", "number"]], [true, "mono_wasm_obj_array_new_ref", "void", ["number", "number"]], [true, "mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], @@ -26,7 +26,7 @@ const legacy_interop_cwraps: SigLine[] = !WasmEnableLegacyJsInterop ? [] : [ [true, "mono_wasm_obj_array_new", "number", ["number"]], [true, "mono_wasm_obj_array_set", "void", ["number", "number", "number"]], [true, "mono_wasm_array_length_ref", "number", ["number"]], -]; +] : []; // when the method is assigned/cached at usage, instead of being invoked directly from cwraps, it can't be marked lazy, because it would be re-bound on each call const fn_signatures: SigLine[] = [ @@ -259,7 +259,9 @@ export const enum I52Error { } export function init_c_exports(): void { - for (const sig of fn_signatures) { + const lfns = WasmEnableLegacyJsInterop && !disableLegacyJsInterop ? legacy_interop_cwraps : []; + const fns = [...fn_signatures, ...lfns]; + for (const sig of fns) { const wf: any = wrapped_c_functions; const [lazy, name, returnType, argTypes, opts] = sig; if (lazy) { diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 0dc84315a929d9..a640e88c6e0cd5 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -57,7 +57,7 @@ extern void mono_wasm_register_timezones_bundle(); extern void mono_wasm_set_entrypoint_breakpoint (const char* assembly_name, int method_token); static void mono_wasm_init_finalizer_thread (void); -#ifdef ENABLE_LEGACY_JS_INTEROP +#ifndef DISABLE_LEGACY_JS_INTEROP #define MARSHAL_TYPE_NULL 0 #define MARSHAL_TYPE_INT 1 @@ -113,7 +113,7 @@ static int resolved_datetime_class = 0, resolved_safehandle_class = 0, resolved_voidtaskresult_class = 0; -#endif /* ENABLE_LEGACY_JS_INTEROP */ +#endif /* DISABLE_LEGACY_JS_INTEROP */ int mono_wasm_enable_gc = 1; @@ -781,7 +781,7 @@ mono_wasm_string_from_utf16_ref (const mono_unichar2 * chars, int length, MonoSt MONO_EXIT_GC_UNSAFE; } -#ifdef ENABLE_LEGACY_JS_INTEROP +#ifndef DISABLE_LEGACY_JS_INTEROP static int class_is_task (MonoClass *klass) @@ -1215,7 +1215,7 @@ mono_wasm_string_array_new_ref (int size, MonoArray **result) MONO_EXIT_GC_UNSAFE; } -#endif /* ENABLE_LEGACY_JS_INTEROP */ +#endif /* DISABLE_LEGACY_JS_INTEROP */ EMSCRIPTEN_KEEPALIVE int mono_wasm_exec_regression (int verbose_level, char *image) diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 19900b76cac876..e6139d35375199 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -14,7 +14,8 @@ 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 DISABLE_LEGACY_JS_INTEROP = process.env.DISABLE_LEGACY_JS_INTEROP === "1"; +const disableLegacyJsInterop = DISABLE_LEGACY_JS_INTEROP ? "true" : "false"; const DotnetSupportLib = { $DOTNET: {}, @@ -37,7 +38,7 @@ if (ENVIRONMENT_IS_NODE) { __dotnet_replacements.requirePromise = __requirePromise; } let __dotnet_exportedAPI = __initializeImportsAndExports( - { isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise }, + { isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isWorker:ENVIRONMENT_IS_WORKER, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, isPThread:${isPThread}, disableLegacyJsInterop:${disableLegacyJsInterop}, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise }, { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module, marshaled_imports: IMPORTS }, __dotnet_replacements, __callbackAPI); updateMemoryViews = __dotnet_replacements.updateMemoryViews; @@ -114,7 +115,7 @@ if (monoWasmThreads) { "mono_wasm_diagnostic_server_stream_signal_work_available", ] } -if (WasmEnableLegacyJsInterop) { +if (!DISABLE_LEGACY_JS_INTEROP) { linked_functions = [...linked_functions, "mono_wasm_invoke_js_with_args_ref", "mono_wasm_get_object_property_ref", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index e185a3adf286ed..02641068889c15 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -7,7 +7,7 @@ import MonoWasmThreads from "consts:monoWasmThreads"; import BuildConfiguration from "consts:configuration"; import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; -import { ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, moduleExports, set_emscripten_entrypoint, set_imports_exports } from "./imports"; +import { ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, disableLegacyJsInterop, moduleExports, set_emscripten_entrypoint, set_imports_exports } from "./imports"; import { is_nullish, EarlyImports, EarlyExports, EarlyReplacements, RuntimeAPI, CreateDotnetRuntimeType, DotnetModuleInternal } from "./types"; import { configure_emscripten_startup, mono_wasm_pthread_worker_init } from "./startup"; @@ -42,13 +42,13 @@ function initializeImportsAndExports( // we want to have same instance of MONO, BINDING and Module in dotnet iife set_imports_exports(imports, exports); - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { set_legacy_exports(exports); } init_polyfills(replacements); // here we merge methods from the local objects into exported objects - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { Object.assign(exports.mono, export_mono_api()); Object.assign(exports.binding, export_binding_api()); Object.assign(exports.internal, export_internal_api()); @@ -67,7 +67,7 @@ function initializeImportsAndExports( }, ...API, }); - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { Object.assign(exportedRuntimeAPI, { MONO: exports.mono, BINDING: exports.binding, @@ -94,7 +94,7 @@ function initializeImportsAndExports( if (imports.isGlobal || !module.disableDotnet6Compatibility) { Object.assign(module, exportedRuntimeAPI); - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { // backward compatibility // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts index e15015cc8b91e1..cab9189477d356 100644 --- a/src/mono/wasm/runtime/imports.ts +++ b/src/mono/wasm/runtime/imports.ts @@ -22,6 +22,10 @@ export let ENVIRONMENT_IS_PTHREAD: boolean; export const exportedRuntimeAPI: RuntimeAPI = {} as any; export const moduleExports: ModuleAPI = {} as any; export let emscriptenEntrypoint: CreateDotnetRuntimeType; + +// this is when we link with workload tools. The consts:WasmEnableLegacyJsInterop is when we compile with rollup. +export let disableLegacyJsInterop = false; + // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function set_imports_exports( imports: EarlyImports, @@ -36,6 +40,7 @@ export function set_imports_exports( ENVIRONMENT_IS_WEB = imports.isWeb; ENVIRONMENT_IS_WORKER = imports.isWorker; ENVIRONMENT_IS_PTHREAD = imports.isPThread; + disableLegacyJsInterop = imports.disableLegacyJsInterop; runtimeHelpers.quit = imports.quit_; runtimeHelpers.ExitStatus = imports.ExitStatus; runtimeHelpers.requirePromise = imports.requirePromise; diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js index 6d7b77906f17cd..a666eebd725f9c 100644 --- a/src/mono/wasm/runtime/rollup.config.js +++ b/src/mono/wasm/runtime/rollup.config.js @@ -16,7 +16,7 @@ const isDebug = configuration !== "Release"; const productVersion = process.env.ProductVersion || "8.0.0-dev"; const nativeBinDir = process.env.NativeBinDir ? process.env.NativeBinDir.replace(/"/g, "") : "bin"; const monoWasmThreads = process.env.MonoWasmThreads === "true" ? true : false; -const WasmEnableLegacyJsInterop = process.env.WasmEnableLegacyJsInterop !== "false" ? true : false; +const WasmEnableLegacyJsInterop = process.env.DISABLE_LEGACY_JS_INTEROP !== "1" ? true : false; const monoDiagnosticsMock = process.env.MonoDiagnosticsMock === "true" ? true : false; const terserConfig = { compress: { diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index d1a76cf7f5a78a..399b2ec5b413e1 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -5,7 +5,7 @@ import BuildConfiguration from "consts:configuration"; import MonoWasmThreads from "consts:monoWasmThreads"; import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigInternal, DotnetModuleInternal, mono_assert } from "./types"; -import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, Module, runtimeHelpers } from "./imports"; +import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, disableLegacyJsInterop, INTERNAL, Module, runtimeHelpers } from "./imports"; import cwraps, { init_c_exports } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; @@ -341,7 +341,7 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { // init_polyfills() is already called from export.ts init_c_exports(); cwraps_internal(INTERNAL); - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { cwraps_mono_api(MONO); cwraps_binding_api(BINDING); } @@ -606,7 +606,7 @@ export function bindings_init(): void { try { const mark = startMeasure(); init_managed_exports(); - if (WasmEnableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { init_legacy_exports(); } initialize_marshalers_to_js(); diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index 30461acde12105..9b34741f419f35 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -362,6 +362,7 @@ export type EarlyImports = { isShell: boolean, isWeb: boolean, isPThread: boolean, + disableLegacyJsInterop: boolean, quit_: Function, ExitStatus: ExitStatusError, requirePromise: Promise diff --git a/src/mono/wasm/runtime/wasm-config.h.in b/src/mono/wasm/runtime/wasm-config.h.in index 7ca162a30ce833..88a9599eeba6df 100644 --- a/src/mono/wasm/runtime/wasm-config.h.in +++ b/src/mono/wasm/runtime/wasm-config.h.in @@ -10,7 +10,7 @@ /* Support for starting user threads is disabled */ #cmakedefine DISABLE_WASM_USER_THREADS -/* Support legacy JavaScript interop */ -#cmakedefine ENABLE_LEGACY_JS_INTEROP +/* Support for legacy JS interop is disabled */ +#cmakedefine DISABLE_LEGACY_JS_INTEROP #endif/*__MONO_WASM_CONFIG_H__*/ diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 9755e405afed42..4da32bff9d960b 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -397,7 +397,7 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASM_OPT_ADDITIONAL_FLAGS="--enable-simd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 - $(CMakeBuildRuntimeConfigureCmd) -DENABLE_LEGACY_JS_INTEROP=0 + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_LEGACY_JS_INTEROP=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) @@ -407,6 +407,8 @@ cmake --build . --config $(Configuration) $(CmakeOptions) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeCmd) bash -c 'source $(EMSDK_PATH)/emsdk_env.sh 2>&1 && $(CMakeBuildRuntimeCmd)' + <_DisableLegacyJsInterop Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">1 + <_DisableLegacyJsInterop Condition="'$(WasmEnableLegacyJsInterop)' != 'false'">0 - + + EnvironmentVariables="DISABLE_LEGACY_JS_INTEROP=$(_DisableLegacyJsInterop)" /> @@ -519,7 +522,7 @@ - Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),WasmEnableLegacyJsInterop:$(WasmEnableLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock) + Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),DISABLE_LEGACY_JS_INTEROP:$(_DisableLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock) From a9bf333b5f417263c31febf993f25eb7d168989b Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 14 Apr 2023 14:35:09 +0200 Subject: [PATCH 2/2] fix --- .../Runtime/InteropServices/JavaScript/JSFunctionBinding.cs | 2 ++ 1 file changed, 2 insertions(+) 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 6b2518472d9c48..c01965dc4610c3 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,6 +142,8 @@ 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")] + // Same for legacy, but the type could be explicitly trimmed by setting WasmEnableLegacyJsInterop=false which would use ILLink.Descriptors.LegacyJsInterop.xml + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "System.Runtime.InteropServices.JavaScript.LegacyExportsTrimmingRoot", "System.Runtime.InteropServices.JavaScript")] public static JSFunctionBinding BindJSFunction(string functionName, string moduleName, ReadOnlySpan signatures) { if (RuntimeInformation.OSArchitecture != Architecture.Wasm)