From f490040ae96548b3183948b6b108a7f897d57fb4 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 19 Jan 2024 16:23:05 +0100 Subject: [PATCH] [browser] remove legacy js interop (#96841) --- .gitattributes | 1 - eng/liveBuilds.targets | 1 - eng/testing/tests.browser.targets | 16 - .../Directory.Build.props | 1 - ...tem.Runtime.InteropServices.JavaScript.sln | 2 - .../src/CompatibilitySuppressions.xml | 37 - ....Runtime.InteropServices.JavaScript.csproj | 15 - .../JavaScript/Interop/JavaScriptImports.cs | 37 - .../JavaScript/Interop/LegacyExports.cs | 247 ------ .../JavaScript/JSFunctionBinding.cs | 2 - .../JavaScript/JSObject.References.cs | 39 - .../JavaScript/JSProxyContext.cs | 63 -- .../JavaScript/Legacy/Array.cs | 122 --- .../JavaScript/Legacy/ArrayBuffer.cs | 56 -- .../JavaScript/Legacy/DataView.cs | 233 ------ .../JavaScript/Legacy/Function.cs | 66 -- .../Legacy/LegacyHostImplementation.cs | 226 ----- .../JavaScript/Legacy/Runtime.cs | 117 --- .../JavaScript/Legacy/Uint8Array.cs | 84 -- ...ropServices.JavaScript.Legacy.Tests.csproj | 38 - .../InteropServices/JavaScript/ArrayTests.cs | 173 ---- .../JavaScript/DataViewTests.cs | 134 --- .../JavaScript/DelegateTests.cs | 449 ---------- .../JavaScript/HelperMarshal.cs | 463 ---------- .../JavaScript/JavaScriptTests.cs | 215 ----- .../JavaScript/MarshalTests.cs | 791 ------------------ .../InteropServices/JavaScript/MemoryTests.cs | 144 ---- .../JavaScript/ParallelTests.cs | 70 -- .../JavaScript/TypedArrayTests.cs | 38 - ...me.InteropServices.JavaScript.Tests.csproj | 5 +- .../JavaScript}/HttpRequestMessageTest.cs | 83 -- .../JavaScript/JSImportExportTest.cs | 5 - .../InteropServices/JavaScript/TimerTests.cs | 0 .../InteropServices/JavaScript}/timers.mjs | 0 src/libraries/tests.proj | 1 - src/mono/browser/.gitignore | 1 - src/mono/browser/browser.proj | 9 +- src/mono/browser/build/BrowserWasmApp.targets | 7 - .../ILLink.Substitutions.LegacyJsInterop.xml | 7 - src/mono/browser/build/README.md | 2 - src/mono/browser/runtime/CMakeLists.txt | 1 - src/mono/browser/runtime/corebindings.c | 30 - src/mono/browser/runtime/cwraps.ts | 49 +- src/mono/browser/runtime/dotnet-legacy.d.ts | 295 ------- src/mono/browser/runtime/dotnet.d.ts | 27 - src/mono/browser/runtime/driver.c | 551 +----------- .../browser/runtime/es6/dotnet.es6.lib.js | 6 - src/mono/browser/runtime/exports-binding.ts | 24 - src/mono/browser/runtime/exports-linker.ts | 7 +- src/mono/browser/runtime/exports.ts | 75 +- src/mono/browser/runtime/globals.ts | 4 +- src/mono/browser/runtime/loader/globals.ts | 1 - .../browser/runtime/net6-legacy/buffers.ts | 114 --- .../runtime/net6-legacy/corebindings.ts | 115 --- .../browser/runtime/net6-legacy/cs-to-js.ts | 354 -------- .../runtime/net6-legacy/export-types.ts | 243 ------ .../runtime/net6-legacy/exports-legacy.ts | 115 --- .../browser/runtime/net6-legacy/globals.ts | 37 - .../browser/runtime/net6-legacy/js-to-cs.ts | 294 ------- .../runtime/net6-legacy/method-binding.ts | 682 --------------- .../runtime/net6-legacy/method-calls.ts | 307 ------- .../browser/runtime/net6-legacy/strings.ts | 40 - src/mono/browser/runtime/rollup.config.js | 25 +- src/mono/browser/runtime/startup.ts | 33 +- src/mono/browser/runtime/tsconfig.shared.json | 1 - src/mono/browser/runtime/types/emscripten.ts | 19 - src/mono/browser/runtime/types/index.ts | 10 - src/mono/browser/runtime/types/internal.ts | 11 +- src/mono/browser/runtime/wasm-config.h.in | 3 - .../WorkloadManifest.targets.in | 1 - .../Wasm.Advanced.Sample.csproj | 1 - .../sample/wasm/browser-bench/JSInterop.cs | 45 - src/mono/sample/wasm/browser-bench/main.js | 26 +- .../Wasm.Browser.WebPack.Sample.csproj | 2 - .../Wasm.Console.Node.TS.Sample.csproj | 2 - .../Wasm.Node.WebPack.Sample.csproj | 2 - .../Blazor/WorkloadRequiredTests.cs | 1 - .../WasmNativeDefaultsTests.cs | 9 +- src/mono/wasm/build/README.md | 2 - src/mono/wasm/build/WasmApp.Common.targets | 1 - src/mono/wasm/test-main.js | 30 +- 81 files changed, 65 insertions(+), 7530 deletions(-) delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/ArrayBuffer.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/DataView.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Function.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Uint8Array.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs delete mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs rename src/libraries/System.Runtime.InteropServices.JavaScript/tests/{System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/Http => System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript}/HttpRequestMessageTest.cs (77%) rename src/libraries/System.Runtime.InteropServices.JavaScript/tests/{System.Runtime.InteropServices.JavaScript.Legacy.UnitTests => System.Runtime.InteropServices.JavaScript.UnitTests}/System/Runtime/InteropServices/JavaScript/TimerTests.cs (100%) rename src/libraries/System.Runtime.InteropServices.JavaScript/tests/{System.Runtime.InteropServices.JavaScript.Legacy.UnitTests => System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript}/timers.mjs (100%) delete mode 100644 src/mono/browser/build/ILLink.Substitutions.LegacyJsInterop.xml delete mode 100644 src/mono/browser/runtime/dotnet-legacy.d.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/buffers.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/corebindings.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/cs-to-js.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/export-types.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/exports-legacy.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/globals.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/js-to-cs.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/method-binding.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/method-calls.ts delete mode 100644 src/mono/browser/runtime/net6-legacy/strings.ts diff --git a/.gitattributes b/.gitattributes index f94bdb5eefa12..55a35b1afffff 100644 --- a/.gitattributes +++ b/.gitattributes @@ -78,4 +78,3 @@ src/tests/JIT/Performance/CodeQuality/BenchmarksGame/reverse-complement/revcomp- src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input.txt text eol=lf src/tests/JIT/Performance/CodeQuality/BenchmarksGame/k-nucleotide/knucleotide-input-big.txt text eol=lf src/mono/wasm/runtime/dotnet.d.ts text eol=lf -src/mono/wasm/runtime/dotnet-legacy.d.ts text eol=lf diff --git a/eng/liveBuilds.targets b/eng/liveBuilds.targets index 5f3bcc6c356f1..70a3cac8cbcdd 100644 --- a/eng/liveBuilds.targets +++ b/eng/liveBuilds.targets @@ -204,7 +204,6 @@ $(LibrariesNativeArtifactsPath)dotnet.runtime.js; $(LibrariesNativeArtifactsPath)dotnet.runtime.js.map; $(LibrariesNativeArtifactsPath)dotnet.d.ts; - $(LibrariesNativeArtifactsPath)dotnet-legacy.d.ts; $(LibrariesNativeArtifactsPath)package.json; $(LibrariesNativeArtifactsPath)dotnet.native.wasm; $(LibrariesNativeArtifactsPath)dotnet.native.js.symbols; diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets index 005a43083a823..5cb92cf605c6d 100644 --- a/eng/testing/tests.browser.targets +++ b/eng/testing/tests.browser.targets @@ -33,7 +33,6 @@ >true <_BundleAOTTestWasmAppForHelixDependsOn>$(_BundleAOTTestWasmAppForHelixDependsOn);PrepareForWasmBuildApp;_PrepareForAOTOnHelix - true false true true @@ -47,21 +46,6 @@ true - - - <_ExtraTrimmerArgs Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">$(_ExtraTrimmerArgs) --substitutions "$(BrowserProjectRoot)build\ILLink.Substitutions.LegacyJsInterop.xml" - - - - diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln b/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln index 73c85be0abf1e..a13a1af6f03fc 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/System.Runtime.InteropServices.JavaScript.sln @@ -11,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JSImportGenerator.Unit.Tests", "tests\JSImportGenerator.UnitTest\JSImportGenerator.Unit.Tests.csproj", "{BFED925C-18F2-4C98-833E-66F205234598}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServices.JavaScript.Legacy.Tests", "tests\System.Runtime.InteropServices.JavaScript.Legacy.UnitTests\System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj", "{ABA5A92B-CAD8-47E8-A7CE-D28A67FB69C0}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.InteropServices.JavaScript.Tests", "tests\System.Runtime.InteropServices.JavaScript.UnitTests\System.Runtime.InteropServices.JavaScript.Tests.csproj", "{765B4AA5-723A-44FF-BC4E-EB0F03103F6D}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator", "..\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj", "{FB12C247-AFEF-4772-BB0C-983969B6CF32}" diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/CompatibilitySuppressions.xml b/src/libraries/System.Runtime.InteropServices.JavaScript/src/CompatibilitySuppressions.xml index 74336f2b95657..5619a7b22a8f2 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/CompatibilitySuppressions.xml @@ -1,42 +1,5 @@  - - CP0001 - T:System.Runtime.InteropServices.JavaScript.Array - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0001 - T:System.Runtime.InteropServices.JavaScript.ArrayBuffer - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0001 - T:System.Runtime.InteropServices.JavaScript.DataView - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0001 - T:System.Runtime.InteropServices.JavaScript.Function - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0001 - T:System.Runtime.InteropServices.JavaScript.Runtime - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - - CP0001 - T:System.Runtime.InteropServices.JavaScript.Uint8Array - ref/net9.0/System.Runtime.InteropServices.JavaScript.dll - runtimes/browser/lib/net9.0/System.Runtime.InteropServices.JavaScript.dll - - CP0001 T:System.Runtime.InteropServices.JavaScript.SynchronizationContextExtension 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 1b8664dc43591..8ad195d25ad0f 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 @@ -14,9 +14,7 @@ true true false - true $(DefineConstants);FEATURE_WASM_THREADS - $(DefineConstants);DISABLE_LEGACY_JS_INTEROP $(DefineConstants);ENABLE_JS_INTEROP_BY_VALUE true @@ -29,7 +27,6 @@ - @@ -68,18 +65,6 @@ - - - - - - - - - - - - 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 deleted file mode 100644 index 667fed536adaf..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System.Runtime.InteropServices.JavaScript -{ - internal static unsafe partial class JavaScriptImports - { -#if !DISABLE_LEGACY_JS_INTEROP - #region legacy - - public static object GetGlobalObject(string? str = null) - { - int exception; - Interop.Runtime.GetGlobalObjectRef(str, out exception, out object jsObj); - - if (exception != 0) - throw new JSException(SR.Format(SR.ErrorResolvingFromGlobalThis, str)); - - LegacyHostImplementation.ReleaseInFlight(jsObj); - return jsObj; - } - - public static IntPtr CreateCSOwnedObject(string typeName, object[] parms) - { - Interop.Runtime.CreateCSOwnedObjectRef(typeName, parms, out int exception, out object res); - if (exception != 0) - throw new JSException((string)res); - - return (IntPtr)(int)res; - } - - #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 deleted file mode 100644 index 928d30f74f513..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/LegacyExports.cs +++ /dev/null @@ -1,247 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// 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; -using System.Threading.Tasks; - -namespace System.Runtime.InteropServices.JavaScript -{ - 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) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - result = JSProxyContext.MainThreadContext.GetCSOwnedObjectByJSHandle(jsHandle, shouldAddInflight); - } - - public static IntPtr GetCSOwnedObjectJSHandleRef(in JSObject jsObject, int shouldAddInflight) - { - jsObject.AssertNotDisposed(); - - if (shouldAddInflight != 0) - { - jsObject.AddInFlight(); - } - return jsObject.JSHandle; - } - - public static IntPtr TryGetCSOwnedObjectJSHandleRef(in object rawObj, int shouldAddInflight) - { - JSObject? jsObject = rawObj as JSObject; - if (jsObject != null && shouldAddInflight != 0) - { - jsObject.AddInFlight(); - } - return jsObject?.JSHandle ?? IntPtr.Zero; - } - - public static void CreateCSOwnedProxyRef(nint jsHandle, LegacyHostImplementation.MappedType mappedType, int shouldAddInflight, out JSObject jsObject) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - jsObject = JSProxyContext.MainThreadContext.CreateCSOwnedProxy(jsHandle, mappedType, shouldAddInflight); - } - - public static void GetJSOwnedObjectByGCHandleRef(int gcHandle, out object result) - { - GCHandle h = (GCHandle)(IntPtr)gcHandle; - result = h.Target!; - } - - public static IntPtr GetJSOwnedObjectGCHandleRef(in object obj) - { - return JSProxyContext.MainThreadContext.GetJSOwnedObjectGCHandle(obj, GCHandleType.Normal); - } - - public static IntPtr CreateTaskSource() - { - var tcs = new TaskCompletionSource(); - return GetJSOwnedObjectGCHandleRef(tcs); - } - - public static void SetTaskSourceResultRef(int tcsGCHandle, in object result) - { - GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; - // this is JS owned Normal handle. We always have a Target - TaskCompletionSource tcs = (TaskCompletionSource)handle.Target!; - tcs.SetResult(result); - } - - public static void SetTaskSourceFailure(int tcsGCHandle, string reason) - { - GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; - // this is JS owned Normal handle. We always have a Target - TaskCompletionSource tcs = (TaskCompletionSource)handle.Target!; - tcs.SetException(new JSException(reason)); - } - - public static void GetTaskSourceTaskRef(int tcsGCHandle, out object result) - { - GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; - // this is JS owned Normal handle. We always have a Target - TaskCompletionSource tcs = (TaskCompletionSource)handle.Target!; - result = tcs.Task; - } - - public static void SetupJSContinuationRef(in Task _task, JSObject continuationObj) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - // HACK: Attempting to use the in-param will produce CS1628, so we make a temporary copy - // on the stack that can be captured by our local functions below - var task = _task; - - if (task.IsCompleted) - Complete(); - else - task.GetAwaiter().OnCompleted(Complete); - - void Complete() - { - try - { - if (task.Exception == null) - { - object? result; - Type task_type = task.GetType(); - if (task_type == typeof(Task)) - { - result = System.Array.Empty(); - } - else - { - result = JSHostImplementation.GetTaskResultMethodInfo(task_type)?.Invoke(task, null); - } - - continuationObj.Invoke("resolve", result); - } - else - { - continuationObj.Invoke("reject", task.Exception.ToString()); - } - } - catch (Exception e) - { - continuationObj.Invoke("reject", e.ToString()); - } - finally - { - continuationObj.Dispose(); - } - } - } - - public static string ObjectToStringRef(ref object o) - { - return o.ToString() ?? string.Empty; - } - - public static double GetDateValueRef(ref object dtv) - { - ArgumentNullException.ThrowIfNull(dtv); - - if (!(dtv is DateTime dt)) - throw new InvalidCastException(SR.Format(SR.UnableCastObjectToType, dtv.GetType(), typeof(DateTime))); - if (dt.Kind == DateTimeKind.Local) - dt = dt.ToUniversalTime(); - else if (dt.Kind == DateTimeKind.Unspecified) - dt = new DateTime(dt.Ticks, DateTimeKind.Utc); - return new DateTimeOffset(dt).ToUnixTimeMilliseconds(); - } - - // HACK: We need to implicitly box by using an 'object' out-param. - // Note that the return value would have been boxed on the C#->JS transition anyway. - public static void CreateDateTimeRef(double ticks, out object result) - { - DateTimeOffset unixTime = DateTimeOffset.FromUnixTimeMilliseconds((long)ticks); - result = unixTime.DateTime; - } - - // we do this via reflection to allow trimming tools to trim dependency on Uri class and it's assembly - // if the user code has methods with Uri signature, they probably also have the Uri constructor - // if they don't have it, they could configure ILLing to protect it after they enabled trimming - // We believe that this code path is probably not even used in the wild - // System.Private.Uri is ~80KB large assembly so it's worth trimming - private static Type? uriType; - - [Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2077", Justification = "Done on purpose, see comment above.")] - [Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming", "IL2057", Justification = "Done on purpose, see comment above.")] - public static void CreateUriRef(string uri, out object? result) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - if (uriType == null) - { - // StringBuilder to confuse ILLink, which is too smart otherwise - StringBuilder sb = new StringBuilder("System.Uri, System.Private.Uri"); - uriType = Type.GetType(sb.ToString()); - } - // See: https://devblogs.microsoft.com/dotnet/customizing-trimming-in-net-core-5/ - if (uriType == null) throw new InvalidOperationException(SR.UriTypeMissing); - try - { - result = Activator.CreateInstance(uriType, uri); - } - catch (MissingMethodException ex) - { - throw new MissingMethodException(SR.UriConstructorMissing, ex); - } - } - - public static bool IsSimpleArrayRef(ref object a) - { - return a is System.Array arr && arr.Rank == 1 && arr.GetLowerBound(0) == 0; - } - - public static string GetCallSignatureRef(IntPtr _methodHandle, in object objForRuntimeType) - { - var methodHandle = JSHostImplementation.GetMethodHandleFromIntPtr(_methodHandle); - - MethodBase? mb = objForRuntimeType is null ? MethodBase.GetMethodFromHandle(methodHandle) : MethodBase.GetMethodFromHandle(methodHandle, Type.GetTypeHandle(objForRuntimeType)); - if (mb is null) - return string.Empty; - - ParameterInfo[] parms = mb.GetParameters(); - int parmsLength = parms.Length; - if (parmsLength == 0) - return string.Empty; - - var result = new char[parmsLength]; - for (int i = 0; i < parmsLength; i++) - { - Type t = parms[i].ParameterType; - var mt = LegacyHostImplementation.GetMarshalTypeFromType(t); - result[i] = LegacyHostImplementation.GetCallSignatureCharacterForMarshalType(mt, null); - } - - return new string(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 72cd8f87700e3..08619d5325df4 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 @@ -170,8 +170,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")] - // 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) 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 6be3f93d36563..a3d1503af177d 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 @@ -25,10 +25,6 @@ public SynchronizationContext SynchronizationContext } } -#if !DISABLE_LEGACY_JS_INTEROP - internal GCHandle? InFlight; - internal int InFlightCounter; -#endif internal bool _isDisposed; internal JSObject(IntPtr jsHandle, JSProxyContext ctx) @@ -37,41 +33,6 @@ internal JSObject(IntPtr jsHandle, JSProxyContext ctx) JSHandle = jsHandle; } -#if !DISABLE_LEGACY_JS_INTEROP - internal void AddInFlight() - { - AssertNotDisposed(); - lock (ProxyContext) - { - InFlightCounter++; - if (InFlightCounter == 1) - { - Debug.Assert(InFlight == null, "InFlight == null"); - InFlight = GCHandle.Alloc(this, GCHandleType.Normal); - } - } - } - - // Note that we could not use SafeHandle.DangerousAddRef() and DangerousRelease() - // because we could get to zero InFlightCounter multiple times across lifetime of the JSObject - // we only want JSObject to be disposed (from GC finalizer) once there is no in-flight reference and also no natural C# reference - internal void ReleaseInFlight() - { - lock (ProxyContext) - { - Debug.Assert(InFlightCounter != 0, "InFlightCounter != 0"); - - InFlightCounter--; - if (InFlightCounter == 0) - { - Debug.Assert(InFlight.HasValue, "InFlight.HasValue"); - InFlight.Value.Free(); - InFlight = null; - } - } - } -#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/JSProxyContext.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSProxyContext.cs index dcb99ed1d3d4e..5dfabdfee916b 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSProxyContext.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSProxyContext.cs @@ -469,69 +469,6 @@ public static void ReleaseCSOwnedObject(JSObject proxy, bool skipJS) #endregion - #region Legacy - - // legacy - public void RegisterCSOwnedObject(JSObject proxy) - { - lock (this) - { - ThreadCsOwnedObjects[(int)proxy.JSHandle] = new WeakReference(proxy, trackResurrection: true); - } - } - - // legacy - public JSObject? GetCSOwnedObjectByJSHandle(nint jsHandle, int shouldAddInflight) - { - lock (this) - { - if (ThreadCsOwnedObjects.TryGetValue(jsHandle, out WeakReference? reference)) - { - reference.TryGetTarget(out JSObject? jsObject); - if (shouldAddInflight != 0) - { - jsObject?.AddInFlight(); - } - return jsObject; - } - } - return null; - } - - // legacy - public JSObject CreateCSOwnedProxy(nint jsHandle, LegacyHostImplementation.MappedType mappedType, int shouldAddInflight) - { - lock (this) - { - JSObject? res = null; - if (!ThreadCsOwnedObjects.TryGetValue(jsHandle, out WeakReference? reference) || - !reference.TryGetTarget(out res) || - res.IsDisposed) - { -#pragma warning disable CS0612 // Type or member is obsolete - res = mappedType switch - { - LegacyHostImplementation.MappedType.JSObject => new JSObject(jsHandle, JSProxyContext.MainThreadContext), - LegacyHostImplementation.MappedType.Array => new Array(jsHandle), - LegacyHostImplementation.MappedType.ArrayBuffer => new ArrayBuffer(jsHandle), - LegacyHostImplementation.MappedType.DataView => new DataView(jsHandle), - LegacyHostImplementation.MappedType.Function => new Function(jsHandle), - LegacyHostImplementation.MappedType.Uint8Array => new Uint8Array(jsHandle), - _ => throw new ArgumentOutOfRangeException(nameof(mappedType)) - }; -#pragma warning restore CS0612 // Type or member is obsolete - ThreadCsOwnedObjects[jsHandle] = new WeakReference(res, trackResurrection: true); - } - if (shouldAddInflight != 0) - { - res.AddInFlight(); - } - return res; - } - } - - #endregion - #region Dispose private void Dispose(bool disposing) 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 deleted file mode 100644 index 7ce50a8e741f2..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System.Runtime.InteropServices.JavaScript -{ - /// - /// Initializes a new instance of JavaScript Core Array class. - /// - [Obsolete] - public class Array : JSObject - { - /// - /// Initializes a new instance of the Array class. - /// - /// Parameters. - public Array(params object[] _params) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(Array), _params), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - /// - /// Initializes a new instance of the Array/> class. - /// - /// Js handle. - internal Array(IntPtr jsHandle) : base(jsHandle, JSProxyContext.MainThreadContext) - { } - - /// - /// Push the specified elements. - /// - /// The new length of the Array push was called on. - /// Elements. - public int Push(params object[] elements) => (int)this.Invoke("push", elements); - - /// - /// Pop this instance. - /// - /// The element removed from the array or null if the array was empty. - public object Pop() => (object)this.Invoke("pop"); - - /// - /// Remove the first element of the Array and return that element - /// - /// The removed element. - public object Shift() => this.Invoke("shift"); - - /// - /// Add to the array starting at index 0 - /// - /// The length after shift. - /// Elements. - public int UnShift(params object[] elements) => (int)this.Invoke("unshift", elements); - - /// - /// Index of the search element. - /// - /// The index of first occurrence of searchElement in the Array or -1 if not Found. - /// Search element. - /// The index to start the search from. - public int IndexOf(object searchElement, int fromIndex = 0) => (int)this.Invoke("indexOf", searchElement, fromIndex); - - /// - /// Finds the index of the last occurrence of - /// - /// The index of the last occurrence. - /// Search element. - public int LastIndexOf(object searchElement) => (int)this.Invoke("lastIndexOf", searchElement); - - /// - /// Finds the index of the last occurrence of between 0 and . - /// - /// The index of the last occurrence. - /// Search element. - /// End index. - public int LastIndexOf(object searchElement, int endIndex) => (int)this.Invoke("lastIndexOf", searchElement, endIndex); - - /// - /// Gets or sets the Array with the index specified by . - /// - /// The index. - public object this[int i] - { - get - { - this.AssertNotDisposed(); - - Interop.Runtime.GetByIndexRef(JSHandle, i, out int exception, out object indexValue); - - if (exception != 0) - throw new JSException((string)indexValue); - LegacyHostImplementation.ReleaseInFlight(indexValue); - return indexValue; - } - set - { - this.AssertNotDisposed(); - - Interop.Runtime.SetByIndexRef(JSHandle, i, value, out int exception, out object res); - - if (exception != 0) - throw new JSException((string)res); - - } - } - - /// - /// Gets or sets the length. - /// - /// The length. - public int Length - { - get => Convert.ToInt32(this.GetObjectProperty("length")); - set => this.SetObjectProperty("length", value, false); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/ArrayBuffer.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/ArrayBuffer.cs deleted file mode 100644 index 92e78a14fe1b2..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/ArrayBuffer.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices.JavaScript -{ - [Obsolete] - public class ArrayBuffer : JSObject - { - /// - /// Initializes a new instance of the JavaScript Core ArrayBuffer class. - /// - /// Length. - public ArrayBuffer(int length) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(ArrayBuffer), new object[] { length }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - /// - /// Initializes a new instance of the JavaScript Core ArrayBuffer class. - /// - /// Js handle. - internal ArrayBuffer(IntPtr jsHandle) : base(jsHandle, JSProxyContext.MainThreadContext) - { } - - /// - /// The length of an ArrayBuffer in bytes. - /// - /// The length of the underlying ArrayBuffer in bytes. - public int ByteLength => (int)this.GetObjectProperty("byteLength"); - - /// - /// Gets a value indicating whether this ArrayBuffer is view. - /// - /// if is view; otherwise, . - public bool IsView => (bool)this.GetObjectProperty("isView"); - - /// - /// Slice the specified begin. - /// - /// The slice. - /// Begin. - public ArrayBuffer Slice(int begin) => (ArrayBuffer)this.Invoke("slice", begin); - - /// - /// Slice the specified begin and end. - /// - /// The slice. - /// Begin. - /// End. - public ArrayBuffer Slice(int begin, int end) => (ArrayBuffer)this.Invoke("slice", begin, end); - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/DataView.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/DataView.cs deleted file mode 100644 index 1046fa8f99fa4..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/DataView.cs +++ /dev/null @@ -1,233 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices.JavaScript -{ - /// - /// The DataView view provides a low-level interface for reading and writing multiple number types in a - /// binary ArrayBuffer, without having to care about the platform's endianness. - /// - [Obsolete] - public class DataView : JSObject - { - /// - /// Initializes a new instance of the DataView class. - /// - /// ArrayBuffer to use as the storage backing the new DataView object. - public DataView(ArrayBuffer buffer) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(DataView), new object[] { buffer }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - /// - /// Initializes a new instance of the DataView class. - /// - /// ArrayBuffer to use as the storage backing the new DataView object. - /// The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte. - public DataView(ArrayBuffer buffer, int byteOffset) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(DataView), new object[] { buffer, byteOffset }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - /// - /// Initializes a new instance of the DataView class. - /// - /// ArrayBuffer to use as the storage backing the new DataView object. - /// The offset, in bytes, to the first byte in the above buffer for the new view to reference. If unspecified, the buffer view starts with the first byte. - /// The number of elements in the byte array. If unspecified, the view's length will match the buffer's length. - public DataView(ArrayBuffer buffer, int byteOffset, int byteLength) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(DataView), new object[] { buffer, byteOffset, byteLength }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - /// - /// Initializes a new instance of the DataView class. - /// - /// Js handle. - internal DataView(IntPtr jsHandle) : base(jsHandle, JSProxyContext.MainThreadContext) - { } - - /// - /// Gets the length (in bytes) of this view from the start of its ArrayBuffer. Fixed at construction time and thus read only. - /// - /// The length (in bytes) of this view. - public int ByteLength => (int)this.GetObjectProperty("byteLength"); - - /// - /// Gets the offset (in bytes) of this view from the start of its ArrayBuffer. Fixed at construction time and thus read only. - /// - /// The offset (in bytes) of this view. - public int ByteOffset => (int)this.GetObjectProperty("byteOffset"); - - /// - /// Gets the ArrayBuffer referenced by this view. Fixed at construction time and thus read only. - /// - /// The ArrayBuffer. - public ArrayBuffer Buffer => (ArrayBuffer)this.GetObjectProperty("buffer"); - - /// - /// Gets the signed 32-bit float (float) at the specified byte offset from the start of the DataView. - /// - /// A signed 32-bit float number. - /// Byte offset. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public float GetFloat32(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getFloat32", byteOffset, littleEndian)); - - /// - /// Gets the signed 64-bit double (double) at the specified byte offset from the start of the DataView. - /// - /// A signed 64-bit coulbe number. - /// Byte offset. - /// Indicates whether the 64-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public double GetFloat64(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getFloat64", byteOffset, littleEndian)); - - /// - /// Gets the signed 16-bit integer (short) at the specified byte offset from the start of the DataView. - /// - /// A signed 16-bit ineger (short) number. - /// Byte offset. - /// Indicates whether the 16-bit integer (short) is stored in little- or big-endian format. If false, a big-endian value is read. - public short GetInt16(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getInt16", byteOffset, littleEndian)); - - /// - /// Gets the signed 32-bit integer (int) at the specified byte offset from the start of the DataView. - /// - /// A signed 32-bit ineger (int) number. - /// Byte offset. - /// Indicates whether the 32-bit integer (int) is stored in little- or big-endian format. If false, a big-endian value is read. - public int GetInt32(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getInt32", byteOffset, littleEndian)); - - /// - /// Gets the signed 8-bit byte (sbyte) at the specified byte offset from the start of the DataView. - /// - /// A signed 8-bit byte (sbyte) number. - /// Byte offset. - /// Indicates whether the 8-bit byte is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public sbyte GetInt8(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getInt8", byteOffset, littleEndian)); - - /// - /// Gets the unsigned 16-bit integer (short) at the specified byte offset from the start of the DataView. - /// - /// A unsigned 16-bit integer (ushort) number. - /// Byte offset. - /// Indicates whether the unsigned 16-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public ushort GetUint16(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getUint16", byteOffset, littleEndian)); - - /// - /// Gets the usigned 32-bit integer (uint) at the specified byte offset from the start of the DataView. - /// - /// A usigned 32-bit ineger (uint) number. - /// Byte offset. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public uint GetUint32(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getUint32", byteOffset, littleEndian)); - - /// - /// Gets the unsigned 8-bit byte (byte) at the specified byte offset from the start of the DataView. - /// - /// A unsigned 8-bit byte (byte) number. - /// Byte offset. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public byte GetUint8(int byteOffset, bool littleEndian = false) => UnBoxValue(this.Invoke("getUint8", byteOffset, littleEndian)); - - /// - /// Sets the signed 32-bit float (float) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// float value. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public void SetFloat32(int byteOffset, float value, bool littleEndian = false) => this.Invoke("setFloat32", byteOffset, value, littleEndian); - - /// - /// Sets the signed 64-bit double (double) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// double value. - /// Indicates whether the 64-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public void SetFloat64(int byteOffset, double value, bool littleEndian = false) => this.Invoke("setFloat64", byteOffset, value, littleEndian); - - /// - /// Sets the signed 16-bit integer (short) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// short value. - /// Indicates whether the 16-bit integer (short) is stored in little- or big-endian format. If false, a big-endian value is read. - public void SetInt16(int byteOffset, short value, bool littleEndian = false) => this.Invoke("setInt16", byteOffset, value, littleEndian); - - /// - /// Sets the signed 32-bit integer (int) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// int value. - /// Indicates whether the 32-bit integer (int) is stored in little- or big-endian format. If false, a big-endian value is read. - public void SetInt32(int byteOffset, int value, bool littleEndian = false) => this.Invoke("setInt32", byteOffset, value, littleEndian); - - /// - /// Sets the signed 8-bit byte (sbyte) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// sbyte value. - /// Indicates whether the 8-bit byte is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public void SetInt8(int byteOffset, sbyte value, bool littleEndian = false) => this.Invoke("setInt8", byteOffset, value, littleEndian); - - /// - /// Sets the unsigned 16-bit integer (short) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// ushort value. - /// Indicates whether the unsigned 16-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public void SetUint16(int byteOffset, ushort value, bool littleEndian = false) => this.Invoke("setUint16", byteOffset, value, littleEndian); - - /// - /// Sets the usigned 32-bit integer (uint) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// uint value. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - [CLSCompliant(false)] - public void SetUint32(int byteOffset, uint value, bool littleEndian = false) => this.Invoke("setUint32", byteOffset, value, littleEndian); - - /// - /// Sets the unsigned 8-bit byte (sbyte) at the specified byte offset from the start of the DataView. - /// - /// Byte offset. - /// byte value. - /// Indicates whether the 32-bit float is stored in little- or big-endian format. If false, a big-endian value is read. - public void SetUint8(int byteOffset, byte value, bool littleEndian = false) => this.Invoke("setUint8", byteOffset, value, littleEndian); - - private static U UnBoxValue(object jsValue) where U : struct - { - if (jsValue == null) - { - throw new InvalidCastException(SR.Format(SR.UnableCastNullToType, typeof(U))); - } - - var type = jsValue.GetType(); - if (type.IsPrimitive) - { - return (U)Convert.ChangeType(jsValue, typeof(U)); - } - else - { - throw new InvalidCastException(SR.Format(SR.UnableCastObjectToType, type, typeof(U))); - } - } - - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Function.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Function.cs deleted file mode 100644 index ebce83d01417a..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Function.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.InteropServices.JavaScript -{ - /// - /// The Function constructor creates a new Function object. - /// - /// - /// Calling the constructor directly can create functions dynamically, but suffers from security and similar - /// (but far less significant) performance issues similar to eval. However, unlike eval, the Function constructor - /// allows executing code in the global scope, prompting better programming habits and allowing for more efficient - /// code minification. - /// - [Obsolete] - public class Function : JSObject - { - public Function(params object[] args) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(Function), args), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - internal Function(IntPtr jsHandle) : base(jsHandle, JSProxyContext.MainThreadContext) - { } - - /// - /// The Apply() method calls a function with a given this value, and arguments provided as an array (or an array-like object). - /// - /// The apply. - /// This argument. - /// Arguments. - public object Apply(object? thisArg, object[]? argsArray = null) => this.Invoke("apply", thisArg, argsArray); - - /// - /// Creates a new Function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. - /// - /// The bind. - /// This argument. - /// Arguments. - public Function Bind(object? thisArg, object[]? argsArray = null) => (Function)this.Invoke("bind", thisArg, argsArray); - - /// - /// Calls a function with a given `this` value and arguments provided individually. - /// - /// The result of calling the function with the specified `this` value and arguments. - /// Optional (null value). The value of this provided for the call to a function. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode, null and undefined will be replaced with the global object and primitive values will be converted to objects. - /// Optional. Arguments for the function. - public object Call(object? thisArg, params object[] argsArray) - { - object?[] argsList = new object[argsArray.Length + 1]; - argsList[0] = thisArg; - System.Array.Copy(argsArray, 0, argsList, 1, argsArray.Length); - return this.Invoke("call", argsList); - } - - /// - /// Calls a function with a null `this` value. - /// - /// The result of calling the function. - public object Call() => Call(null); - } -} 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 deleted file mode 100644 index c0503f449fd41..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs +++ /dev/null @@ -1,226 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; -using System.Runtime.Versioning; -using System.Threading; -using System.Threading.Tasks; - -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(); - } - - public static MarshalType GetMarshalTypeFromType(Type type) - { - if (type is null) - return MarshalType.VOID; - - var typeCode = Type.GetTypeCode(type); - if (type.IsEnum) - { - switch (typeCode) - { - case TypeCode.Int32: - case TypeCode.UInt32: - return MarshalType.ENUM; - case TypeCode.Int64: - case TypeCode.UInt64: - return MarshalType.ENUM64; - default: - throw new ArgumentException(SR.Format(SR.UnsupportedEnumType, type.FullName), nameof(type)); - } - } - - switch (typeCode) - { - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.Int32: - return MarshalType.INT; - case TypeCode.Byte: - case TypeCode.UInt16: - case TypeCode.UInt32: - return MarshalType.UINT32; - case TypeCode.Boolean: - return MarshalType.BOOL; - case TypeCode.Int64: - return MarshalType.INT64; - case TypeCode.UInt64: - return MarshalType.UINT64; - case TypeCode.Single: - return MarshalType.FP32; - case TypeCode.Double: - return MarshalType.FP64; - case TypeCode.String: - return MarshalType.STRING; - case TypeCode.Char: - return MarshalType.CHAR; - } - - if (type.IsArray) - { - if (!type.IsSZArray) - throw new ArgumentException(SR.Format(SR.UnsupportedArrayType, type.FullName), nameof(type)); - - var elementType = type.GetElementType(); - switch (Type.GetTypeCode(elementType)) - { - case TypeCode.Byte: - return MarshalType.ARRAY_UBYTE; - case TypeCode.SByte: - return MarshalType.ARRAY_BYTE; - case TypeCode.Int16: - return MarshalType.ARRAY_SHORT; - case TypeCode.UInt16: - return MarshalType.ARRAY_USHORT; - case TypeCode.Int32: - return MarshalType.ARRAY_INT; - case TypeCode.UInt32: - return MarshalType.ARRAY_UINT; - case TypeCode.Single: - return MarshalType.ARRAY_FLOAT; - case TypeCode.Double: - return MarshalType.ARRAY_DOUBLE; - default: - throw new ArgumentException(SR.Format(SR.UnsupportedElementType, elementType), nameof(type)); - } - } - else if (type == typeof(IntPtr)) - return MarshalType.POINTER; - else if (type == typeof(UIntPtr)) - return MarshalType.POINTER; - else if (type == typeof(SafeHandle)) - return MarshalType.SAFEHANDLE; - else if (typeof(Delegate).IsAssignableFrom(type)) - return MarshalType.DELEGATE; - else if ((type == typeof(Task)) || typeof(Task).IsAssignableFrom(type)) - return MarshalType.TASK; - else if (type.FullName == "System.Uri") - return MarshalType.URI; - else if (type.IsPointer) - return MarshalType.POINTER; - - if (type.IsValueType) - return MarshalType.VT; - else - return MarshalType.OBJECT; - } - - public static char GetCallSignatureCharacterForMarshalType(MarshalType type, char? defaultValue) - { - switch (type) - { - case MarshalType.BOOL: - return 'b'; - case MarshalType.UINT32: - case MarshalType.POINTER: - return 'I'; - case MarshalType.INT: - return 'i'; - case MarshalType.UINT64: - return 'L'; - case MarshalType.INT64: - return 'l'; - case MarshalType.FP32: - return 'f'; - case MarshalType.FP64: - return 'd'; - case MarshalType.STRING: - return 's'; - case MarshalType.URI: - return 'u'; - case MarshalType.SAFEHANDLE: - return 'h'; - case MarshalType.ENUM: - return 'j'; // this is wrong for uint enums - case MarshalType.ENUM64: - return 'k'; // this is wrong for ulong enums - case MarshalType.TASK: - case MarshalType.DELEGATE: - case MarshalType.OBJECT: - return 'o'; - case MarshalType.VT: - return 'a'; - default: - if (defaultValue.HasValue) - return defaultValue.Value; - else - throw new ArgumentException(SR.Format(SR.UnsupportedLegacyMarshlerType, type), nameof(type)); - } - } - - // see src/mono/wasm/driver.c MARSHAL_TYPE_xxx - public enum MarshalType : int - { - NULL = 0, - INT = 1, - FP64 = 2, - STRING = 3, - VT = 4, - DELEGATE = 5, - TASK = 6, - OBJECT = 7, - BOOL = 8, - ENUM = 9, - URI = 22, - SAFEHANDLE = 23, - ARRAY_BYTE = 10, - ARRAY_UBYTE = 11, - ARRAY_UBYTE_C = 12, - ARRAY_SHORT = 13, - ARRAY_USHORT = 14, - ARRAY_INT = 15, - ARRAY_UINT = 16, - ARRAY_FLOAT = 17, - ARRAY_DOUBLE = 18, - FP32 = 24, - UINT32 = 25, - INT64 = 26, - UINT64 = 27, - CHAR = 28, - STRING_INTERNED = 29, - VOID = 30, - ENUM64 = 31, - POINTER = 32 - } - - // see src/mono/wasm/driver.c MARSHAL_ERROR_xxx - public enum MarshalError : int - { - BUFFER_TOO_SMALL = 512, - NULL_CLASS_POINTER = 513, - NULL_TYPE_POINTER = 514, - UNSUPPORTED_TYPE = 515, - FIRST = BUFFER_TOO_SMALL - } - - // please keep BINDING wasm_type_symbol in sync - public enum MappedType - { - JSObject = 0, - Array = 1, - ArrayBuffer = 2, - DataView = 3, - Function = 4, - Uint8Array = 11, - } - -#if FEATURE_WASM_THREADS - public static void ThrowIfLegacyWorkerThread() - { - if (Environment.CurrentManagedThreadId != 1) - { - throw new PlatformNotSupportedException("Legacy interop is not supported with WebAssembly threads."); - } - } -#endif - } -} 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 deleted file mode 100644 index 81535a162d51c..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - -namespace System.Runtime.InteropServices.JavaScript -{ - [Obsolete] - public static class Runtime - { - public static object GetGlobalObject(string str) - => JavaScriptImports.GetGlobalObject(str); - - /// - /// Invoke a named method of the object, or throws a JSException on error. - /// - /// thisArg - /// The name of the method to invoke. - /// The argument list to pass to the invoke command. - /// - /// - /// The return value can either be a primitive (string, int, double), a JSObject for JavaScript objects, a - /// System.Threading.Tasks.Task(object) for JavaScript promises, an array of - /// a byte, int or double (for Javascript objects typed as ArrayBuffer) or a - /// System.Func to represent JavaScript functions. The specific version of - /// the Func that will be returned depends on the parameters of the Javascript function - /// and return value. - /// - /// - /// The value of a returned promise (The Task(object) return) can in turn be any of the above - /// valuews. - /// - /// - public static object Invoke(this JSObject self, string method, params object?[] args) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - ArgumentNullException.ThrowIfNull(self); - self.AssertNotDisposed(); - Interop.Runtime.InvokeJSWithArgsRef(self.JSHandle, method, args, out int exception, out object res); - if (exception != 0) - throw new JSException((string)res); - LegacyHostImplementation.ReleaseInFlight(res); - return res; - } - - /// - /// Returns the named property from the object, or throws a JSException on error. - /// - /// thisArg - /// The name of the property to lookup. - /// - /// This method can raise a JSException if fetching the property in Javascript raises an exception. - /// - /// - /// - /// The return value can either be a primitive (string, int, double), a - /// JSObject for JavaScript objects, a - /// System.Threading.Tasks.Task (object) for JavaScript promises, an array of - /// a byte, int or double (for Javascript objects typed as ArrayBuffer) or a - /// System.Func to represent JavaScript functions. The specific version of - /// the Func that will be returned depends on the parameters of the Javascript function - /// and return value. - /// - /// - /// The value of a returned promise (The Task(object) return) can in turn be any of the above - /// valuews. - /// - /// - public static object GetObjectProperty(this JSObject self, string name) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - ArgumentNullException.ThrowIfNull(self); - self.AssertNotDisposed(); - - Interop.Runtime.GetObjectPropertyRef(self.JSHandle, name, out int exception, out object propertyValue); - if (exception != 0) - throw new JSException((string)propertyValue); - LegacyHostImplementation.ReleaseInFlight(propertyValue); - return propertyValue; - } - - /// - /// Sets the named property to the provided value. - /// - /// - /// - /// thisArg - /// The name of the property to lookup. - /// The value can be a primitive type (int, double, string, bool), an - /// array that will be surfaced as a typed ArrayBuffer (byte[], sbyte[], short[], ushort[], - /// float[], double[]) - /// Defaults to and creates the property on the javascript object if not found, if set to it will not create the property if it does not exist. If the property exists, the value is updated with the provided value. - /// - public static void SetObjectProperty(this JSObject self, string name, object? value, bool createIfNotExists = true, bool hasOwnProperty = false) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - ArgumentNullException.ThrowIfNull(self); - self.AssertNotDisposed(); - - Interop.Runtime.SetObjectPropertyRef(self.JSHandle, name, in value, createIfNotExists, hasOwnProperty, out int exception, out object res); - if (exception != 0) - throw new JSException(SR.Format(SR.ErrorLegacySettingProperty, name, self.JSHandle, res)); - } - - public static void AssertInFlight(this JSObject self, int expectedInFlightCount) - { - if (self.InFlightCounter != expectedInFlightCount) throw new InvalidOperationException(SR.Format(SR.UnsupportedLegacyMarshlerType, self.JSHandle, expectedInFlightCount, self.InFlightCounter)); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Uint8Array.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Uint8Array.cs deleted file mode 100644 index 1cea722c1cc62..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Uint8Array.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; - -namespace System.Runtime.InteropServices.JavaScript -{ - [Obsolete] - public sealed class Uint8Array : JSObject - { - public Uint8Array(int length) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(Uint8Array), new object[] { length }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - public Uint8Array(ArrayBuffer buffer) - : base(JavaScriptImports.CreateCSOwnedObject(nameof(Uint8Array), new object[] { buffer }), JSProxyContext.MainThreadContext) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - JSProxyContext.MainThreadContext.RegisterCSOwnedObject(this); - } - - internal Uint8Array(IntPtr jsHandle) : base(jsHandle, JSProxyContext.MainThreadContext) - { } - - public int Length - { - get => Convert.ToInt32(this.GetObjectProperty("length")); - set => this.SetObjectProperty("length", value, false); - } - - /// - /// Defines an implicit conversion of JavaScript Core Uint8Array class to a Span<byte> - /// - public static implicit operator Span(Uint8Array typedarray) => typedarray.ToArray(); - - public static implicit operator Uint8Array(Span span) => From(span); - - public byte[] ToArray() - { - this.AssertNotDisposed(); - - Interop.Runtime.TypedArrayToArrayRef(JSHandle, out int exception, out object res); - - if (exception != 0) - throw new JSException((string)res); - return (byte[])res; - } - - public static unsafe Uint8Array From(ReadOnlySpan span) - { -#if FEATURE_WASM_THREADS - LegacyHostImplementation.ThrowIfLegacyWorkerThread(); -#endif - // source has to be instantiated. - if (span == null) - { - throw new System.ArgumentException(SR.Format(SR.ArgumentCannotBeNull, nameof(span)), nameof(span)); - } - - ReadOnlySpan bytes = MemoryMarshal.AsBytes(span); - fixed (byte* ptr = bytes) - { - Interop.Runtime.TypedArrayFromRef((int)ptr, 0, span.Length, sizeof(byte), (int)TypedArrayTypeCode.Uint8Array, out int exception, out object res); - if (exception != 0) - throw new JSException((string)res); - var r = (Uint8Array)res; - r.ReleaseInFlight(); - return r; - } - } - - public enum TypedArrayTypeCode - { - Uint8Array = 6, - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj deleted file mode 100644 index a46f95dde5a92..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.Tests.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - true - $(NetCoreAppCurrent)-browser - true - $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop - 0612 - true - $(DefineConstants);DISABLE_LEGACY_JS_INTEROP - WasmTestOnBrowser - - <_XUnitBackgroundExec>false - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs deleted file mode 100644 index ae247a1bb2f63..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ArrayTests.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class ArrayTests - { - [Fact] - public static void ArrayLength() - { - Array d = new Array(); - Assert.Equal(0, d.Length); - } - - [Fact] - public static void ArrayLength1() - { - Array d = new Array(50); - Assert.Equal(50, d.Length); - } - - [Fact] - public static void Array_GetSetItem() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - IList iList = new int[] { 7, 8, 9, 10, 11, 12, 13 }; - - Assert.Equal(jsArray.Length, iList.Count); - for (int i = 0; i < iList.Count; i++) - { - Assert.Equal(jsArray[i], iList[i]); - - iList[i] = 99; - jsArray[i] = 99; - Assert.Equal(99, iList[i]); - Assert.Equal(99, jsArray[i]); - } - } - - [Fact] - public static void Array_GetSetItemInvalid() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Null(jsArray[-1]); - Assert.Null(jsArray[jsArray.Length]); - Assert.Equal(0, jsArray[-1] = 0); - Assert.Equal(0, jsArray[jsArray.Length] = 0); - } - - [Fact] - public static void Array_GetItemIndex() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Equal(7, jsArray[0]); - Assert.Equal(8, jsArray[1]); - Assert.Equal(9, jsArray[2]); - Assert.Equal(10, jsArray[3]); - Assert.Equal(11, jsArray[4]); - Assert.Equal(12, jsArray[5]); - Assert.Equal(13, jsArray[6]); - } - - [Fact] - public static void Array_GetSetItemIndex() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - for (int d = 0; d < jsArray.Length; d++) - { - jsArray[d] = (int)jsArray[d] + 1; - } - Assert.Equal(8, jsArray[0]); - Assert.Equal(9, jsArray[1]); - Assert.Equal(10, jsArray[2]); - Assert.Equal(11, jsArray[3]); - Assert.Equal(12, jsArray[4]); - Assert.Equal(13, jsArray[5]); - Assert.Equal(14, jsArray[6]); - } - - [Fact] - public static void Array_Pop() - { - var jsArray = new Array(7, 8, 9, 10, 11, 12, 13); - Assert.Equal(13, jsArray.Pop()); - Assert.Equal(12, jsArray.Pop()); - Assert.Equal(11, jsArray.Pop()); - Assert.Equal(10, jsArray.Pop()); - Assert.Equal(9, jsArray.Pop()); - Assert.Equal(8, jsArray.Pop()); - Assert.Equal(7, jsArray.Pop()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_PushPop() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - jsArray.Push(objArray[d]); - } - Assert.Equal("test13", jsArray.Pop()); - Assert.Equal("test12", jsArray.Pop()); - Assert.Equal("test11", jsArray.Pop()); - Assert.Equal("test10", jsArray.Pop()); - Assert.Equal("test9", jsArray.Pop()); - Assert.Equal("test8", jsArray.Pop()); - Assert.Equal("test7", jsArray.Pop()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_PushShift() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - jsArray.Push(objArray[d]); - } - Assert.Equal("test7", jsArray.Shift()); - Assert.Equal("test8", jsArray.Shift()); - Assert.Equal("test9", jsArray.Shift()); - Assert.Equal("test10", jsArray.Shift()); - Assert.Equal("test11", jsArray.Shift()); - Assert.Equal("test12", jsArray.Shift()); - Assert.Equal("test13", jsArray.Shift()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_UnShiftShift() - { - var objArray = new object[] { "test7", "test8", "test9", "test10", "test11", "test12", "test13" }; - var jsArray = new Array(); - for (int d = 0; d < objArray.Length; d++) - { - Assert.Equal(d + 1, jsArray.UnShift(objArray[d])); - } - Assert.Equal("test13", jsArray.Shift()); - Assert.Equal("test12", jsArray.Shift()); - Assert.Equal("test11", jsArray.Shift()); - Assert.Equal("test10", jsArray.Shift()); - Assert.Equal("test9", jsArray.Shift()); - Assert.Equal("test8", jsArray.Shift()); - Assert.Equal("test7", jsArray.Shift()); - Assert.Equal(0, jsArray.Length); - } - - [Fact] - public static void Array_IndexOf() - { - var beasts = new Array("ant", "bison", "camel", "duck", "bison"); - Assert.Equal(1, beasts.IndexOf("bison")); - Assert.Equal(4, beasts.IndexOf("bison", 2)); - Assert.Equal(-1, beasts.IndexOf("giraffe")); - } - - [Fact] - public static void Array_LastIndexOf() - { - var beasts = new Array("Dodo", "Tiger", "Penguin", "Dodo"); - Assert.Equal(3, beasts.LastIndexOf("Dodo")); - Assert.Equal(1, beasts.LastIndexOf("Tiger")); - Assert.Equal(0, beasts.LastIndexOf("Dodo", 2)); // The array is searched backwards - Assert.Equal(-1, beasts.LastIndexOf("giraffe")); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs deleted file mode 100644 index 4e06bf20f005a..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DataViewTests.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class DataViewTests - { - [Fact] - public static void DataViewConstructor() - { - // create an ArrayBuffer with a size in bytes - var buffer = new ArrayBuffer(16); - - // Create a couple of views - var view1 = new DataView(buffer); - var view2 = new DataView(buffer, 12, 4); //from byte 12 for the next 4 bytes - view1.SetInt8(12, 42); // put 42 in slot 12 - - Assert.Equal(42, view2.GetInt8(0)); - } - - public static IEnumerable ArrayBuffer_Test_Data() - { - yield return new object[] { new ArrayBuffer(12) }; - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewArrayBuffer(ArrayBuffer buffer) - { - var x = new DataView(buffer); - Assert.True(buffer == x.Buffer); - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewByteLength(ArrayBuffer buffer) - { - var x = new DataView(buffer, 4, 2); - Assert.Equal(2, x.ByteLength); - } - - [Theory] - [MemberData(nameof(ArrayBuffer_Test_Data))] - public static void DataViewByteOffset(ArrayBuffer buffer) - { - var x = new DataView(buffer, 4, 2); - Assert.Equal(4, x.ByteOffset); - } - - public static IEnumerable DataView_Test_Data() - { - yield return new object[] { new DataView(new ArrayBuffer(12), 0) }; - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - - public static void DataViewGetFloat32(DataView view) - { - view.SetFloat32(1, (float)Math.PI); - Assert.Equal((float)Math.Round(Math.PI, 5), (float)Math.Round(view.GetFloat32(1), 5)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetFloat64(DataView view) - { - view.SetFloat64(1, (float)Math.PI); - Assert.Equal(Math.Round(Math.PI, 5), Math.Round(view.GetFloat64(1), 5)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt16(DataView view) - { - view.SetInt16(1, 1234); - Assert.Equal(1234, view.GetInt16(1)); - - view.SetInt16(1, -1234); - Assert.Equal(-1234, view.GetInt16(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt32(DataView view) - { - view.SetInt32(1, 1234); - Assert.Equal(1234, view.GetInt32(1)); - - view.SetInt32(1, -1234); - Assert.Equal(-1234, view.GetInt32(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetInt8(DataView view) - { - view.SetInt8(1, 123); - Assert.Equal(123, view.GetInt8(1)); - - view.SetInt8(1, -123); - Assert.Equal(-123, view.GetInt8(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint16(DataView view) - { - view.SetUint16(1, 1234); - Assert.Equal(1234, view.GetUint16(1)); - - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint32(DataView view) - { - view.SetUint32(1, 1234); - Assert.Equal(1234u, view.GetUint32(1)); - } - - [Theory] - [MemberData(nameof(DataView_Test_Data))] - public static void DataViewGetUint8(DataView view) - { - view.SetUint8(1, 123); - Assert.Equal(123u, view.GetUint8(1)); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs deleted file mode 100644 index f5a49b0ef4c4b..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/DelegateTests.cs +++ /dev/null @@ -1,449 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Threading.Tasks; -using Xunit; -using System.Runtime.InteropServices.JavaScript; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class DelegateTests - { - private static Function _objectPrototype; - - [Fact] - public static void InvokeFunction() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - - Utils.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(30, HelperMarshal._functionResultValue); - Assert.Equal(60, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeFunctionInLoopUsingConstanceValues() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - - Utils.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - for (let x = 0; x < 1000; x++) - { - res = funcDelegate (10, 20); - } - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(30, HelperMarshal._functionResultValue); - Assert.Equal(60, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeFunctionInLoopUsingIncrementedValues() - { - HelperMarshal._functionResultValue = 0; - HelperMarshal._i32Value = 0; - Utils.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegate"", [ ]); - var res = funcDelegate (10, 20); - for (let x = 0; x < 1000; x++) - { - res = funcDelegate (x, x); - } - App.call_test_method (""InvokeI32"", [ res, res ]); - "); - - Assert.Equal(1998, HelperMarshal._functionResultValue); - Assert.Equal(3996, HelperMarshal._i32Value); - } - - [Fact] - public static void InvokeActionTReturnedByInvokingFuncT() - { - HelperMarshal._functionActionResultValue = 0; - HelperMarshal._functionActionResultValueOfAction = 0; - - Utils.InvokeJS(@" - var funcDelegate = App.call_test_method (""CreateFunctionDelegateWithAction"", [ ]); - var actionDelegate = funcDelegate (10, 20); - actionDelegate(30,40); - "); - - Assert.Equal(30, HelperMarshal._functionActionResultValue); - Assert.Equal(70, HelperMarshal._functionActionResultValueOfAction); - } - - [Fact] - public static void InvokeActionIntInt() - { - HelperMarshal._actionResultValue = 0; - - Utils.InvokeJS(@" - var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); - actionDelegate(30,40); - "); - - Assert.Equal(70, HelperMarshal._actionResultValue); - } - - [Fact] - public static void InvokeActionFloatIntToIntInt() - { - HelperMarshal._actionResultValue = 0; - var ex = Assert.Throws(()=>Utils.InvokeJS(@" - var actionDelegate = App.call_test_method (""CreateActionDelegate"", [ ]); - actionDelegate(3.14,40); - ")); - - Assert.Contains("Value is not an integer: 3.14 (number)", ex.Message); - Assert.Equal(0, HelperMarshal._actionResultValue); - } - - [Fact] - public static void InvokeDelegateMethod() - { - HelperMarshal._delMethodResultValue = string.Empty; - Utils.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateMethod"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Hic sunt dracones", HelperMarshal._delMethodResultValue); - } - - [Fact] - public static void InvokeDelegateMethodReturnString() - { - HelperMarshal._delMethodStringResultValue = string.Empty; - Utils.InvokeJS(@" - var del = App.call_test_method (""CreateDelegateMethodReturnString"", [ ]); - var res = del(""Hic sunt dracones""); - App.call_test_method (""SetTestString1"", [ res ]); - "); - - Assert.Equal("Received: Hic sunt dracones", HelperMarshal._delMethodStringResultValue); - } - - [Theory] - [InlineData("CreateCustomMultiCastDelegate_VoidString", "Moin")] - [InlineData("CreateMultiCastAction_VoidString", "MoinMoin")] - public static void InvokeMultiCastDelegate_VoidString(string creator, string testStr) - { - HelperMarshal._delegateCallResult = string.Empty; - Utils.InvokeJS($@" - var del = App.call_test_method (""{creator}"", [ ]); - del(""{testStr}""); - "); - Assert.Equal($" Hello, {testStr}! GoodMorning, {testStr}!", HelperMarshal._delegateCallResult); - } - - [Theory] - [InlineData("CreateDelegateFromAnonymousMethod_VoidString")] - [InlineData("CreateDelegateFromLambda_VoidString")] - [InlineData("CreateDelegateFromMethod_VoidString")] - [InlineData("CreateActionT_VoidString")] - public static void InvokeDelegate_VoidString(string creator) - { - HelperMarshal._delegateCallResult = string.Empty; - var s = Utils.InvokeJS($@" - var del = App.call_test_method (""{creator}"", [ ]); - del(""Hic sunt dracones""); - "); - - Assert.Equal("Notification received for: Hic sunt dracones", HelperMarshal._delegateCallResult); - } - - public static IEnumerable ArrayType_TestData() - { - _objectPrototype ??= new Function("return Object.prototype.toString;"); - yield return new object[] { _objectPrototype.Call(), "Uint8Array", Uint8Array.From(new byte[10]) }; - yield return new object[] { _objectPrototype.Call(), "Array", new Array(10) }; - } - - [Theory] - [MemberData(nameof(ArrayType_TestData))] - public static void InvokeFunctionAcceptingArrayTypes(Function objectPrototype, string creator, JSObject arrayType) - { - HelperMarshal._funcActionBufferObjectResultValue = arrayType; - Assert.Equal(10, HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length")); - Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); - - Utils.InvokeJS($@" - var buffer = new {creator}(50); - var del = App.call_test_method (""CreateFunctionAccepting{creator}"", [ ]); - var setAction = del(buffer); - setAction(buffer); - "); - - Assert.Equal(50, HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length")); - Assert.Equal(HelperMarshal._funcActionBufferObjectResultValue.GetObjectProperty("length"), HelperMarshal._funcActionBufferResultLengthValue); - Assert.Equal($"[object {creator}]", objectPrototype.Call(HelperMarshal._funcActionBufferObjectResultValue)); - } - - [Fact] - public static void DispatchToDelegate() - { - var factory = new Function(@"return { - callback: null, - eventFactory:function(data){ - return { - data:data - }; - }, - fireEvent: function (evt) { - this.callback(evt); - } - };"); - var dispatcher = (JSObject)factory.Call(); - var temp = new bool[2]; - Action cb = (JSObject envt) => - { - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }; - dispatcher.SetObjectProperty("callback", cb); - var evnt0 = dispatcher.Invoke("eventFactory", 0); - var evnt1 = dispatcher.Invoke("eventFactory", 1); - dispatcher.Invoke("fireEvent", evnt0); - dispatcher.Invoke("fireEvent", evnt0); - dispatcher.Invoke("fireEvent", evnt1); - Assert.True(temp[0]); - Assert.True(temp[1]); - } - - [Fact] - public static void EventsAreNotCollected() - { - const int attempts = 100; // we fire 100 events in a loop, to try that it's GC same - var factory = new Function(@"return { - callback: null, - eventFactory:function(data){ - return { - data:data - }; - }, - fireEvent: function (evt) { - this.callback(evt); - } - };"); - var dispatcher = (JSObject)factory.Call(); - var temp = new bool[attempts]; - Action cb = (JSObject envt) => - { - ObjectDisposedException.ThrowIf(envt.IsDisposed, envt); - envt.AssertInFlight(0); - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }; - dispatcher.SetObjectProperty("callback", cb); - - var evnt = dispatcher.Invoke("eventFactory", 0); - for (int i = 0; i < attempts; i++) - { - var evnti = dispatcher.Invoke("eventFactory", i); - dispatcher.Invoke("fireEvent", evnti); - dispatcher.Invoke("fireEvent", evnt); - Utils.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - } - } - - - [Fact] - public static void NullDelegate() - { - var factory = new Function("delegate", "callback", @" - callback(delegate); - "); - - Delegate check = null; - Action callback = (Delegate data) => - { - check = data; - }; - factory.Call(null, null, callback); - Assert.Null(check); - } - - [Fact] - public static async Task ResolveStringPromise() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve('foo'); - }, 10); - });"); - - var promise = (Task)factory.Call(); - var value = await promise; - - Assert.Equal("foo", (string)value); - - } - - [Fact] - public static async Task ResolveJSObjectPromise() - { - for (int i = 0; i < 10; i++) - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - resolve({foo:'bar'}); - }, 10); - });"); - - var promise = (Task)factory.Call(); - var value = (JSObject)await promise; - - Assert.Equal("bar", value.GetObjectProperty("foo")); - Utils.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - } - } - - [Fact] - public static async Task RejectPromise() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - reject('fail'); - }, 10); - });"); - - var promise = (Task)factory.Call(); - - var ex = await Assert.ThrowsAsync(async () => await promise); - Assert.Equal("fail", ex.Message); - } - - [Fact] - public static async Task RejectPromiseError() - { - var factory = new Function(@" - return new Promise((resolve, reject) => { - setTimeout(() => { - reject(new Error('fail')); - }, 10); - });"); - - var promise = (Task)factory.Call(); - - var ex = await Assert.ThrowsAsync(async () => await promise); - Assert.Equal("Error: fail", ex.Message); - } - - - [ActiveIssue("https://github.com/dotnet/runtime/issues/56963")] - [Fact] - public static void RoundtripPromise() - { - var factory = new Function(@" - var dummy=new Promise((resolve, reject) => {}); - return { - dummy:dummy, - check:(promise)=>{ - return promise===dummy ? 1:0; - } - }"); - - var obj = (JSObject)factory.Call(); - var dummy = obj.GetObjectProperty("dummy"); - Assert.IsType>(dummy); - var check = obj.Invoke("check", dummy); - Assert.Equal(1, check); - } - - - [Fact] - public static async Task ResolveTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - return task.then((data)=>{ - callback(data); - }) - "); - - int check = 0; - Action callback = (int data) => - { - check = data; - }; - Task task = tcs.Task; - // we are testing that Task is marshaled as thenable - var promise = (Task)factory.Call(null, task, callback); - tcs.SetResult(1); - // the result value is not applied until we await the promise - Assert.Equal(0, check); - await promise; - // but it's set after we do - Assert.Equal(1, check); - } - - [Fact] - public static async Task RejectTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - return task.catch((reason)=>{ - callback(reason); - }) - "); - - string check = null; - Action callback = (string data) => - { - check = data; - }; - var promise = (Task)factory.Call(null, tcs.Task, callback); - Assert.Null(check); - tcs.SetException(new Exception("test")); - Assert.Null(check); - await promise; - Assert.Contains("System.Exception: test", check); - } - - [Fact] - public static void NullTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("task", "callback", @" - callback(task); - "); - - Task check = Task.FromResult(1); - Action callback = (Task data) => - { - check = data; - }; - factory.Call(null, null, callback); - Assert.Null(check); - } - - [ActiveIssue("https://github.com/dotnet/runtime/issues/56963")] - [Fact] - public static void RoundtripTask() - { - var tcs = new TaskCompletionSource(); - var factory = new Function("dummy", @" - return { - dummy:dummy, - }"); - - var obj = (JSObject)factory.Call(null, tcs.Task); - var dummy = obj.GetObjectProperty("dummy"); - Assert.IsType>(dummy); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs deleted file mode 100644 index f37408f32f10d..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/HelperMarshal.cs +++ /dev/null @@ -1,463 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading.Tasks; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class HelperMarshal - { - internal const string INTEROP_CLASS = "[System.Runtime.InteropServices.JavaScript.Legacy.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:"; - internal static int _i32Value; - private static void InvokeI32(int a, int b) - { - _i32Value = a + b; - } - - internal static float _f32Value; - private static void InvokeFloat(float f) - { - _f32Value = f; - } - - internal static double _f64Value; - private static void InvokeDouble(double d) - { - _f64Value = d; - } - - internal static long _i64Value; - private static void InvokeLong(long l) - { - _i64Value = l; - } - - internal static byte[] _byteBuffer; - private static void MarshalArrayBuffer(ArrayBuffer buffer) - { - using (var bytes = new Uint8Array(buffer)) - _byteBuffer = bytes.ToArray(); - } - - private static void MarshalByteBuffer(Uint8Array buffer) - { - _byteBuffer = buffer.ToArray(); - } - - internal static string _stringResource; - private static void InvokeString(string s) - { - _stringResource = s; - } - - internal static string _stringResource2; - private static void InvokeString2(string s) - { - _stringResource2 = s; - } - - private static string StoreArgumentAndReturnLiteral(string s) - { - _stringResource = $"s: {s} length: {s?.Length}"; - return "1"; - } - - private static string StoreAndReturnNew(string s) - { - var sb = new System.Text.StringBuilder(); - sb.Append("Got:"); - sb.Append(' '); - sb.Append(s); - _stringResource = sb.ToString(); - return _stringResource; - } - - internal static string _marshaledString; - private static string InvokeMarshalString() - { - _marshaledString = "Hic Sunt Dracones"; - return _marshaledString; - } - - internal static object _object1; - private static object InvokeObj1(object obj) - { - _object1 = obj; - return obj; - } - - internal static object _object2; - private static object InvokeObj2(object obj) - { - _object2 = obj; - return obj; - } - - internal static object _marshaledObject; - private static object InvokeMarshalObj() - { - _marshaledObject = new object(); - return _marshaledObject; - } - - private static object InvokeReturnMarshalObj() - { - return _marshaledObject; - } - - private static int InvokeReturnInt() - { - return 42; - } - - private static long InvokeReturnLong() - { - return 42L; - } - - private static double InvokeReturnDouble() - { - return double.Pi; - } - - internal static int _valOne, _valTwo; - private static void ManipulateObject(JSObject obj) - { - _valOne = (int)obj.Invoke("inc"); - _valTwo = (int)obj.Invoke("add", 20); - } - - internal static object[] _jsObjects; - private static void MinipulateObjTypes(JSObject obj) - { - _jsObjects = new object[4]; - _jsObjects[0] = obj.Invoke("return_int"); - _jsObjects[1] = obj.Invoke("return_double"); - _jsObjects[2] = obj.Invoke("return_string"); - _jsObjects[3] = obj.Invoke("return_bool"); - } - - internal static int _jsAddFunctionResult; - private static void UseFunction(JSObject obj) - { - _jsAddFunctionResult = (int)obj.Invoke("call", null, 10, 20); - } - - internal static int _jsAddAsFunctionResult; - private static void UseAsFunction(Function func) - { - _jsAddAsFunctionResult = (int)func.Call(null, 20, 30); - } - - internal static int _intValue; - private static void InvokeInt(int value) - { - _intValue = value; - } - - internal static IntPtr _intPtrValue; - private static void InvokeIntPtr(IntPtr i) - { - _intPtrValue = i; - } - - internal static IntPtr _marshaledIntPtrValue; - private static IntPtr InvokeMarshalIntPtr() - { - _marshaledIntPtrValue = (IntPtr)42; - return _marshaledIntPtrValue; - } - - internal static object[] _jsProperties; - private static void RetrieveObjectProperties(JSObject obj) - { - _jsProperties = new object[4]; - _jsProperties[0] = obj.GetObjectProperty("myInt"); - _jsProperties[1] = obj.GetObjectProperty("myDouble"); - _jsProperties[2] = obj.GetObjectProperty("myString"); - _jsProperties[3] = obj.GetObjectProperty("myBoolean"); - } - - private static void PopulateObjectProperties(JSObject obj, bool createIfNotExist) - { - _jsProperties = new object[4]; - obj.SetObjectProperty("myInt", 100, createIfNotExist); - obj.SetObjectProperty("myDouble", 4.5, createIfNotExist); - obj.SetObjectProperty("myString", "qwerty", createIfNotExist); - obj.SetObjectProperty("myBoolean", true, createIfNotExist); - } - - private static void SetTypedArrayByte(JSObject obj) - { - var dragons = "hic sunt dracones"; - byte[] buffer = System.Text.Encoding.ASCII.GetBytes(dragons); - obj.SetObjectProperty("dracones", Uint8Array.From(buffer)); - } - - internal static byte[] _taByte; - private static void GetTypedArrayByte(JSObject obj) - { - _taByte = ((Uint8Array)obj.GetObjectProperty("dracones")).ToArray(); - } - - private static Function _sumFunction; - private static void CreateFunctionSum() - { - _sumFunction = new Function("a", "b", "return a + b"); - } - - internal static int _sumValue = 0; - private static void CallFunctionSum() - { - if (_sumFunction == null) - throw new Exception("_sumFunction is null"); - _sumValue = (int)_sumFunction.Call(null, 3, 5); - } - - private static Function _mathMinFunction; - private static void CreateFunctionApply() - { - var math = (JSObject)Runtime.GetGlobalObject("Math"); - if (math == null) - throw new Exception("Runtime.GetGlobalObject(Math) returned null"); - _mathMinFunction = (Function)math.GetObjectProperty("min"); - - } - - internal static int _minValue = 0; - private static void CallFunctionApply() - { - if (_mathMinFunction == null) - throw new Exception("_mathMinFunction is null"); - _minValue = (int)_mathMinFunction.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - } - - internal static Uri _blobURL; - public static void SetBlobUrl(string blobUrl) - { - _blobURL = new Uri(blobUrl); - } - - internal static Uri _blobURI; - public static void SetBlobAsUri(Uri blobUri) - { - _blobURI = blobUri; - } - - internal static uint _uintValue; - private static void InvokeUInt(uint value) - { - _uintValue = value; - } - - internal static TestEnum _enumValue; - private static void SetEnumValue(TestEnum value) - { - _enumValue = value; - } - private static TestEnum GetEnumValue() - { - return _enumValue; - } - - private static UInt64 GetUInt64() - { - return UInt64.MaxValue; - } - - internal static int _functionResultValue; - private static Func CreateFunctionDelegate() - { - return (a, b) => - { - _functionResultValue = a + b; - return _functionResultValue; - }; - } - - internal static int _functionActionResultValue; - internal static int _functionActionResultValueOfAction; - private static Func> CreateFunctionDelegateWithAction() - { - return (a, b) => - { - _functionActionResultValue = a + b; - return (i1, i2) => - { - _functionActionResultValueOfAction = i1 + i2; - }; - }; - } - - internal static int _actionResultValue; - private static Action CreateActionDelegate() - { - return (a1, a2) => - { - _actionResultValue = a1 + a2; - }; - } - - private static bool AreEqual(int a, int b) - { - return a == b; - } - - private static string TestString1(string a) - { - return "Received: " + a; - } - - private static void SetTestString1(string a) - { - _delMethodStringResultValue = a; - } - - // Create a method for a delegate. - public static void DelegateMethod(string message) - { - _delMethodResultValue = message; - } - - delegate void Del(string message); - internal static string _delMethodResultValue; - private static Del CreateDelegateMethod() - { - // Instantiate the delegate. - Del handler = DelegateMethod; - return handler; - } - - delegate string Del2(string message); - internal static string _delMethodStringResultValue; - private static Del2 CreateDelegateMethodReturnString() - { - // Instantiate the delegate. - Del2 handler = TestString1; - return handler; - } - - internal static string _delegateCallResult; - private static Del CreateDelegateFromAnonymousMethod_VoidString() - { - // Instantiate the delegate. - Del handler = delegate(string name) { _delegateCallResult = $"Notification received for: {name}"; }; - return handler; - } - - private static Del CreateDelegateFromLambda_VoidString() - { - // Instantiate the delegate. - Del handler = (string name) => { _delegateCallResult = $"Notification received for: {name}"; }; - return handler; - } - - public static void DelegateMethod_VoidString(string name) => _delegateCallResult = $"Notification received for: {name}"; - - private static Del CreateDelegateFromMethod_VoidString() - { - // Instantiate the delegate. - Del handler = DelegateMethod_VoidString; - return handler; - } - - private static Action CreateActionT_VoidString() - => (string name) => _delegateCallResult = $"Notification received for: {name}"; - - static void Hello(string s) - { - _delegateCallResult += $" Hello, {s}!"; - } - - static void GoodMorning(string s) - { - _delegateCallResult += $" GoodMorning, {s}!"; - } - - delegate void CustomDelStr(string s); - private static CustomDelStr CreateCustomMultiCastDelegate_VoidString() - { - CustomDelStr hiDel, mornDel, multiDel; - hiDel = Hello; - mornDel = GoodMorning; - multiDel = hiDel + mornDel; - - return multiDel; - } - - private static Action CreateMultiCastAction_VoidString() - { - Action hiDel, mornDel, multiDel; - hiDel = Hello; - mornDel = GoodMorning; - multiDel = hiDel + mornDel; - - return multiDel; - } - - internal static JSObject _funcActionBufferObjectResultValue; - internal static int _funcActionBufferResultLengthValue; - - private static Func> CreateFunctionAcceptingUint8Array() - { - return (buffer) => - { - _funcActionBufferObjectResultValue = buffer; - return (i1) => - { - _funcActionBufferResultLengthValue = i1.Length; - }; - }; - } - private static Func> CreateFunctionAcceptingArray() - { - return (buffer) => - { - _funcActionBufferObjectResultValue = buffer; - return (i1) => - { - _funcActionBufferResultLengthValue = i1.Length; - }; - }; - } - - public static Task SynchronousTask() - { - return Task.CompletedTask; - } - - public static async Task AsynchronousTask() - { - await Task.Yield(); - } - - public static Task SynchronousTaskInt(int i) - { - return Task.FromResult(i); - } - - public static async Task AsynchronousTaskInt(int i) - { - await Task.Yield(); - return i; - } - - public static Task FailedSynchronousTask() - { - return Task.FromException(new Exception()); - } - - public static async Task FailedAsynchronousTask() - { - await Task.Yield(); - throw new Exception(); - } - } - - public enum TestEnum : uint { - FirstValue = 1, - Zero = 0, - Five = 5, - BigValue = 0xFFFFFFFEu - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs deleted file mode 100644 index c78c422cc1b6d..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs +++ /dev/null @@ -1,215 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class JavaScriptTests - { - [Fact] - public static void CoreTypes() - { - var arr1 = new Uint8Array(50); - Assert.Equal(50, arr1.Length); - } - - [Fact] - public static void FunctionSum() - { - // The Difference Between call() and apply() - // The difference is: - // The call() method takes arguments separately. - // The apply() method takes arguments as an array. - var sum = new Function("a", "b", "return a + b"); - Assert.Equal(8, (int)sum.Call(null, 3, 5)); - - Assert.Equal(13, (int)sum.Apply(null, new object[] { 6, 7 })); - } - - [Fact] - public static void FunctionMath() - { - JSObject math = (JSObject)Runtime.GetGlobalObject("Math"); - Assert.True(math != null, "math != null"); - - Function mathMax = (Function)math.GetObjectProperty("max"); - Assert.True(mathMax != null, "math.max != null"); - - var maxValue = (int)mathMax.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - Assert.Equal(7, maxValue); - - maxValue = (int)mathMax.Call(null, 5, 6, 2, 3, 7); - Assert.Equal(7, maxValue); - - Function mathMin = (Function)((JSObject)Runtime.GetGlobalObject("Math")).GetObjectProperty("min"); - Assert.True(mathMin != null, "math.min != null"); - - var minValue = (int)mathMin.Apply(null, new object[] { 5, 6, 2, 3, 7 }); - Assert.Equal(2, minValue); - - minValue = (int)mathMin.Call(null, 5, 6, 2, 3, 7); - Assert.Equal(2, minValue); - } - - [Fact] - [OuterLoop("slow")] - public static async Task BagIterator() - { - await Task.Delay(1); - - var bagFn = new Function(@" - var same = { - x:1 - }; - return Object.entries({ - a:1, - b:'two', - c:{fold:{}}, - d:same, - e:same, - f:same - }); - "); - - for (int attempt = 0; attempt < 100_000; attempt++) - { - try - { - using var bag = (JSObject)bagFn.Call(null); - using var entriesIterator = (JSObject)bag.Invoke("entries"); - - var cnt = entriesIterator.ToEnumerable().Count(); - Assert.Equal(6, cnt); - - // fill GC helps to repro - var x = new byte[100 + attempt / 100]; - if (attempt % 1000 == 0) - { - Utils.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - GC.Collect(); - } - } - catch (Exception ex) - { - throw new Exception(ex.Message + " At attempt=" + attempt, ex); - } - } - } - - [Fact] - public static async Task Iterator() - { - await Task.Delay(1); - - var makeRangeIterator = new Function("start", "end", "step", @" - let nextIndex = start; - let iterationCount = 0; - - const rangeIterator = { - next: function() { - let result; - if (nextIndex < end) { - result = { value: {}, done: false } - nextIndex += step; - iterationCount++; - return result; - } - return { value: {}, done: true } - } - }; - return rangeIterator; - "); - - const int count = 500; - for (int attempt = 0; attempt < 100; attempt++) - { - int index = 0; - try - { - var entriesIterator = (JSObject)makeRangeIterator.Call(null, 0, count, 1); - Assert.NotNull(entriesIterator); - using (entriesIterator) - { - var enumerable = entriesIterator.ToEnumerable(); - var enumerator = enumerable.GetEnumerator(); - Assert.NotNull(enumerator); - - using (enumerator) - { - while (enumerator.MoveNext()) - { - Assert.NotNull(enumerator.Current); - index++; - } - } - } - Assert.Equal(count, index); - } - catch (Exception ex) - { - throw new Exception($"At attempt={attempt}, index={index}: {ex.Message}", ex); - } - await Task.Yield(); - } - } - - public static IEnumerable ToEnumerable(this JSObject iterrator) - { - JSObject nextResult = null; - try - { - nextResult = (JSObject)iterrator.Invoke("next"); - var done = (bool)nextResult.GetObjectProperty("done"); - while (!done) - { - object value = nextResult.GetObjectProperty("value"); - nextResult.Dispose(); - yield return value; - nextResult = (JSObject)iterrator.Invoke("next"); - done = (bool)nextResult.GetObjectProperty("done"); - } - } - finally - { - nextResult?.Dispose(); - } - } - - [Fact] - public static void RoundtripCSDate() - { - var factory = new Function("dummy", @" - return { - dummy:dummy, - }"); - var date = new DateTime(2021, 01, 01, 12, 34, 45); - - var obj = (JSObject)factory.Call(null, date); - var dummy = (DateTime)obj.GetObjectProperty("dummy"); - Assert.Equal(date, dummy); - } - - [Fact] - public static void RoundtripJSDate() - { - var factory = new Function(@" - var dummy = new Date(2021, 00, 01, 12, 34, 45, 567); - return { - dummy:dummy, - check:(value) => { - return value.valueOf()==dummy.valueOf() ? 1 : 0; - }, - }"); - var obj = (JSObject)factory.Call(); - - var date = (DateTime)obj.GetObjectProperty("dummy"); - var check = (int)obj.Invoke("check", date); - Assert.Equal(1, check); - } - - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs deleted file mode 100644 index 3d27ba7948c24..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MarshalTests.cs +++ /dev/null @@ -1,791 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class MarshalTests - { - [Fact] - public static void MarshalPrimitivesToCS() - { - HelperMarshal._i32Value = 0; - Utils.InvokeJS("App.call_test_method (\"InvokeI32\", [10, 20])"); - Assert.Equal(30, HelperMarshal._i32Value); - - HelperMarshal._f32Value = 0; - Utils.InvokeJS("App.call_test_method (\"InvokeFloat\", [1.5])"); - Assert.Equal(1.5f, HelperMarshal._f32Value); - - HelperMarshal._f64Value = 0; - Utils.InvokeJS("App.call_test_method (\"InvokeDouble\", [4.5])"); - Assert.Equal(4.5, HelperMarshal._f64Value); - - HelperMarshal._i64Value = 0; - Utils.InvokeJS("App.call_test_method (\"InvokeLong\", [99])"); - Assert.Equal(99, HelperMarshal._i64Value); - } - - [Fact] - public static void MarshalArrayBuffer() - { - Utils.InvokeJS(@" - var buffer = new ArrayBuffer(16); - App.call_test_method (""MarshalArrayBuffer"", [ buffer ]); - "); - Assert.Equal(16, HelperMarshal._byteBuffer.Length); - } - - [Fact] - public static void MarshalStringToCS() - { - HelperMarshal._stringResource = null; - Utils.InvokeJS("App.call_test_method(\"InvokeString\", [\"hello\"])"); - Assert.Equal("hello", HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalUnicodeStringToCS() - { - HelperMarshal._stringResource = null; - Utils.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\u0050\u0159\u00ed\u006c\u0069\u0161\u0020\u017e\u006c\u0075\u0165\u006f\u0075\u010d\u006b\u00fd\u0020\u006b\u016f\u0148\u202f\u00fa\u0070\u011b\u006c\u0020\u010f\u00e1\u0062\u0065\u006c\u0073\u006b\u00e9\u0020\u00f3\u0064\u0079\"])"); - Assert.Equal("Got: \u0050\u0159\u00ed\u006c\u0069\u0161\u0020\u017e\u006c\u0075\u0165\u006f\u0075\u010d\u006b\u00fd\u0020\u006b\u016f\u0148\u202f\u00fa\u0070\u011b\u006c\u0020\u010f\u00e1\u0062\u0065\u006c\u0073\u006b\u00e9\u0020\u00f3\u0064\u0079", HelperMarshal._stringResource); - - HelperMarshal._stringResource = null; - Utils.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\uFEFF\u0000\uFFFE\"])"); - Assert.Equal("Got: \uFEFF\0\uFFFE", HelperMarshal._stringResource); - - HelperMarshal._stringResource = null; - Utils.InvokeJS("App.call_test_method(\"StoreAndReturnNew\", [' '+\"\u02F3o\u0302\u0303\u0308\u0930\u0903\u0951\"])"); - Assert.Equal("Got: \u02F3o\u0302\u0303\u0308\u0930\u0903\u0951", HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalNullStringToCS() - { - HelperMarshal._stringResource = null; - Utils.InvokeJS("App.call_test_method(\"InvokeString\", [ null ])"); - Assert.Null(HelperMarshal._stringResource); - } - - [Fact] - public static void MarshalStringToJS() - { - HelperMarshal._marshaledString = HelperMarshal._stringResource = null; - Utils.InvokeJS(@" - var str = App.call_test_method (""InvokeMarshalString""); - App.call_test_method (""InvokeString"", [ str ]); - "); - Assert.NotNull(HelperMarshal._marshaledString); - Assert.Equal(HelperMarshal._marshaledString, HelperMarshal._stringResource); - } - - [Fact] - public static void JSObjectKeepIdentityAcrossCalls() - { - HelperMarshal._object1 = HelperMarshal._object2 = null; - Utils.InvokeJS(@" - var obj = { foo: 10 }; - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - App.call_test_method (""InvokeObj2"", [ res ]); - "); - - Assert.NotNull(HelperMarshal._object1); - Assert.Same(HelperMarshal._object1, HelperMarshal._object2); - } - - [Fact] - public static void CSObjectKeepIdentityAcrossCalls() - { - HelperMarshal._marshaledObject = HelperMarshal._object1 = HelperMarshal._object2 = null; - Utils.InvokeJS(@" - var obj = App.call_test_method (""InvokeMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - App.call_test_method (""InvokeObj2"", [ res ]); - "); - - Assert.NotNull(HelperMarshal._object1); - Assert.Same(HelperMarshal._marshaledObject, HelperMarshal._object1); - Assert.Same(HelperMarshal._object1, HelperMarshal._object2); - } - - [Theory] - [InlineData(byte.MinValue)] - [InlineData(byte.MaxValue)] - [InlineData(SByte.MinValue)] - [InlineData(SByte.MaxValue)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxNumberString(object o) - { - HelperMarshal._marshaledObject = o; - HelperMarshal._object1 = HelperMarshal._object2 = null; - var value = Utils.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj.toString() ]); - "); - - Assert.Equal(o.ToString().ToLower(), HelperMarshal._object1); - } - - [Theory] - [InlineData(byte.MinValue, 0)] - [InlineData(byte.MaxValue, 255)] - [InlineData(SByte.MinValue, -128)] - [InlineData(SByte.MaxValue, 127)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue, 0)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxNumber(object o, object expected = null) - { - HelperMarshal._marshaledObject = o; - HelperMarshal._object1 = HelperMarshal._object2 = null; - Utils.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnMarshalObj""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(expected ?? o, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxInt() - { - Utils.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnInt""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(42, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxDouble() - { - Utils.InvokeJS(@" - var obj = App.call_test_method (""InvokeReturnDouble""); - var res = App.call_test_method (""InvokeObj1"", [ obj ]); - "); - - Assert.Equal(double.Pi, HelperMarshal._object1); - } - - [Fact] - public static void InvokeUnboxLongFail() - { - var ex = Assert.Throws(() => Utils.InvokeJS(@" - console.log(""the exception in InvokeReturnLong after this is intentional""); - App.call_test_method (""InvokeReturnLong""); - ")); - Assert.Contains("int64 not available", ex.Message); - } - - [Theory] - [InlineData(byte.MinValue, 0)] - [InlineData(byte.MaxValue, 255)] - [InlineData(SByte.MinValue, -128)] - [InlineData(SByte.MaxValue, 127)] - [InlineData(uint.MaxValue)] - [InlineData(uint.MinValue, 0)] - [InlineData(int.MaxValue)] - [InlineData(int.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.MinValue)] - public static void InvokeUnboxStringNumber(object o, object expected = null) - { - HelperMarshal._marshaledObject = HelperMarshal._object1 = HelperMarshal._object2 = null; - Utils.InvokeJS(String.Format(@" - var res = App.call_test_method (""InvokeObj1"", [ {0} ]); - ", o)); - - Assert.Equal(expected ?? o, HelperMarshal._object1); - } - - [Fact] - public static void JSInvokeInt() - { - Utils.InvokeJS(@" - var obj = { - foo: 10, - inc: function() { - var c = this.foo; - ++this.foo; - return c; - }, - add: function(val){ - return this.foo + val; - } - }; - App.call_test_method (""ManipulateObject"", [ obj ]); - "); - Assert.Equal(10, HelperMarshal._valOne); - Assert.Equal(31, HelperMarshal._valTwo); - } - - [Fact] - public static void JSInvokeTypes() - { - Utils.InvokeJS(@" - var obj = { - return_int: function() { return 100; }, - return_double: function() { return 4.5; }, - return_string: function() { return 'Hic Sunt Dracones'; }, - return_bool: function() { return true; }, - }; - App.call_test_method (""MinipulateObjTypes"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsObjects[0]); - Assert.Equal(4.5, HelperMarshal._jsObjects[1]); - Assert.Equal("Hic Sunt Dracones", HelperMarshal._jsObjects[2]); - Assert.NotEqual("HIC SVNT LEONES", HelperMarshal._jsObjects[2]); - Assert.Equal(true, HelperMarshal._jsObjects[3]); - } - - [Fact] - public static void JSObjectApply() - { - Utils.InvokeJS(@" - var do_add = function(a, b) { return a + b }; - App.call_test_method (""UseFunction"", [ do_add ]); - "); - Assert.Equal(30, HelperMarshal._jsAddFunctionResult); - } - - [Fact] - public static void JSObjectAsFunction() - { - Utils.InvokeJS(@" - var do_add = function(a, b) { return a + b }; - App.call_test_method (""UseAsFunction"", [ do_add ]); - "); - Assert.Equal(50, HelperMarshal._jsAddAsFunctionResult); - } - - [Fact] - public static void BindStaticMethod() - { - HelperMarshal._intValue = 0; - Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (200); - "); - - Assert.Equal(200, HelperMarshal._intValue); - } - - [Fact] - public static void BindIntPtrStaticMethod() - { - HelperMarshal._intPtrValue = IntPtr.Zero; - Utils.InvokeJS(@$" - var invoke_int_ptr = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeIntPtr""); - invoke_int_ptr (42); - "); - Assert.Equal(42, (int)HelperMarshal._intPtrValue); - } - - [Fact] - public static void MarshalIntPtrToJS() - { - HelperMarshal._marshaledIntPtrValue = IntPtr.Zero; - Utils.InvokeJS(@$" - var invokeMarshalIntPtr = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeMarshalIntPtr""); - var r = invokeMarshalIntPtr (); - - if (r != 42) throw `Invalid int_ptr value`; - "); - Assert.Equal(42, (int)HelperMarshal._marshaledIntPtrValue); - } - - [Fact] - public static void ResolveMethod() - { - HelperMarshal._intValue = 0; - Utils.InvokeJS(@$" - var invoke_int = INTERNAL.mono_method_resolve (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - App.call_test_method (""InvokeInt"", [ invoke_int ]); - "); - - Assert.NotEqual(0, HelperMarshal._intValue); - } - - [Fact] - public static void GetObjectProperties() - { - Utils.InvokeJS(@" - var obj = {myInt: 100, myDouble: 4.5, myString: ""Hic Sunt Dracones"", myBoolean: true}; - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("Hic Sunt Dracones", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectProperties() - { - Utils.InvokeJS(@" - var obj = {myInt: 200, myDouble: 0, myString: ""foo"", myBoolean: false}; - App.call_test_method (""PopulateObjectProperties"", [ obj, false ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("qwerty", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectPropertiesIfNotExistsFalse() - { - // This test will not create the properties if they do not already exist - Utils.InvokeJS(@" - var obj = {myInt: 200}; - App.call_test_method (""PopulateObjectProperties"", [ obj, false ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Null(HelperMarshal._jsProperties[1]); - Assert.Null(HelperMarshal._jsProperties[2]); - Assert.Null(HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void SetObjectPropertiesIfNotExistsTrue() - { - // This test will set the value of the property if it exists and will create and - // set the value if it does not exists - Utils.InvokeJS(@" - var obj = {myInt: 200}; - App.call_test_method (""PopulateObjectProperties"", [ obj, true ]); - App.call_test_method (""RetrieveObjectProperties"", [ obj ]); - "); - - Assert.Equal(100, HelperMarshal._jsProperties[0]); - Assert.Equal(4.5, HelperMarshal._jsProperties[1]); - Assert.Equal("qwerty", HelperMarshal._jsProperties[2]); - Assert.Equal(true, HelperMarshal._jsProperties[3]); - } - - [Fact] - public static void MarshalTypedArray() - { - Utils.InvokeJS(@" - var buffer = new ArrayBuffer(16); - var uint8View = new Uint8Array(buffer); - App.call_test_method (""MarshalByteBuffer"", [ uint8View ]); - "); - - Assert.Equal(16, HelperMarshal._byteBuffer.Length); - } - - [Fact] - public static void MarshalUri() - { - HelperMarshal._blobURI = null; - Utils.InvokeJS(@" - App.call_test_method (""SetBlobAsUri"", [ ""https://dotnet.microsoft.com/en-us/"" ]); - "); - - Assert.NotNull(HelperMarshal._blobURI); - } - - private static void RunMarshalTypedArrayJS(string type) - { - Utils.InvokeJS(@" - var obj = { }; - App.call_test_method (""SetTypedArray" + type + @""", [ obj ]); - App.call_test_method (""GetTypedArray" + type + @""", [ obj ]); - "); - } - - [Fact] - public static void MarshalTypedArrayByte() - { - RunMarshalTypedArrayJS("Byte"); - Assert.Equal(17, HelperMarshal._taByte.Length); - Assert.Equal(104, HelperMarshal._taByte[0]); - Assert.Equal(115, HelperMarshal._taByte[HelperMarshal._taByte.Length - 1]); - Assert.Equal("hic sunt dracones", System.Text.Encoding.Default.GetString(HelperMarshal._taByte)); - } - - [Fact] - public static void TestFunctionSum() - { - HelperMarshal._sumValue = 0; - Utils.InvokeJS(@" - App.call_test_method (""CreateFunctionSum"", []); - App.call_test_method (""CallFunctionSum"", []); - "); - Assert.Equal(8, HelperMarshal._sumValue); - } - - [Fact] - public static void TestFunctionApply() - { - HelperMarshal._minValue = 0; - Utils.InvokeJS(@" - App.call_test_method (""CreateFunctionApply"", []); - App.call_test_method (""CallFunctionApply"", []); - "); - Assert.Equal(2, HelperMarshal._minValue); - } - - [Fact] - public static void BoundStaticMethodMissingArgs() - { - HelperMarshal._intValue = 1; - var ex = Assert.Throws(() => Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (); - ")); - Assert.Contains("Value is not an integer: undefined (undefined)", ex.Message); - Assert.Equal(1, HelperMarshal._intValue); - } - - [Fact] - public static void BoundStaticMethodExtraArgs() - { - HelperMarshal._intValue = 0; - Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (200, 400); - "); - Assert.Equal(200, HelperMarshal._intValue); - } - - [Fact] - public static void RangeCheckInt() - { - HelperMarshal._intValue = 0; - // no numbers bigger than 32 bits - var ex = Assert.Throws(() => Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (Number.MAX_SAFE_INTEGER); - ")); - Assert.Contains("Overflow: value 9007199254740991 is out of -2147483648 2147483647 range", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void IntegerCheckInt() - { - HelperMarshal._intValue = 0; - // no floating point rounding - var ex = Assert.Throws(() => Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (3.14); - ")); - Assert.Contains("Value is not an integer: 3.14 (number)", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void TypeCheckInt() - { - HelperMarshal._intValue = 0; - // no string conversion - var ex = Assert.Throws(() => Utils.InvokeJS(@$" - var invoke_int = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeInt""); - invoke_int (""200""); - ")); - Assert.Contains("Value is not an integer: 200 (string)", ex.Message); - Assert.Equal(0, HelperMarshal._intValue); - } - - [Fact] - public static void PassUintArgument() - { - HelperMarshal._uintValue = 0; - Utils.InvokeJS(@$" - var invoke_uint = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeUInt""); - invoke_uint (0xFFFFFFFE); - "); - - Assert.Equal(0xFFFFFFFEu, HelperMarshal._uintValue); - } - - [Fact] - public static void ReturnUintEnum() - { - HelperMarshal._uintValue = 0; - HelperMarshal._enumValue = TestEnum.BigValue; - Utils.InvokeJS(@$" - var get_value = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}GetEnumValue""); - var e = get_value (); - var invoke_uint = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}InvokeUInt""); - invoke_uint (e); - "); - Assert.Equal((uint)TestEnum.BigValue, HelperMarshal._uintValue); - } - - [Fact] - public static void PassUintEnumByValue() - { - HelperMarshal._enumValue = TestEnum.Zero; - Utils.InvokeJS(@$" - var set_enum = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}SetEnumValue"", ""j""); - set_enum (0xFFFFFFFE); - "); - Assert.Equal(TestEnum.BigValue, HelperMarshal._enumValue); - } - - [Fact] - public static void PassUintEnumByNameIsNotImplemented() - { - HelperMarshal._enumValue = TestEnum.Zero; - var exc = Assert.Throws(() => - Utils.InvokeJS(@$" - var set_enum = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}SetEnumValue"", ""j""); - set_enum (""BigValue""); - ") - ); - Assert.StartsWith("Error: Expected numeric value for enum argument, got 'BigValue'", exc.Message); - } - - [Fact] - public static void CannotUnboxUint64() - { - var exc = Assert.Throws(() => - Utils.InvokeJS(@$" - var get_u64 = BINDING.bind_static_method (""{HelperMarshal.INTEROP_CLASS}GetUInt64"", """"); - var u64 = get_u64(); - ") - ); - Assert.StartsWith("Error: int64 not available", exc.Message); - } - - [Fact] - public static void BareStringArgumentsAreNotInterned() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var jsLiteral = ""hello world""; - App.call_test_method (""InvokeString"", [ jsLiteral ]); - App.call_test_method (""InvokeString2"", [ jsLiteral ]); - "); - Assert.Equal("hello world", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.False(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void InternedStringSignaturesAreInternedOnJavascriptSide() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var sym = ""interned string""; - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""S""); - "); - Assert.Equal("interned string", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void OnceAJSStringIsInternedItIsAlwaysUsedIfPossible() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var sym = ""interned string 2""; - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal("interned string 2", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void ManuallyInternString() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var sym = INTERNAL.stringToMonoStringIntern(""interned string 3""); - App.call_test_method (""InvokeString"", [ sym ], ""s""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal("interned string 3", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void LargeStringsAreNotAutomaticallyLocatedInInternTable() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var s = ""long interned string""; - for (var i = 0; i < 1024; i++) - s += String(i % 10); - var sym = INTERNAL.stringToMonoStringIntern(s); - App.call_test_method (""InvokeString"", [ sym ], ""S""); - App.call_test_method (""InvokeString2"", [ sym ], ""s""); - "); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.False(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void CanInternVeryManyStrings() - { - HelperMarshal._stringResource = null; - Utils.InvokeJS(@" - for (var i = 0; i < 10240; i++) - INTERNAL.stringToMonoStringIntern('s' + i); - App.call_test_method (""InvokeString"", [ 's5000' ], ""S""); - "); - Assert.Equal("s5000", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, string.IsInterned(HelperMarshal._stringResource)); - } - - [Fact] - public static void SymbolsAreMarshaledAsStrings() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - Utils.InvokeJS(@" - var jsLiteral = Symbol(""custom symbol""); - App.call_test_method (""InvokeString"", [ jsLiteral ]); - App.call_test_method (""InvokeString2"", [ jsLiteral ]); - "); - Assert.Equal("custom symbol", HelperMarshal._stringResource); - Assert.Equal(HelperMarshal._stringResource, HelperMarshal._stringResource2); - Assert.True(Object.ReferenceEquals(HelperMarshal._stringResource, HelperMarshal._stringResource2)); - } - - [Fact] - public static void InternedStringReturnValuesWork() - { - HelperMarshal._stringResource = HelperMarshal._stringResource2 = null; - var fqn = "[System.Runtime.InteropServices.JavaScript.Legacy.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:StoreArgumentAndReturnLiteral"; - Utils.InvokeJS( - $"var a = BINDING.bind_static_method('{fqn}')('test');\r\n" + - $"var b = BINDING.bind_static_method('{fqn}')(a);\r\n" + - "App.call_test_method ('InvokeString2', [ b ]);" - ); - Assert.Equal("s: 1 length: 1", HelperMarshal._stringResource); - Assert.Equal("1", HelperMarshal._stringResource2); - } - - [Fact] - public static void InvokeJSExpression() - { - var result = Utils.InvokeJS(@"1 + 2"); - Assert.Equal("3", result); - } - - [Fact] - public static void InvokeJSNullExpression() - { - var result = Utils.InvokeJS(@"null"); - Assert.Null(result); - } - - [Fact] - public static void InvokeJSUndefinedExpression() - { - var result = Utils.InvokeJS(@"undefined"); - Assert.Null(result); - } - - [Fact] - public static void InvokeJSNotInGlobalScope() - { - var result = Utils.InvokeJS(@"var test_local_variable_name = 5; globalThis.test_local_variable_name"); - Assert.Null(result); - } - - private static async Task MarshalTask(string helperMethodName, string helperMethodArgs = "", string resolvedBody = "") - { - Utils.InvokeJS( - @"globalThis.__test_promise_completed = false; " + - @"globalThis.__test_promise_resolved = false; " + - @"globalThis.__test_promise_failed = false; " + - $@"var t = App.call_test_method ('{helperMethodName}', [ {helperMethodArgs} ]); " + - "t.then(result => { globalThis.__test_promise_resolved = true; " + resolvedBody + " })" + - " .catch(e => { globalThis.__test_promise_failed = true; })" + - " .finally(result => { globalThis.__test_promise_completed = true; }); " + - "" - ); - - await Task.Delay(1); - - var completed = bool.Parse(Utils.InvokeJS(@"globalThis.__test_promise_completed")); - Assert.True(completed, "JavasScript promise did not completed."); - - var resolved = bool.Parse(Utils.InvokeJS(@"globalThis.__test_promise_resolved")); - return resolved; - } - - private static async Task MarshalTaskReturningInt(string helperMethodName) - { - HelperMarshal._intValue = 0; - - bool success = await MarshalTask(helperMethodName, "7", "App.call_test_method ('InvokeInt', [ result ], 'i');"); - - Assert.True(success, $"{helperMethodName} didn't succeeded."); - Assert.Equal(7, HelperMarshal._intValue); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static async Task MarshalSynchronousTask() - { - bool success = await MarshalTask("SynchronousTask"); - Assert.True(success, "SynchronousTask didn't succeeded."); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static async Task MarshalAsynchronousTask() - { - bool success = await MarshalTask("AsynchronousTask"); - Assert.True(success, "AsynchronousTask didn't succeeded."); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static Task MarshalSynchronousTaskInt() - { - return MarshalTaskReturningInt("SynchronousTaskInt"); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static Task MarshalAsynchronousTaskInt() - { - return MarshalTaskReturningInt("AsynchronousTaskInt"); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static async Task MarshalFailedSynchronousTask() - { - bool success = await MarshalTask("FailedSynchronousTask"); - Assert.False(success, "FailedSynchronousTask didn't failed."); - } - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/94253", typeof(PlatformDetection), nameof(PlatformDetection.IsWasmThreadingSupported))] - public static async Task MarshalFailedAsynchronousTask() - { - bool success = await MarshalTask("FailedAsynchronousTask"); - Assert.False(success, "FailedAsynchronousTask didn't failed."); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs deleted file mode 100644 index 70eb88b1a55c6..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/MemoryTests.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.CompilerServices; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public class MemoryTests - { - [Theory] - [InlineData(-1L)] - [InlineData(-42L)] - [InlineData(int.MinValue)] - [InlineData(-9007199254740990L)]//MIN_SAFE_INTEGER+1 - [InlineData(-9007199254740991L)]//MIN_SAFE_INTEGER - [InlineData(1L)] - [InlineData(0L)] - [InlineData(42L)] - [InlineData(int.MaxValue)] - [InlineData(0xF_FFFF_FFFFL)] - [InlineData(9007199254740991L)]//MAX_SAFE_INTEGER - public static unsafe void Int52TestOK(long value) - { - long expected = value; - long dummy = 0xA6A6A6A6L; - long actual2 = dummy; - var bagFn = new Function("ptr", "ptr2", @" - const value=globalThis.App.runtime.getHeapI52(ptr); - globalThis.App.runtime.setHeapI52(ptr2, value); - return ''+value;"); - - uint ptr = (uint)Unsafe.AsPointer(ref expected); - uint ptr2 = (uint)Unsafe.AsPointer(ref actual2); - - object actual = (string)bagFn.Call(null, ptr, ptr2); - Assert.Equal(""+ value, actual); - Assert.Equal(value, actual2); - Assert.Equal(0xA6A6A6A6L, dummy); - } - - [Theory] - [InlineData(uint.MinValue)] - [InlineData(1UL)] - [InlineData(0UL)] - [InlineData(42UL)] - [InlineData(uint.MaxValue)] - [InlineData(0xF_FFFF_FFFFUL)] - [InlineData(9007199254740991UL)]//MAX_SAFE_INTEGER - public static unsafe void UInt52TestOK(ulong value) - { - ulong expected = value; - ulong dummy = 0xA6A6A6A6UL; - ulong actual2 = dummy; - var bagFn = new Function("ptr", "ptr2", @" - const value=globalThis.App.runtime.getHeapI52(ptr); - globalThis.App.runtime.setHeapU52(ptr2, value); - return ''+value;"); - - uint ptr = (uint)Unsafe.AsPointer(ref expected); - uint ptr2 = (uint)Unsafe.AsPointer(ref actual2); - - string actual = (string)bagFn.Call(null, ptr, ptr2); - Assert.Equal(""+value, actual); - Assert.Equal(value, actual2); - Assert.Equal(0xA6A6A6A6UL, dummy); - } - - [Fact] - public static unsafe void UInt52TestRandom() - { - for(int i = 0; i < 1000; i++) - { - var value = (ulong)Random.Shared.NextInt64(); - value&= 0x1F_FFFF_FFFF_FFFFUL;// only safe range - UInt52TestOK(value); - } - } - - [Fact] - public static unsafe void Int52TestRandom() - { - for(int i = 0; i < 1000; i++) - { - var value = Random.Shared.NextInt64(-9007199254740991L, 9007199254740991L); - Int52TestOK(value); - } - } - - [Theory] - [InlineData(double.NegativeInfinity)] - [InlineData(double.PositiveInfinity)] - [InlineData(double.MinValue)] - [InlineData(double.MaxValue)] - [InlineData(double.Pi)] - [InlineData(9007199254740993.0)]//MAX_SAFE_INTEGER +2 - public static unsafe void Int52TestRange(double value) - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.runtime.setHeapI52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Value is not a safe integer", ex.Message); - - double expectedD = value; - uint ptrD = (uint)Unsafe.AsPointer(ref expectedD); - var bagFnD = new Function("ptr", "value", @" - globalThis.App.runtime.getHeapI52(ptr);"); - var exD = Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Value is not a safe integer", ex.Message); - } - - [Theory] - [InlineData(-1.0)] - public static unsafe void UInt52TestRange(double value) - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.runtime.setHeapU52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Can't convert negative Number into UInt64", ex.Message); - - double expectedD = value; - uint ptrD = (uint)Unsafe.AsPointer(ref expectedD); - var bagFnD = new Function("ptr", "value", @" - globalThis.App.runtime.getHeapU52(ptr);"); - var exD = Assert.Throws(() => bagFn.Call(null, ptr, value)); - Assert.Contains("Can't convert negative Number into UInt64", ex.Message); - } - - [Fact] - public static unsafe void Int52TestNaN() - { - long actual = 0; - uint ptr = (uint)Unsafe.AsPointer(ref actual); - var bagFn = new Function("ptr", "value", @" - globalThis.App.runtime.setHeapI52(ptr, value);"); - var ex=Assert.Throws(() => bagFn.Call(null, ptr, double.NaN)); - Assert.Contains("Value is not a safe integer: NaN (number)", ex.Message); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs deleted file mode 100644 index c74b84b60fc09..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/ParallelTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections; -using System.Collections.Generic; -using System.Runtime.InteropServices.JavaScript; -using System.Threading; -using System.Threading.Tasks; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class ParallelTests - { - // The behavior of APIs like Invoke depends on how many items they are asked to invoke - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(2)] - [InlineData(5)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelInvokeActionArray(int count) - { - var actions = new List(); - int sum = 0, expected = 0; - for (int i = 0; i < count; i++) { - int j = i; - actions.Add(() => { - sum += j; - }); - expected += j; - } - - Parallel.Invoke(actions.ToArray()); - Assert.Equal(expected, sum); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelFor(int count) - { - int sum = 0, expected = 0; - for (int i = 0; i < count; i++) - expected += i; - Parallel.For(0, count, (i) => { sum += i; }); - Assert.Equal(expected, sum); - } - - [Theory] - [InlineData(0)] - [InlineData(1)] - [InlineData(32)] - [InlineData(250)] - public static void ParallelForEach(int count) - { - int sum = 0, expected = 0; - var items = new List(); - for (int i = 0; i < count; i++) { - items.Add(i); - expected += i; - } - Parallel.ForEach(items, (i) => { sum += i; }); - Assert.Equal(expected, sum); - } - } -} \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs deleted file mode 100644 index 9df7fd8719bcc..0000000000000 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TypedArrayTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using Xunit; - -namespace System.Runtime.InteropServices.JavaScript.Tests -{ - public static class TypedArrayTests - { - private static Function _objectPrototype; - - public static IEnumerable Object_Prototype() - { - _objectPrototype ??= new Function("return Object.prototype.toString;"); - yield return new object[] { _objectPrototype.Call() }; - } - - [Theory] - [MemberData(nameof(Object_Prototype))] - public static void Uint8ArrayFrom(Function objectPrototype) - { - var array = new byte[50]; - Uint8Array from = Uint8Array.From(array); - Assert.Equal(50, from.Length); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(from)); - } - - [Theory] - [MemberData(nameof(Object_Prototype))] - public static void Uint8ArrayFromArrayBuffer(Function objectPrototype) - { - Uint8Array from = new Uint8Array(new ArrayBuffer(50)); - Assert.True(from.Length == 50); - Assert.Equal("[object Uint8Array]", objectPrototype.Call(from)); - } - } -} 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 ab0e7ac77251e..a0457f006246c 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 @@ -8,10 +8,8 @@ $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop true true - false true $(DefineConstants);FEATURE_WASM_THREADS - $(DefineConstants);DISABLE_LEGACY_JS_INTEROP true @@ -24,12 +22,15 @@ + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs similarity index 77% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs rename to src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs index e9c2f68c3097e..815dfeb0dcd2d 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/Http/HttpRequestMessageTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/HttpRequestMessageTest.cs @@ -366,89 +366,6 @@ public void ToString_NonDefaultInstanceWithCustomHeaders_DumpAllFields(string ur "}", rm.ToString()); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupported))] - public async Task BlobUri_Marshal_CorrectValues_Browser() - { - Utils.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be marshaled as valid URI - App.call_test_method (""InvokeString"", [ url ]); - "); - - var client = new HttpClient (); - Assert.StartsWith ("blob:", HelperMarshal._stringResource); - - HttpRequestMessage rm = new HttpRequestMessage(HttpMethod.Get, new Uri (HelperMarshal._stringResource)); - HttpResponseMessage resp = await client.SendAsync (rm); - Assert.NotNull (resp.Content); - string content = await resp.Content.ReadAsStringAsync(); - Assert.Equal (59, content.Length); - } - - [Fact] - public void BlobStringUri_Marshal_CorrectValues() - { - Utils.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - // URL.createObjectURL does not work outside of browser but since this was actual - // test code from https://developer.mozilla.org/en-US/docs/Web/API/Blob - // left it in to show what this should do if the test code were to actually run - //return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - return 'blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7'; - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be converted to a valid Uri - // within the method - App.call_test_method (""SetBlobUrl"", [ url ]); - "); - - var rm = new HttpRequestMessage(HttpMethod.Post, HelperMarshal._blobURL); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri("blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7"), rm.RequestUri); - } - - [Fact] - public void BlobUri_Marshal_CorrectValues() - { - Utils.InvokeJS(@" - function typedArrayToURL(typedArray, mimeType) { - // URL.createObjectURL does not work outside of browser but since this was actual - // test code from https://developer.mozilla.org/en-US/docs/Web/API/Blob - // left it in to show what this should do if the test code were to actually run - //return URL.createObjectURL(new Blob([typedArray.buffer], {type: mimeType})) - return 'blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7'; - } - const bytes = new Uint8Array(59); - for(let i = 0; i < 59; i++) { - bytes[i] = 32 + i; - } - const url = typedArrayToURL(bytes, 'text/plain'); - // Calls method with string that will be marshaled as valid URI - App.call_test_method (""SetBlobAsUri"", [ url ]); - "); - - var rm = new HttpRequestMessage(HttpMethod.Post, HelperMarshal._blobURI); - - Assert.Equal(HttpMethod.Post, rm.Method); - Assert.Equal(_expectedRequestMessageVersion, rm.Version); - Assert.Null(rm.Content); - Assert.Equal(new Uri("blob:https://mdn.mozillademos.org/ca45b575-6348-4d3e-908a-3dbf3d146ea7"), rm.RequestUri); - } - #region Helper methods private class MockContent : HttpContent 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 8fdcfebf52c41..e7e058e120fb4 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 @@ -68,11 +68,6 @@ public unsafe void GlobalThis() [Fact] public unsafe void DotnetInstance() { -#if !DISABLE_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/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TimerTests.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/TimerTests.cs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System/Runtime/InteropServices/JavaScript/TimerTests.cs rename to src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/TimerTests.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/timers.mjs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/timers.mjs similarity index 100% rename from src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/timers.mjs rename to src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/timers.mjs diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 9456a9b5c45f9..79ab84eedef73 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -530,7 +530,6 @@ - diff --git a/src/mono/browser/.gitignore b/src/mono/browser/.gitignore index 6047d67b80823..6177029d9f9e1 100644 --- a/src/mono/browser/.gitignore +++ b/src/mono/browser/.gitignore @@ -3,4 +3,3 @@ emsdk runtime/dotnet.d.ts.sha256 -runtime/dotnet-legacy.d.ts.sha256 diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index 9b962a7efabe4..3d8cc6b3306c9 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -26,7 +26,6 @@ $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) true true - true true false false @@ -393,7 +392,6 @@ $(CMakeBuildRuntimeConfigureCmd) -DCONFIGURATION_INTERPSIMDTABLES_LIB="nosimd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DENABLE_JS_INTEROP_BY_VALUE=1 - $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_LEGACY_JS_INTEROP=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) @@ -405,8 +403,6 @@ bash -c 'source $(EMSDK_PATH)/emsdk_env.sh 2>&1 && $(CMakeBuildRuntimeCmd)' - <_CmakeEnvironmentVariable Include="DISABLE_LEGACY_JS_INTEROP=1" Condition="'$(WasmEnableLegacyJsInterop)' == 'false'"/> - <_CmakeEnvironmentVariable Include="DISABLE_LEGACY_JS_INTEROP=0" Condition="'$(WasmEnableLegacyJsInterop)' != 'false'"/> <_CmakeEnvironmentVariable Include="ENABLE_JS_INTEROP_BY_VALUE=1" Condition="'$(WasmEnableJsInteropByValue)' != 'false'"/> <_CmakeEnvironmentVariable Include="ENABLE_JS_INTEROP_BY_VALUE=0" Condition="'$(WasmEnableJsInteropByValue)' == 'false'"/> <_CmakeEnvironmentVariable Include="WASM_ENABLE_SIMD=1" Condition="'$(WasmEnableSIMD)' != 'false'" /> @@ -480,7 +476,6 @@ $(NativeBinDir)dotnet.runtime.js.map; $(NativeBinDir)dotnet.native.js; $(NativeBinDir)dotnet.d.ts; - $(NativeBinDir)dotnet-legacy.d.ts; $(NativeBinDir)package.json; $(NativeBinDir)dotnet.native.wasm" DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)" @@ -529,7 +524,7 @@ <_RollupInputs Include="$(BrowserProjectRoot)runtime/**/*.ts" - Exclude="$(BrowserProjectRoot)runtime/dotnet.d.ts;$(BrowserProjectRoot)runtime/dotnet-legacy.d.ts;$(BrowserProjectRoot)runtime/diagnostics-mock.d.ts;$(BrowserProjectRoot)runtime/node_modules/**/*.ts" /> + Exclude="$(BrowserProjectRoot)runtime/dotnet.d.ts;$(BrowserProjectRoot)runtime/diagnostics-mock.d.ts;$(BrowserProjectRoot)runtime/node_modules/**/*.ts" /> <_RollupInputs Include="$(BrowserProjectRoot)runtime/**/tsconfig.*" Exclude="$(BrowserProjectRoot)runtime/node_modules/**/tsconfig.*" /> <_RollupInputs Include="$(BrowserProjectRoot)runtime/workers/**/*.js"/> @@ -549,8 +544,6 @@ <_MonoRollupEnvironmentVariable Include="WASM_ENABLE_SIMD:0" Condition="'$(WasmEnableSIMD)' == 'false'" /> <_MonoRollupEnvironmentVariable Include="WASM_ENABLE_EH:1" Condition="'$(WasmEnableExceptionHandling)' != 'false'" /> <_MonoRollupEnvironmentVariable Include="WASM_ENABLE_EH:0" Condition="'$(WasmEnableExceptionHandling)' == 'false'" /> - <_MonoRollupEnvironmentVariable Include="DISABLE_LEGACY_JS_INTEROP:1" Condition="'$(WasmEnableLegacyJsInterop)' == 'false'" /> - <_MonoRollupEnvironmentVariable Include="DISABLE_LEGACY_JS_INTEROP:0" Condition="'$(WasmEnableLegacyJsInterop)' != 'false'" /> <_MonoRollupEnvironmentVariable Include="ENABLE_JS_INTEROP_BY_VALUE:1" Condition="'$(WasmEnableJsInteropByValue)' == 'true'" /> <_MonoRollupEnvironmentVariable Include="ENABLE_JS_INTEROP_BY_VALUE:0" Condition="'$(WasmEnableJsInteropByValue)' != 'true'" /> <_MonoRollupEnvironmentVariable Include="MonoDiagnosticsMock:$(MonoDiagnosticsMock)" /> diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets index 9dd40ec65cc64..edba838ff2bd0 100644 --- a/src/mono/browser/build/BrowserWasmApp.targets +++ b/src/mono/browser/build/BrowserWasmApp.targets @@ -28,7 +28,6 @@ _WasmGenerateRunV8Script; - true true false @@ -48,7 +47,6 @@ <_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' == 'true' and '$(RunAOTCompilation)' == 'true'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.WasmIntrinsics.xml" <_ExtraTrimmerArgs Condition="'$(WasmEnableSIMD)' != 'true'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.NoWasmIntrinsics.xml" - <_ExtraTrimmerArgs Condition="'$(WasmEnableLegacyJsInterop)' == 'false'">$(_ExtraTrimmerArgs) --substitutions "$(MSBuildThisFileDirectory)ILLink.Substitutions.LegacyJsInterop.xml" true emcc @@ -64,7 +62,6 @@ - <_BoolPropertiesThatTriggerRelinking Include="WasmEnableLegacyJsInterop" DefaultValueInRuntimePack="true" /> <_BoolPropertiesThatTriggerRelinking Include="WasmEnableSIMD" DefaultValueInRuntimePack="true" /> <_BoolPropertiesThatTriggerRelinking Include="WasmEnableExceptionHandling" DefaultValueInRuntimePack="true" /> <_BoolPropertiesThatTriggerRelinking Include="WasmNativeStrip" DefaultValueInRuntimePack="true" /> @@ -278,7 +275,6 @@ $(EmccInitialHeapSize) 5MB false - true $(EmscriptenUpstreamEmscriptenPath)emcc @@ -310,7 +306,6 @@ <_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="-DENABLE_JS_INTEROP_BY_VALUE=1" Condition="'$(WasmEnableJsInteropByValue)' == 'true'" /> <_EmccCFlags Include="-DGEN_PINVOKE=1" /> @@ -356,8 +351,6 @@ - - diff --git a/src/mono/browser/build/ILLink.Substitutions.LegacyJsInterop.xml b/src/mono/browser/build/ILLink.Substitutions.LegacyJsInterop.xml deleted file mode 100644 index 523a1d947c5f1..0000000000000 --- a/src/mono/browser/build/ILLink.Substitutions.LegacyJsInterop.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/mono/browser/build/README.md b/src/mono/browser/build/README.md index e1565c8359fe5..495e8020b76a5 100644 --- a/src/mono/browser/build/README.md +++ b/src/mono/browser/build/README.md @@ -32,8 +32,6 @@ Implementation: - *after* any of the wasm build targets, use `AfterTargets="WasmBuildApp"` on that target - Avoid depending on this target, because it is available only when the workload is installed. Use `$(WasmNativeWorkload)` to check if it is installed. -- When `Module.disableDotnet6Compatibility` is set it would not pollute global namespace. - ## `Publish` Implementation: diff --git a/src/mono/browser/runtime/CMakeLists.txt b/src/mono/browser/runtime/CMakeLists.txt index 64cdb841a349d..60570d6deafd6 100644 --- a/src/mono/browser/runtime/CMakeLists.txt +++ b/src/mono/browser/runtime/CMakeLists.txt @@ -3,7 +3,6 @@ cmake_minimum_required(VERSION 3.20) project(mono-wasm-runtime C) option(DISABLE_THREADS "defined if the build does NOT support multithreading" ON) -option(DISABLE_LEGACY_JS_INTEROP "defined if the build does not support legacy JavaScript interop" OFF) option(ENABLE_JS_INTEROP_BY_VALUE "defined when JS interop without pointers to managed objects" OFF) set(CMAKE_EXECUTABLE_SUFFIX ".js") diff --git a/src/mono/browser/runtime/corebindings.c b/src/mono/browser/runtime/corebindings.c index 4b52eb4badf22..9dc2efa3de77e 100644 --- a/src/mono/browser/runtime/corebindings.c +++ b/src/mono/browser/runtime/corebindings.c @@ -22,21 +22,6 @@ extern void mono_wasm_resolve_or_reject_promise(void *data); typedef void (*background_job_cb)(void); -#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); -extern void mono_wasm_get_by_index_ref (int js_handle, int property_index, int *is_exception, MonoObject **result); -extern void mono_wasm_set_by_index_ref (int js_handle, int property_index, MonoObject **value, int *is_exception, MonoObject **result); -extern void mono_wasm_get_global_object_ref (MonoString **global_name, int *is_exception, MonoObject **result); -extern void mono_wasm_typed_array_to_array_ref (int js_handle, int *is_exception, MonoObject **result); -extern void mono_wasm_create_cs_owned_object_ref (MonoString **core_name, MonoArray **args, int *is_exception, MonoObject** result); -extern void mono_wasm_typed_array_from_ref (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception, MonoObject** result); - -// 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 /* DISABLE_LEGACY_JS_INTEROP */ - #ifndef DISABLE_THREADS extern void mono_wasm_install_js_worker_interop (int context_gc_handle); extern void mono_wasm_uninstall_js_worker_interop (); @@ -87,21 +72,6 @@ void bindings_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::InvokeJSFunction", mono_wasm_invoke_js_function); #endif /* DISABLE_THREADS */ -#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); - mono_add_internal_call ("Interop/Runtime::SetObjectPropertyRef", mono_wasm_set_object_property_ref); - mono_add_internal_call ("Interop/Runtime::GetByIndexRef", mono_wasm_get_by_index_ref); - mono_add_internal_call ("Interop/Runtime::SetByIndexRef", mono_wasm_set_by_index_ref); - mono_add_internal_call ("Interop/Runtime::GetGlobalObjectRef", mono_wasm_get_global_object_ref); - mono_add_internal_call ("Interop/Runtime::TypedArrayToArrayRef", mono_wasm_typed_array_to_array_ref); - mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); - mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); - - // 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 /* 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/browser/runtime/cwraps.ts b/src/mono/browser/runtime/cwraps.ts index 0a3f2e0894cd1..180bbd5ccc2c1 100644 --- a/src/mono/browser/runtime/cwraps.ts +++ b/src/mono/browser/runtime/cwraps.ts @@ -2,36 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import type { - MonoArray, MonoAssembly, MonoClass, + MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments } from "./types/internal"; import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; -import { linkerDisableLegacyJsInterop, linkerEnableAotProfiler, linkerEnableBrowserProfiler, Module } from "./globals"; +import { linkerEnableAotProfiler, linkerEnableBrowserProfiler, Module } from "./globals"; import { mono_log_error } from "./logging"; import { mono_assert } from "./globals"; type SigLine = [lazyOrSkip: boolean | (() => boolean), name: string, returnType: string | null, argTypes?: string[], opts?: any]; -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"]], - [true, "mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], - [true, "mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]], - [true, "mono_wasm_string_array_new_ref", "void", ["number", "number"]], - [true, "mono_wasm_typed_array_new_ref", "void", ["number", "number", "number", "number", "number"]], - [true, "mono_wasm_get_delegate_invoke_ref", "number", ["number"]], - [true, "mono_wasm_get_type_name", "string", ["number"]], - [true, "mono_wasm_get_type_aqn", "string", ["number"]], - [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"]], -] : []; - const threading_cwraps: SigLine[] = MonoWasmThreads ? [ // MONO.diagnostics [true, "mono_wasm_event_pipe_enable", "bool", ["string", "number", "number", "string", "bool", "number"]], @@ -46,7 +29,6 @@ const threading_cwraps: SigLine[] = MonoWasmThreads ? [ // 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[] = [ - // MONO [true, "mono_wasm_register_root", "number", ["number", "number", "string"]], [true, "mono_wasm_deregister_root", null, ["number"]], [true, "mono_wasm_string_get_data_ref", null, ["number", "number", "number", "number"]], @@ -64,7 +46,6 @@ const fn_signatures: SigLine[] = [ [false, "mono_wasm_load_runtime", null, ["string", "number"]], [true, "mono_wasm_change_debugger_log_level", "void", ["number"]], - // BINDING [true, "mono_wasm_get_corlib", "number", []], [true, "mono_wasm_assembly_load", "number", ["string"]], [true, "mono_wasm_assembly_find_class", "number", ["number", "string", "string"]], @@ -76,7 +57,6 @@ const fn_signatures: SigLine[] = [ [true, "mono_wasm_assembly_get_entry_point", "number", ["number", "number"]], [true, "mono_wasm_class_get_type", "number", ["number"]], - //INTERNAL [false, "mono_wasm_exit", "void", ["number"]], [false, "mono_wasm_abort", "void", []], [true, "mono_wasm_getenv", "number", ["string"]], @@ -155,26 +135,8 @@ const fn_signatures: SigLine[] = [ [true, "mono_interp_pgo_save_table", "number", ["number", "number"]], ...threading_cwraps, - ...legacy_interop_cwraps, ]; -export interface t_LegacyCwraps { - // legacy interop - mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; - mono_wasm_obj_array_new_ref(size: number, result: MonoObjectRef): void; - mono_wasm_obj_array_set_ref(array: MonoObjectRef, idx: number, obj: MonoObjectRef): void; - mono_wasm_try_unbox_primitive_and_get_type_ref(obj: MonoObjectRef, buffer: VoidPtr, buffer_size: number): number; - mono_wasm_box_primitive_ref(klass: MonoClass, value: VoidPtr, value_size: number, result: MonoObjectRef): void; - mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; - mono_wasm_typed_array_new_ref(arr: VoidPtr, length: number, size: number, type: number, result: MonoObjectRef): void; - mono_wasm_get_delegate_invoke_ref(delegate: MonoObjectRef): MonoMethod; - mono_wasm_get_type_name(ty: MonoType): string; - mono_wasm_get_type_aqn(ty: MonoType): string; - mono_wasm_obj_array_new(size: number): MonoArray; - mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; - mono_wasm_array_length_ref(array: MonoObjectRef): number; -} - export interface t_ThreadingCwraps { // MONO.diagnostics mono_wasm_event_pipe_enable(outputPath: string | null, stream: VoidPtr, bufferSizeInMB: number, providers: string, rundownRequested: boolean, outSessionId: VoidPtr): boolean; @@ -193,7 +155,6 @@ export interface t_ProfilerCwraps { } export interface t_Cwraps { - // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; mono_wasm_deregister_root(addr: VoidPtr): void; mono_wasm_string_get_data_ref(stringRef: MonoStringRef, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; @@ -211,7 +172,6 @@ export interface t_Cwraps { mono_wasm_load_runtime(unused: string, debugLevel: number): void; mono_wasm_change_debugger_log_level(value: number): void; - // BINDING mono_wasm_get_corlib(): MonoAssembly; mono_wasm_assembly_load(name: string): MonoAssembly; mono_wasm_assembly_find_class(assembly: MonoAssembly, namespace: string, name: string): MonoClass; @@ -222,7 +182,6 @@ export interface t_Cwraps { mono_wasm_assembly_get_entry_point(assembly: MonoAssembly, idx: number): MonoMethod; mono_wasm_intern_string_ref(strRef: MonoStringRef): void; - //INTERNAL mono_wasm_exit(exit_code: number): void; mono_wasm_abort(): void; mono_wasm_getenv(name: string): CharPtr; @@ -308,7 +267,6 @@ export interface t_Cwraps { const wrapped_c_functions: t_Cwraps = {}; export default wrapped_c_functions; -export const legacy_c_functions: t_LegacyCwraps & t_Cwraps = wrapped_c_functions as any; export const threads_c_functions: t_ThreadingCwraps & t_Cwraps = wrapped_c_functions as any; export const profiler_c_functions: t_ProfilerCwraps & t_Cwraps = wrapped_c_functions as any; @@ -353,8 +311,7 @@ function cwrap(name: string, returnType: string | null, argTypes: string[] | und } export function init_c_exports(): void { - const lfns = WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop ? legacy_interop_cwraps : []; - const fns = [...fn_signatures, ...lfns]; + const fns = [...fn_signatures]; for (const sig of fns) { const wf: any = wrapped_c_functions; const [lazyOrSkip, name, returnType, argTypes, opts] = sig; diff --git a/src/mono/browser/runtime/dotnet-legacy.d.ts b/src/mono/browser/runtime/dotnet-legacy.d.ts deleted file mode 100644 index ede3f4a2231c5..0000000000000 --- a/src/mono/browser/runtime/dotnet-legacy.d.ts +++ /dev/null @@ -1,295 +0,0 @@ -//! Licensed to the .NET Foundation under one or more agreements. -//! The .NET Foundation licenses this file to you under the MIT license. -//! -//! This is generated file, see src/mono/wasm/runtime/rollup.config.js - -//! This is not considered public API with backward compatibility guarantees. - -declare interface ManagedPointer { - __brandManagedPointer: "ManagedPointer"; -} -declare interface NativePointer { - __brandNativePointer: "NativePointer"; -} -declare interface VoidPtr extends NativePointer { - __brand: "VoidPtr"; -} - -interface MonoObject extends ManagedPointer { - __brandMonoObject: "MonoObject"; -} -interface MonoString extends MonoObject { - __brand: "MonoString"; -} -interface MonoArray extends MonoObject { - __brand: "MonoArray"; -} -interface MonoObjectRef extends ManagedPointer { - __brandMonoObjectRef: "MonoObjectRef"; -} -type MemOffset = number | VoidPtr | NativePointer | ManagedPointer; -type NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer; -interface WasmRoot { - get_address(): MonoObjectRef; - get_address_32(): number; - get address(): MonoObjectRef; - get(): T; - set(value: T): T; - get value(): T; - set value(value: T); - copy_from_address(source: MonoObjectRef): void; - copy_to_address(destination: MonoObjectRef): void; - copy_from(source: WasmRoot): void; - copy_to(destination: WasmRoot): void; - valueOf(): T; - clear(): void; - release(): void; - toString(): string; -} -interface WasmRootBuffer { - get_address(index: number): MonoObjectRef; - get_address_32(index: number): number; - get(index: number): ManagedPointer; - set(index: number, value: ManagedPointer): ManagedPointer; - copy_value_from_address(index: number, sourceAddress: MonoObjectRef): void; - clear(): void; - release(): void; - toString(): string; -} - -/** - * @deprecated Please use methods in top level API object instead - */ -type BINDINGType = { - /** - * @deprecated Please use [JSExportAttribute] instead - */ - bind_static_method: (fqn: string, signature?: string) => Function; - /** - * @deprecated Please use runMain() instead - */ - call_assembly_entry_point: (assembly: string, args?: any[], signature?: string) => number; - /** - * @deprecated Not GC or thread safe - */ - mono_obj_array_new: (size: number) => MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void; - /** - * @deprecated Not GC or thread safe - */ - js_string_to_mono_string: (string: string) => MonoString; - /** - * @deprecated Not GC or thread safe - */ - js_typed_array_to_array: (js_obj: any) => MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_array_to_js_array: (mono_array: MonoArray) => any[] | null; - /** - * @deprecated Not GC or thread safe - */ - js_to_mono_obj: (js_obj: any) => MonoObject; - /** - * @deprecated Not GC or thread safe - */ - conv_string: (mono_obj: MonoString) => string | null; - /** - * @deprecated Not GC or thread safe - */ - unbox_mono_obj: (mono_obj: MonoObject) => any; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_string_to_mono_string_root: (string: string, result: WasmRoot) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_typed_array_to_array_root: (js_obj: any, result: WasmRoot) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_to_mono_obj_root: (js_obj: any, result: WasmRoot, should_add_in_flight: boolean) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - conv_string_root: (root: WasmRoot) => string | null; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - unbox_mono_obj_root: (root: WasmRoot) => any; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_array_root_to_js_array: (arrayRoot: WasmRoot) => any[] | null; -}; -/** - * @deprecated Please use methods in top level API object instead - */ -type MONOType = { - /** - * @deprecated Please use setEnvironmentVariable() instead - */ - mono_wasm_setenv: (name: string, value: string) => void; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_bytes_into_heap: (bytes: Uint8Array) => VoidPtr; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_icu_data: (offset: VoidPtr) => boolean; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_runtime_ready: () => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_root_buffer: (capacity: number, name?: string) => WasmRootBuffer; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_root: (value?: T | undefined) => WasmRoot; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_external_root: (address: VoidPtr | MonoObjectRef) => WasmRoot; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_release_roots: (...args: WasmRoot[]) => void; - /** - * @deprecated Please use runMain instead - */ - mono_run_main: (main_assembly_name: string, args: string[]) => Promise; - /** - * @deprecated Please use runMainAndExit instead - */ - mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_runtime: (unused: string, debugLevel: number) => void; - /** - * @deprecated Please use getConfig() instead - */ - config: any; - /** - * @deprecated Please use config.assets instead - */ - loaded_files: string[]; - /** - * @deprecated Please use setHeapB32 - */ - setB32: (offset: MemOffset, value: number | boolean) => void; - /** - * @deprecated Please use setHeapI8 - */ - setI8: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI16 - */ - setI16: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI32 - */ - setI32: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI52 - */ - setI52: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU52 - */ - setU52: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI64Big - */ - setI64Big: (offset: MemOffset, value: bigint) => void; - /** - * @deprecated Please use setHeapU8 - */ - setU8: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU16 - */ - setU16: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU32 - */ - setU32: (offset: MemOffset, value: NumberOrPointer) => void; - /** - * @deprecated Please use setHeapF32 - */ - setF32: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapF64 - */ - setF64: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use getHeapB32 - */ - getB32: (offset: MemOffset) => boolean; - /** - * @deprecated Please use getHeapI8 - */ - getI8: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI16 - */ - getI16: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI32 - */ - getI32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI52 - */ - getI52: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU52 - */ - getU52: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI64Big - */ - getI64Big: (offset: MemOffset) => bigint; - /** - * @deprecated Please use getHeapU8 - */ - getU8: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU16 - */ - getU16: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU32 - */ - getU32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapF32 - */ - getF32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapF64 - */ - getF64: (offset: MemOffset) => number; -}; - -export { BINDINGType, MONOType, MonoArray, MonoObject, MonoString }; diff --git a/src/mono/browser/runtime/dotnet.d.ts b/src/mono/browser/runtime/dotnet.d.ts index 5dde3a3e265ca..3670e7c42389d 100644 --- a/src/mono/browser/runtime/dotnet.d.ts +++ b/src/mono/browser/runtime/dotnet.d.ts @@ -18,24 +18,6 @@ declare interface Int32Ptr extends NativePointer { __brand: "Int32Ptr"; } declare interface EmscriptenModule { - /** @deprecated Please use localHeapViewI8() instead.*/ - HEAP8: Int8Array; - /** @deprecated Please use localHeapViewI16() instead.*/ - HEAP16: Int16Array; - /** @deprecated Please use localHeapViewI32() instead. */ - HEAP32: Int32Array; - /** @deprecated Please use localHeapViewI64() instead. */ - HEAP64: BigInt64Array; - /** @deprecated Please use localHeapViewU8() instead. */ - HEAPU8: Uint8Array; - /** @deprecated Please use localHeapViewU16() instead. */ - HEAPU16: Uint16Array; - /** @deprecated Please use localHeapViewU32() instead */ - HEAPU32: Uint32Array; - /** @deprecated Please use localHeapViewF32() instead */ - HEAPF32: Float32Array; - /** @deprecated Please use localHeapViewF64() instead. */ - HEAPF64: Float64Array; _malloc(size: number): VoidPtr; _free(ptr: VoidPtr): void; out(message: string): void; @@ -378,7 +360,6 @@ declare const enum GlobalizationMode { Hybrid = "hybrid" } type DotnetModuleConfig = { - disableDotnet6Compatibility?: boolean; config?: MonoConfig; configSrc?: string; onConfigLoaded?: (config: MonoConfig) => void | Promise; @@ -430,14 +411,6 @@ type APIType = { localHeapViewF64: () => Float64Array; }; type RuntimeAPI = { - /** - * @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts - */ - MONO: any; - /** - * @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts - */ - BINDING: any; INTERNAL: any; Module: EmscriptenModule; runtimeId: number; diff --git a/src/mono/browser/runtime/driver.c b/src/mono/browser/runtime/driver.c index a48e77894018e..47ca561e7c240 100644 --- a/src/mono/browser/runtime/driver.c +++ b/src/mono/browser/runtime/driver.c @@ -52,64 +52,6 @@ extern void mono_bundled_resources_add_assembly_resource (const char *id, const extern void mono_bundled_resources_add_assembly_symbol_resource (const char *id, const uint8_t *data, uint32_t size, void (*free_func)(void *, void *), void *free_data); extern void mono_bundled_resources_add_satellite_assembly_resource (const char *id, const char *name, const char *culture, const uint8_t *data, uint32_t size, void (*free_func)(void *, void*), void *free_data); -#ifndef DISABLE_LEGACY_JS_INTEROP - -#define MARSHAL_TYPE_NULL 0 -#define MARSHAL_TYPE_INT 1 -#define MARSHAL_TYPE_FP64 2 -#define MARSHAL_TYPE_STRING 3 -#define MARSHAL_TYPE_VT 4 -#define MARSHAL_TYPE_DELEGATE 5 -#define MARSHAL_TYPE_TASK 6 -#define MARSHAL_TYPE_OBJECT 7 -#define MARSHAL_TYPE_BOOL 8 -#define MARSHAL_TYPE_ENUM 9 -#define MARSHAL_TYPE_DATE 20 -#define MARSHAL_TYPE_DATEOFFSET 21 -#define MARSHAL_TYPE_URI 22 -#define MARSHAL_TYPE_SAFEHANDLE 23 - -// typed array marshaling -#define MARSHAL_ARRAY_BYTE 10 -#define MARSHAL_ARRAY_UBYTE 11 -#define MARSHAL_ARRAY_UBYTE_C 12 -#define MARSHAL_ARRAY_SHORT 13 -#define MARSHAL_ARRAY_USHORT 14 -#define MARSHAL_ARRAY_INT 15 -#define MARSHAL_ARRAY_UINT 16 -#define MARSHAL_ARRAY_FLOAT 17 -#define MARSHAL_ARRAY_DOUBLE 18 - -#define MARSHAL_TYPE_FP32 24 -#define MARSHAL_TYPE_UINT32 25 -#define MARSHAL_TYPE_INT64 26 -#define MARSHAL_TYPE_UINT64 27 -#define MARSHAL_TYPE_CHAR 28 -#define MARSHAL_TYPE_STRING_INTERNED 29 -#define MARSHAL_TYPE_VOID 30 -#define MARSHAL_TYPE_POINTER 32 - -// errors -#define MARSHAL_ERROR_BUFFER_TOO_SMALL 512 -#define MARSHAL_ERROR_NULL_CLASS_POINTER 513 -#define MARSHAL_ERROR_NULL_TYPE_POINTER 514 - -static MonoClass* datetime_class; -static MonoClass* datetimeoffset_class; -static MonoClass* uri_class; -static MonoClass* task_class; -static MonoClass* safehandle_class; -static MonoClass* voidtaskresult_class; - -static int resolved_datetime_class = 0, - resolved_datetimeoffset_class = 0, - resolved_uri_class = 0, - resolved_task_class = 0, - resolved_safehandle_class = 0, - resolved_voidtaskresult_class = 0; - -#endif /* DISABLE_LEGACY_JS_INTEROP */ - int mono_string_instance_is_interned (MonoString *str_raw); @@ -421,470 +363,6 @@ mono_wasm_string_from_utf16_ref (const mono_unichar2 * chars, int length, MonoSt MONO_EXIT_GC_UNSAFE; } -#ifndef DISABLE_LEGACY_JS_INTEROP - -static int -class_is_task (MonoClass *klass) -{ - if (!klass) - return 0; - - int result; - MONO_ENTER_GC_UNSAFE; - if (!task_class && !resolved_task_class) { - task_class = mono_class_from_name (mono_get_corlib(), "System.Threading.Tasks", "Task"); - resolved_task_class = 1; - } - - result = task_class && (klass == task_class || mono_class_is_subclass_of(klass, task_class, 0)); - MONO_EXIT_GC_UNSAFE; - return result; -} - -static MonoClass* -_get_uri_class(MonoException** exc) -{ - MonoAssembly* assembly = mono_wasm_assembly_load ("System"); - if (!assembly) - return NULL; - MonoClass* klass = mono_wasm_assembly_find_class(assembly, "System", "Uri"); - return klass; -} - -static void -_ensure_classes_resolved (void) -{ - MONO_ENTER_GC_UNSAFE; - if (!datetime_class && !resolved_datetime_class) { - datetime_class = mono_class_from_name (mono_get_corlib(), "System", "DateTime"); - resolved_datetime_class = 1; - } - if (!datetimeoffset_class && !resolved_datetimeoffset_class) { - datetimeoffset_class = mono_class_from_name (mono_get_corlib(), "System", "DateTimeOffset"); - resolved_datetimeoffset_class = 1; - } - if (!uri_class && !resolved_uri_class) { - PVOLATILE(MonoException) exc = NULL; - uri_class = _get_uri_class((MonoException **)&exc); - resolved_uri_class = 1; - } - if (!safehandle_class && !resolved_safehandle_class) { - safehandle_class = mono_class_from_name (mono_get_corlib(), "System.Runtime.InteropServices", "SafeHandle"); - resolved_safehandle_class = 1; - } - if (!voidtaskresult_class && !resolved_voidtaskresult_class) { - voidtaskresult_class = mono_class_from_name (mono_get_corlib(), "System.Threading.Tasks", "VoidTaskResult"); - resolved_voidtaskresult_class = 1; - } - MONO_EXIT_GC_UNSAFE; -} - -// This must be run inside a GC unsafe region -static int -_marshal_type_from_mono_type (int mono_type, MonoClass *klass, MonoType *type) -{ - switch (mono_type) { - // case MONO_TYPE_CHAR: prob should be done not as a number? - case MONO_TYPE_VOID: - return MARSHAL_TYPE_VOID; - case MONO_TYPE_BOOLEAN: - return MARSHAL_TYPE_BOOL; - case MONO_TYPE_I: // IntPtr - case MONO_TYPE_U: // UIntPtr - case MONO_TYPE_PTR: - return MARSHAL_TYPE_POINTER; - case MONO_TYPE_I1: - case MONO_TYPE_I2: - case MONO_TYPE_I4: - return MARSHAL_TYPE_INT; - case MONO_TYPE_CHAR: - return MARSHAL_TYPE_CHAR; - case MONO_TYPE_U1: - case MONO_TYPE_U2: - case MONO_TYPE_U4: // The distinction between this and signed int is - // important due to how numbers work in JavaScript - return MARSHAL_TYPE_UINT32; - case MONO_TYPE_I8: - return MARSHAL_TYPE_INT64; - case MONO_TYPE_U8: - return MARSHAL_TYPE_UINT64; - case MONO_TYPE_R4: - return MARSHAL_TYPE_FP32; - case MONO_TYPE_R8: - return MARSHAL_TYPE_FP64; - case MONO_TYPE_STRING: - return MARSHAL_TYPE_STRING; - case MONO_TYPE_SZARRAY: { // simple zero based one-dim-array - if (klass) { - MonoClass *eklass = mono_class_get_element_class (klass); - MonoType *etype = mono_class_get_type (eklass); - - switch (mono_type_get_type (etype)) { - case MONO_TYPE_U1: - return MARSHAL_ARRAY_UBYTE; - case MONO_TYPE_I1: - return MARSHAL_ARRAY_BYTE; - case MONO_TYPE_U2: - return MARSHAL_ARRAY_USHORT; - case MONO_TYPE_I2: - return MARSHAL_ARRAY_SHORT; - case MONO_TYPE_U4: - return MARSHAL_ARRAY_UINT; - case MONO_TYPE_I4: - return MARSHAL_ARRAY_INT; - case MONO_TYPE_R4: - return MARSHAL_ARRAY_FLOAT; - case MONO_TYPE_R8: - return MARSHAL_ARRAY_DOUBLE; - default: - return MARSHAL_TYPE_OBJECT; - } - } else { - return MARSHAL_TYPE_OBJECT; - } - } - default: - _ensure_classes_resolved (); - - if (klass) { - if (klass == datetime_class) - return MARSHAL_TYPE_DATE; - if (klass == datetimeoffset_class) - return MARSHAL_TYPE_DATEOFFSET; - if (uri_class && mono_class_is_assignable_from(uri_class, klass)) - return MARSHAL_TYPE_URI; - if (klass == voidtaskresult_class) - return MARSHAL_TYPE_VOID; - if (mono_class_is_enum (klass)) - return MARSHAL_TYPE_ENUM; - if (type && !mono_type_is_reference (type)) //vt - return MARSHAL_TYPE_VT; - if (mono_class_is_delegate (klass)) - return MARSHAL_TYPE_DELEGATE; - if (class_is_task(klass)) - return MARSHAL_TYPE_TASK; - if (safehandle_class && (klass == safehandle_class || mono_class_is_subclass_of(klass, safehandle_class, 0))) - return MARSHAL_TYPE_SAFEHANDLE; - } - - return MARSHAL_TYPE_OBJECT; - } -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, PPVOLATILE(MonoArray) result) -{ - MONO_ENTER_GC_UNSAFE; - MonoClass * typeClass = mono_get_byte_class(); // default is Byte - switch (type) { - case MARSHAL_ARRAY_BYTE: - typeClass = mono_get_sbyte_class(); - break; - case MARSHAL_ARRAY_SHORT: - typeClass = mono_get_int16_class(); - break; - case MARSHAL_ARRAY_USHORT: - typeClass = mono_get_uint16_class(); - break; - case MARSHAL_ARRAY_INT: - typeClass = mono_get_int32_class(); - break; - case MARSHAL_ARRAY_UINT: - typeClass = mono_get_uint32_class(); - break; - case MARSHAL_ARRAY_FLOAT: - typeClass = mono_get_single_class(); - break; - case MARSHAL_ARRAY_DOUBLE: - typeClass = mono_get_double_class(); - break; - case MARSHAL_ARRAY_UBYTE: - case MARSHAL_ARRAY_UBYTE_C: - typeClass = mono_get_byte_class(); - break; - default: - printf ("Invalid marshal type %d in mono_wasm_typed_array_new", type); - abort(); - } - - PVOLATILE(MonoArray) buffer; - - buffer = mono_array_new (mono_get_root_domain(), typeClass, length); - memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); - - store_volatile((PPVOLATILE(MonoObject))result, (MonoObject *)buffer); - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE MonoMethod* -mono_wasm_get_delegate_invoke_ref (MonoObject **delegate) -{ - MonoMethod * result; - MONO_ENTER_GC_UNSAFE; - result = mono_get_delegate_invoke(mono_object_get_class (*delegate)); - MONO_EXIT_GC_UNSAFE; - return result; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_box_primitive_ref (MonoClass *klass, void *value, int value_size, PPVOLATILE(MonoObject) result) -{ - assert (klass); - - MONO_ENTER_GC_UNSAFE; - MonoType *type = mono_class_get_type (klass); - int alignment; - - if (mono_type_size (type, &alignment) <= value_size) - // TODO: use mono_value_box_checked and propagate error out - store_volatile(result, mono_value_box (root_domain, klass, value)); - - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE char * -mono_wasm_get_type_name (MonoType * typePtr) { - return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_REFLECTION); -} - -EMSCRIPTEN_KEEPALIVE char * -mono_wasm_get_type_aqn (MonoType * typePtr) { - return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED); -} - -// this will return bool value if the object is a bool, otherwise it will return -1 or error -EMSCRIPTEN_KEEPALIVE int -mono_wasm_read_as_bool_or_null_unsafe (PVOLATILE(MonoObject) obj) { - - int result = -1; - - MONO_ENTER_GC_UNSAFE; - - MonoClass *klass = mono_object_get_class (obj); - if (!klass) { - goto end; - } - - MonoType *type = mono_class_get_type (klass); - if (!type) { - goto end; - } - - int mono_type = mono_type_get_type (type); - if (MONO_TYPE_BOOLEAN == mono_type) { - result = ((signed char*)mono_object_unbox (obj) == 0 ? 0 : 1); - } - - end: - MONO_EXIT_GC_UNSAFE; - return result; -} - -// This code runs inside a gc unsafe region -static int -_mono_wasm_try_unbox_primitive_and_get_type_ref_impl (PVOLATILE(MonoObject) obj, void *result, int result_capacity) { - void **resultP = result; - int *resultI = result; - uint32_t *resultU = result; - int64_t *resultL = result; - float *resultF = result; - double *resultD = result; - - /* Process obj before calling into the runtime, class_from_name () can invoke managed code */ - MonoClass *klass = mono_object_get_class (obj); - if (!klass) - return MARSHAL_ERROR_NULL_CLASS_POINTER; - - MonoType *type = mono_class_get_type (klass), *original_type = type; - if (!type) - return MARSHAL_ERROR_NULL_TYPE_POINTER; - - if ((klass == mono_get_string_class ()) && - mono_string_instance_is_interned ((MonoString *)obj)) { - *resultL = 0; - *resultP = type; - return MARSHAL_TYPE_STRING_INTERNED; - } - - if (mono_class_is_enum (klass)) - type = mono_type_get_underlying_type (type); - - if (!type) - return MARSHAL_ERROR_NULL_TYPE_POINTER; - - int mono_type = mono_type_get_type (type); - - if (mono_type == MONO_TYPE_GENERICINST) { - // HACK: While the 'any other type' fallback is valid for classes, it will do the - // wrong thing for structs, so we need to make sure the valuetype handler is used - if (mono_type_generic_inst_is_valuetype (type)) - mono_type = MONO_TYPE_VALUETYPE; - } - - // FIXME: We would prefer to unbox once here but it will fail if the value isn't unboxable - - switch (mono_type) { - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - *resultI = *(signed char*)mono_object_unbox (obj); - break; - case MONO_TYPE_U1: - *resultU = *(unsigned char*)mono_object_unbox (obj); - break; - case MONO_TYPE_I2: - case MONO_TYPE_CHAR: - *resultI = *(short*)mono_object_unbox (obj); - break; - case MONO_TYPE_U2: - *resultU = *(unsigned short*)mono_object_unbox (obj); - break; - case MONO_TYPE_I4: - case MONO_TYPE_I: - *resultI = *(int*)mono_object_unbox (obj); - break; - case MONO_TYPE_U4: - *resultU = *(uint32_t*)mono_object_unbox (obj); - break; - case MONO_TYPE_R4: - *resultF = *(float*)mono_object_unbox (obj); - break; - case MONO_TYPE_R8: - *resultD = *(double*)mono_object_unbox (obj); - break; - case MONO_TYPE_PTR: - *resultU = (uint32_t)(*(void**)mono_object_unbox (obj)); - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - // FIXME: At present the javascript side of things can't handle this, - // but there's no reason not to future-proof this API - *resultL = *(int64_t*)mono_object_unbox (obj); - break; - case MONO_TYPE_VALUETYPE: - { - int obj_size = mono_object_get_size (obj), - required_size = (sizeof (int)) + (sizeof (MonoType *)) + obj_size; - - // Check whether this struct has special-case marshaling - // FIXME: Do we need to null out obj before this? - int marshal_type = _marshal_type_from_mono_type (mono_type, klass, original_type); - if (marshal_type != MARSHAL_TYPE_VT) - return marshal_type; - - // Check whether the result buffer is big enough for the struct and padding - if (result_capacity < required_size) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - // Store a header before the struct data with the size of the data and its MonoType - *resultP = type; - int * resultSize = (int *)(resultP + 1); - *resultSize = obj_size; - void * resultVoid = (resultP + 2); - void * unboxed = mono_object_unbox (obj); - memcpy (resultVoid, unboxed, obj_size); - return MARSHAL_TYPE_VT; - } - break; - default: - // If we failed to do a fast unboxing, return the original type information so - // that the caller can do a proper, slow unboxing later - // HACK: Store the class pointer into the result buffer so our caller doesn't - // have to call back into the native runtime later to get it - *resultP = type; - int fallbackResultType = _marshal_type_from_mono_type (mono_type, klass, original_type); - assert (fallbackResultType != MARSHAL_TYPE_VT); - return fallbackResultType; - } - - // We successfully performed a fast unboxing here so use the type information - // matching what we unboxed (i.e. an enum's underlying type instead of its type) - int resultType = _marshal_type_from_mono_type (mono_type, klass, type); - assert (resultType != MARSHAL_TYPE_VT); - return resultType; -} - -EMSCRIPTEN_KEEPALIVE int -mono_wasm_try_unbox_primitive_and_get_type_ref (MonoObject **objRef, void *result, int result_capacity) -{ - if (!result) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - int retval; - int *resultI = result; - int64_t *resultL = result; - - if (result_capacity >= sizeof (int64_t)) - *resultL = 0; - else if (result_capacity >= sizeof (int)) - *resultI = 0; - - if (result_capacity < 16) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - if (!objRef || !(*objRef)) - return MARSHAL_TYPE_NULL; - - MONO_ENTER_GC_UNSAFE; - retval = _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (*objRef, result, result_capacity); - MONO_EXIT_GC_UNSAFE; - return retval; -} - -EMSCRIPTEN_KEEPALIVE int -mono_wasm_array_length_ref (MonoArray **array) -{ - return mono_array_length (*array); -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_array_get_ref (PPVOLATILE(MonoArray) array, int idx, PPVOLATILE(MonoObject) result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic((void*)result, mono_array_get ((MonoArray*)*array, MonoObject*, idx)); - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_new_ref (int size, MonoArray **result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_object_class (), size)); - MONO_EXIT_GC_UNSAFE; -} - -// Deprecated -EMSCRIPTEN_KEEPALIVE MonoArray* -mono_wasm_obj_array_new (int size) -{ - PVOLATILE(MonoArray) result = NULL; - mono_wasm_obj_array_new_ref(size, (MonoArray **)&result); - return result; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj) -{ - mono_array_setref (array, idx, obj); -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_set_ref (MonoArray **array, int idx, MonoObject **obj) -{ - MONO_ENTER_GC_UNSAFE; - mono_array_setref (*array, idx, *obj); - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_string_array_new_ref (int size, MonoArray **result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_string_class (), size)); - MONO_EXIT_GC_UNSAFE; -} - -#endif /* DISABLE_LEGACY_JS_INTEROP */ - EMSCRIPTEN_KEEPALIVE int mono_wasm_exec_regression (int verbose_level, char *image) { @@ -1099,3 +577,32 @@ EMSCRIPTEN_KEEPALIVE int mono_wasm_is_zero_page_reserved () { // https://github.com/emscripten-core/emscripten/issues/19389 return (emscripten_stack_get_base() > 512) && (emscripten_stack_get_end() > 512); } + +// this will return bool value if the object is a bool, otherwise it will return -1 or error +// we use it in Blazor's renderBatch as internal only +EMSCRIPTEN_KEEPALIVE int +mono_wasm_read_as_bool_or_null_unsafe (PVOLATILE(MonoObject) obj) { + + int result = -1; + + MONO_ENTER_GC_UNSAFE; + + MonoClass *klass = mono_object_get_class (obj); + if (!klass) { + goto end; + } + + MonoType *type = mono_class_get_type (klass); + if (!type) { + goto end; + } + + int mono_type = mono_type_get_type (type); + if (MONO_TYPE_BOOLEAN == mono_type) { + result = ((signed char*)mono_object_unbox (obj) == 0 ? 0 : 1); + } + + end: + MONO_EXIT_GC_UNSAFE; + return result; +} \ No newline at end of file diff --git a/src/mono/browser/runtime/es6/dotnet.es6.lib.js b/src/mono/browser/runtime/es6/dotnet.es6.lib.js index 78fdc26dfaaac..0a9236a11d3ba 100644 --- a/src/mono/browser/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/browser/runtime/es6/dotnet.es6.lib.js @@ -7,7 +7,6 @@ // -- this javascript file is evaluated by emcc during compilation! -- // because we can't pass custom define symbols to acorn optimizer, we use environment variables to pass other build options -const DISABLE_LEGACY_JS_INTEROP = process.env.DISABLE_LEGACY_JS_INTEROP === "1"; const WASM_ENABLE_SIMD = process.env.WASM_ENABLE_SIMD === "1"; const WASM_ENABLE_EH = process.env.WASM_ENABLE_EH === "1"; const ENABLE_BROWSER_PROFILER = process.env.ENABLE_BROWSER_PROFILER === "1"; @@ -83,12 +82,7 @@ function injectDependencies() { createWasmImportStubsFrom(methodIndexByName.mono_wasm_threads_imports); #endif - if (!DISABLE_LEGACY_JS_INTEROP) { - createWasmImportStubsFrom(methodIndexByName.mono_wasm_legacy_interop_imports); - } - DotnetSupportLib["$DOTNET__postset"] = `DOTNET.setup({ ` + - `linkerDisableLegacyJsInterop: ${DISABLE_LEGACY_JS_INTEROP ? "true" : "false"},` + `linkerWasmEnableSIMD: ${WASM_ENABLE_SIMD ? "true" : "false"},` + `linkerWasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` + `linkerEnableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` + diff --git a/src/mono/browser/runtime/exports-binding.ts b/src/mono/browser/runtime/exports-binding.ts index 34d23af190d22..2f69b78b95fec 100644 --- a/src/mono/browser/runtime/exports-binding.ts +++ b/src/mono/browser/runtime/exports-binding.ts @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import { mono_wasm_debugger_log, mono_wasm_add_dbg_command_received, mono_wasm_set_entrypoint_breakpoint, mono_wasm_fire_debugger_agent_message_with_data, mono_wasm_fire_debugger_agent_message_with_data_to_pause } from "./debug"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; @@ -26,13 +25,6 @@ import { mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_starts_with, m import { mono_wasm_get_calendar_info } from "./hybrid-globalization/calendar"; import { mono_wasm_install_js_worker_interop, mono_wasm_uninstall_js_worker_interop } from "./pthreads/shared"; -import { - mono_wasm_invoke_js_blazor, mono_wasm_invoke_js_with_args_ref, mono_wasm_get_object_property_ref, mono_wasm_set_object_property_ref, - mono_wasm_get_by_index_ref, mono_wasm_set_by_index_ref, mono_wasm_get_global_object_ref -} from "./net6-legacy/method-calls"; -import { mono_wasm_create_cs_owned_object_ref } from "./net6-legacy/cs-to-js"; -import { mono_wasm_typed_array_to_array_ref } from "./net6-legacy/js-to-cs"; -import { mono_wasm_typed_array_from_ref } from "./net6-legacy/buffers"; import { mono_wasm_get_culture_info } from "./hybrid-globalization/culture-info"; import { mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year } from "./hybrid-globalization/locales"; import { mono_wasm_browser_entropy } from "./crypto"; @@ -57,20 +49,6 @@ export const mono_wasm_threads_imports = !MonoWasmThreads ? [] : [ mono_wasm_invoke_import_sync, ]; -export const mono_wasm_legacy_interop_imports = !WasmEnableLegacyJsInterop ? [] : [ - // corebindings.c - mono_wasm_invoke_js_with_args_ref, - mono_wasm_get_object_property_ref, - mono_wasm_set_object_property_ref, - mono_wasm_get_by_index_ref, - mono_wasm_set_by_index_ref, - mono_wasm_get_global_object_ref, - mono_wasm_create_cs_owned_object_ref, - mono_wasm_typed_array_to_array_ref, - mono_wasm_typed_array_from_ref, - mono_wasm_invoke_js_blazor, -]; - export const mono_wasm_imports = [ // mini-wasm.c mono_wasm_schedule_timer, @@ -127,8 +105,6 @@ const wasmImports: Function[] = [ ...mono_wasm_imports, // threading exports, if threading is enabled ...mono_wasm_threads_imports, - // legacy interop exports, if enabled - ...mono_wasm_legacy_interop_imports ]; export function replace_linker_placeholders(imports: WebAssembly.Imports) { diff --git a/src/mono/browser/runtime/exports-linker.ts b/src/mono/browser/runtime/exports-linker.ts index dd4ed9ec2233b..84e39b446155b 100644 --- a/src/mono/browser/runtime/exports-linker.ts +++ b/src/mono/browser/runtime/exports-linker.ts @@ -1,14 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_imports, mono_wasm_legacy_interop_imports, mono_wasm_threads_imports } from "./exports-binding"; +import { mono_wasm_imports, mono_wasm_threads_imports } from "./exports-binding"; import gitHash from "consts:gitHash"; export function export_linker_indexes_as_code(): string { const indexByName: any = { mono_wasm_imports: {}, mono_wasm_threads_imports: {}, - mono_wasm_legacy_interop_imports: {}, }; let idx = 0; for (const wi of mono_wasm_imports) { @@ -19,10 +18,6 @@ export function export_linker_indexes_as_code(): string { indexByName.mono_wasm_threads_imports[wi.name] = idx; idx++; } - for (const wi of mono_wasm_legacy_interop_imports) { - indexByName.mono_wasm_legacy_interop_imports[wi.name] = idx; - idx++; - } return ` var gitHash = "${gitHash}"; var methodIndexByName = ${JSON.stringify(indexByName, null, 2)}; diff --git a/src/mono/browser/runtime/exports.ts b/src/mono/browser/runtime/exports.ts index 35e03cf5db1a4..14032d5134a8d 100644 --- a/src/mono/browser/runtime/exports.ts +++ b/src/mono/browser/runtime/exports.ts @@ -3,11 +3,10 @@ import ProductVersion from "consts:productVersion"; import BuildConfiguration from "consts:configuration"; -import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import type { RuntimeAPI } from "./types"; -import { Module, linkerDisableLegacyJsInterop, exportedRuntimeAPI, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; -import { GlobalObjects, is_nullish } from "./types/internal"; +import { Module, exportedRuntimeAPI, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; +import { GlobalObjects } from "./types/internal"; import { configureEmscriptenStartup, configureRuntimeStartup, configureWorkerStartup } from "./startup"; import { create_weak_ref } from "./weak-ref"; @@ -15,11 +14,7 @@ import { export_internal } from "./exports-internal"; import { export_api } from "./export-api"; import { initializeReplacements } from "./polyfills"; -// legacy -import { mono_bind_static_method } from "./net6-legacy/method-calls"; -import { export_binding_api, export_internal_api, export_mono_api } from "./net6-legacy/exports-legacy"; -import { initializeLegacyExports } from "./net6-legacy/globals"; -import { mono_log_warn, mono_wasm_stringify_as_error_with_stack } from "./logging"; +import { mono_wasm_stringify_as_error_with_stack } from "./logging"; import { instantiate_asset, instantiate_symbols_asset, instantiate_segmentation_rules_asset } from "./assets"; import { jiterpreter_dump_stats } from "./jiterpreter"; import { forceDisposeProxies } from "./gc-handles"; @@ -29,16 +24,6 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { const globals = globalObjects; const globalThisAny = globalThis as any; - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - initializeLegacyExports(globals); - } - - // here we merge methods from the local objects into exported objects - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - Object.assign(globals.mono, export_mono_api()); - Object.assign(globals.binding, export_binding_api()); - Object.assign(globals.internal, export_internal_api()); - } Object.assign(globals.internal, export_internal()); Object.assign(runtimeHelpers, { stringify_as_error_with_stack: mono_wasm_stringify_as_error_with_stack, @@ -60,60 +45,6 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { }, ...API, }); - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - Object.assign(exportedRuntimeAPI, { - MONO: globals.mono, - BINDING: globals.binding, - }); - } - - if (typeof module.disableDotnet6Compatibility === "undefined") { - module.disableDotnet6Compatibility = true; - } - // here we expose objects global namespace for tests and backward compatibility - if (!module.disableDotnet6Compatibility) { - Object.assign(module, exportedRuntimeAPI); - - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - // backward compatibility - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - module.mono_bind_static_method = (fqn: string, signature: string/*ArgsMarshalString*/): Function => { - mono_log_warn("Module.mono_bind_static_method is obsolete, please use [JSExportAttribute] interop instead"); - return mono_bind_static_method(fqn, signature); - }; - } - - const warnWrap = (name: string, provider: () => any) => { - if (typeof globalThisAny[name] !== "undefined") { - // it already exists in the global namespace - return; - } - let value: any = undefined; - Object.defineProperty(globalThis, name, { - get: () => { - if (is_nullish(value)) { - const stack = (new Error()).stack; - const nextLine = stack ? stack.substr(stack.indexOf("\n", 8) + 1) : ""; - mono_log_warn(`global ${name} is obsolete, please use Module.${name} instead ${nextLine}`); - value = provider(); - } - return value; - } - }); - }; - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - globalThisAny.MONO = globals.mono; - globalThisAny.BINDING = globals.binding; - globalThisAny.INTERNAL = globals.internal; - } - globalThisAny.Module = module; - - // Blazor back compat - warnWrap("cwrap", () => module.cwrap); - warnWrap("addRunDependency", () => module.addRunDependency); - warnWrap("removeRunDependency", () => module.removeRunDependency); - } // this code makes it possible to find dotnet runtime on a page via global namespace, even when there are multiple runtimes at the same time let list: RuntimeList; diff --git a/src/mono/browser/runtime/globals.ts b/src/mono/browser/runtime/globals.ts index e9c051108dbb6..e8175488d02fc 100644 --- a/src/mono/browser/runtime/globals.ts +++ b/src/mono/browser/runtime/globals.ts @@ -28,8 +28,7 @@ export let ENVIRONMENT_IS_PTHREAD: boolean; export let exportedRuntimeAPI: RuntimeAPI = null as any; export let runtimeHelpers: RuntimeHelpers = null as any; export let loaderHelpers: LoaderHelpers = null as any; -// this is when we link with workload tools. The consts:wasmEnableLegacyJsInterop is when we compile with rollup. -export let linkerDisableLegacyJsInterop = false; + export let linkerWasmEnableSIMD = true; export let linkerWasmEnableEH = true; export let linkerEnableAotProfiler = false; @@ -39,7 +38,6 @@ export let _runtimeModuleLoaded = false; // please keep it in place also as roll export function passEmscriptenInternals(internals: EmscriptenInternals): void { ENVIRONMENT_IS_PTHREAD = internals.isPThread; - linkerDisableLegacyJsInterop = internals.linkerDisableLegacyJsInterop; linkerWasmEnableSIMD = internals.linkerWasmEnableSIMD; linkerWasmEnableEH = internals.linkerWasmEnableEH; linkerEnableAotProfiler = internals.linkerEnableAotProfiler; diff --git a/src/mono/browser/runtime/loader/globals.ts b/src/mono/browser/runtime/loader/globals.ts index fa07faabf0b6d..dde641c77ff33 100644 --- a/src/mono/browser/runtime/loader/globals.ts +++ b/src/mono/browser/runtime/loader/globals.ts @@ -70,7 +70,6 @@ export function setLoaderGlobals( }); Object.assign(globalObjects.module, { - disableDotnet6Compatibility: true, config: deep_merge_config(monoConfig, { environmentVariables: {} }), }); Object.assign(runtimeHelpers, { diff --git a/src/mono/browser/runtime/net6-legacy/buffers.ts b/src/mono/browser/runtime/net6-legacy/buffers.ts deleted file mode 100644 index d2b963ee58fde..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/buffers.ts +++ /dev/null @@ -1,114 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; -import { mono_wasm_new_external_root } from "../roots"; -import { MonoArray, MonoObjectRef, MonoObject } from "../types/internal"; -import { Int32Ptr, TypedArray } from "../types/emscripten"; -import { js_to_mono_obj_root } from "./js-to-cs"; -import { localHeapViewU8 } from "../memory"; - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function mono_wasm_typed_array_from_ref(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - const resultRoot = mono_wasm_new_external_root(result_address); - try { - const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type); - // returns JS typed array like Int8Array, to be wraped with JSObject proxy - js_to_mono_obj_root(res, resultRoot, true); - wrap_no_error_root(is_exception); - } catch (exc) { - wrap_error_root(is_exception, String(exc), resultRoot); - } finally { - resultRoot.release(); - } -} - -// Creates a new typed array from pinned array address from pinned_array allocated on the heap to the typed array. -// address of managed pinned array -> copy from heap -> typed array memory -function typed_array_from(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number) { - - // typed array - let newTypedArray: TypedArray | null = null; - - switch (type) { - case 5: - newTypedArray = new Int8Array(end - begin); - break; - case 6: - newTypedArray = new Uint8Array(end - begin); - break; - case 7: - newTypedArray = new Int16Array(end - begin); - break; - case 8: - newTypedArray = new Uint16Array(end - begin); - break; - case 9: - newTypedArray = new Int32Array(end - begin); - break; - case 10: - newTypedArray = new Uint32Array(end - begin); - break; - case 13: - newTypedArray = new Float32Array(end - begin); - break; - case 14: - newTypedArray = new Float64Array(end - begin); - break; - case 15: // This is a special case because the typed array is also byte[] - newTypedArray = new Uint8ClampedArray(end - begin); - break; - default: - throw new Error("Unknown array type " + type); - } - - typedarray_copy_from(newTypedArray, pinned_array, begin, end, bytes_per_element); - return newTypedArray; -} - -// Copy the pinned array address from pinned_array allocated on the heap to the typed array. -// address of managed pinned array -> copy from heap -> typed array memory -function typedarray_copy_from(typed_array: TypedArray, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number) { - - // JavaScript typed arrays are array-like objects and provide a mechanism for accessing - // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays - // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) - // is an object representing a chunk of data; it has no format to speak of, and offers no - // mechanism for accessing its contents. In order to access the memory contained in a buffer, - // you need to use a view. A view provides a context - that is, a data type, starting offset, - // and number of elements - that turns the data into an actual typed array. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays - if (has_backing_array_buffer(typed_array) && typed_array.BYTES_PER_ELEMENT) { - // Some sanity checks of what is being asked of us - // lets play it safe and throw an error here instead of assuming to much. - // Better safe than sorry later - if (bytes_per_element !== typed_array.BYTES_PER_ELEMENT) - throw new Error("Inconsistent element sizes: TypedArray.BYTES_PER_ELEMENT '" + typed_array.BYTES_PER_ELEMENT + "' sizeof managed element: '" + bytes_per_element + "'"); - - // how much space we have to work with - let num_of_bytes = (end - begin) * bytes_per_element; - // how much typed buffer space are we talking about - const view_bytes = typed_array.length * typed_array.BYTES_PER_ELEMENT; - // only use what is needed. - if (num_of_bytes > view_bytes) - num_of_bytes = view_bytes; - - // Create a new view for mapping - const typedarrayBytes = new Uint8Array(typed_array.buffer, 0, num_of_bytes); - // offset index into the view - const offset = begin * bytes_per_element; - // Set view bytes to value from HEAPU8 - typedarrayBytes.set(localHeapViewU8().subarray(pinned_array + offset, pinned_array + offset + num_of_bytes)); - return num_of_bytes; - } - else { - throw new Error("Object '" + typed_array + "' is not a typed array"); - } -} - - -export function has_backing_array_buffer(js_obj: TypedArray): boolean { - return typeof SharedArrayBuffer !== "undefined" - ? js_obj.buffer instanceof ArrayBuffer || js_obj.buffer instanceof SharedArrayBuffer - : js_obj.buffer instanceof ArrayBuffer; -} \ No newline at end of file diff --git a/src/mono/browser/runtime/net6-legacy/corebindings.ts b/src/mono/browser/runtime/net6-legacy/corebindings.ts deleted file mode 100644 index fd4d85aa02130..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/corebindings.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { JSHandle, GCHandle, MonoObjectRef, MonoMethod, MonoObject, WasmRoot, PromiseController } from "../types/internal"; -import { mono_bind_method, _create_primitive_converters } from "./method-binding"; -import { mono_wasm_new_root } from "../roots"; -import { Module, runtimeHelpers } from "../globals"; -import cwraps from "../cwraps"; -import { legacyHelpers, wasm_type_symbol } from "./globals"; -import { find_corlib_class } from "../class-loader"; -type SigLine = [lazy: boolean, jsname: string, csname: string, signature: string/*ArgsMarshalString*/]; -const fn_signatures: SigLine[] = [ - [true, "_get_cs_owned_object_by_js_handle_ref", "GetCSOwnedObjectByJSHandleRef", "iim"], - [true, "_get_cs_owned_object_js_handle_ref", "GetCSOwnedObjectJSHandleRef", "mi"], - [true, "_try_get_cs_owned_object_js_handle_ref", "TryGetCSOwnedObjectJSHandleRef", "mi"], - [true, "_create_cs_owned_proxy_ref", "CreateCSOwnedProxyRef", "iiim"], - - [true, "_get_js_owned_object_by_gc_handle_ref", "GetJSOwnedObjectByGCHandleRef", "im"], - [true, "_get_js_owned_object_gc_handle_ref", "GetJSOwnedObjectGCHandleRef", "m"], - - [true, "_create_tcs", "CreateTaskSource", ""], - [true, "_set_tcs_result_ref", "SetTaskSourceResultRef", "iR"], - [true, "_set_tcs_failure", "SetTaskSourceFailure", "is"], - [true, "_get_tcs_task_ref", "GetTaskSourceTaskRef", "im"], - [true, "_setup_js_cont_ref", "SetupJSContinuationRef", "mo"], - - [true, "_object_to_string_ref", "ObjectToStringRef", "m"], - [true, "_get_date_value_ref", "GetDateValueRef", "m"], - [true, "_create_date_time_ref", "CreateDateTimeRef", "dm"], - [true, "_create_uri_ref", "CreateUriRef", "sm"], - [true, "_is_simple_array_ref", "IsSimpleArrayRef", "m"], - [true, "_get_call_sig_ref", "GetCallSignatureRef", "im"], -]; - -export interface LegacyExports { - // see src\libraries\System.Runtime.InteropServices.JavaScript\src\System\Runtime\InteropServices\JavaScript\Interop\LegacyExports.cs - _get_cs_owned_object_by_js_handle_ref(jsHandle: JSHandle, shouldAddInflight: 0 | 1, result: MonoObjectRef): void; - _get_cs_owned_object_js_handle_ref(obj: MonoObjectRef, shouldAddInflight: 0 | 1): JSHandle; - _try_get_cs_owned_object_js_handle_ref(obj: MonoObjectRef, shouldAddInflight: 0 | 1): JSHandle; - _create_cs_owned_proxy_ref(jsHandle: JSHandle, mappedType: number, shouldAddInflight: 0 | 1, result: MonoObjectRef): void; - - _get_js_owned_object_by_gc_handle_ref(gcHandle: GCHandle, result: MonoObjectRef): void; - _get_js_owned_object_gc_handle_ref(obj: MonoObjectRef): GCHandle - - _create_tcs(): GCHandle; - _set_tcs_result_ref(gcHandle: GCHandle, result: any): void - _set_tcs_failure(gcHandle: GCHandle, result: string): void - _get_tcs_task_ref(gcHandle: GCHandle, result: MonoObjectRef): void; - _setup_js_cont_ref(task: MonoObjectRef, continuation: PromiseController): void; - - _object_to_string_ref(obj: MonoObjectRef): string; - _get_date_value_ref(obj: MonoObjectRef): number; - _create_date_time_ref(ticks: number, result: MonoObjectRef): void; - _create_uri_ref(uri: string, result: MonoObjectRef): void; - _is_simple_array_ref(obj: MonoObjectRef): boolean; - _get_call_sig_ref(method: MonoMethod, obj: WasmRoot): string; -} - -export const legacyManagedExports: LegacyExports = {}; - - -export function bind_runtime_method(method_name: string, signature: string): Function { - const method = get_method(method_name); - return mono_bind_method(method, signature, false, "BINDINGS_" + method_name); -} - -export function init_legacy_exports(): void { - // please keep System.Runtime.InteropServices.JavaScript.JSHostImplementation.MappedType in sync - (Object.prototype)[wasm_type_symbol] = 0; - (Array.prototype)[wasm_type_symbol] = 1; - (ArrayBuffer.prototype)[wasm_type_symbol] = 2; - (DataView.prototype)[wasm_type_symbol] = 3; - (Function.prototype)[wasm_type_symbol] = 4; - (Uint8Array.prototype)[wasm_type_symbol] = 11; - - const box_buffer_size = 65536; - legacyHelpers._unbox_buffer_size = 65536; - legacyHelpers._box_buffer = Module._malloc(box_buffer_size); - legacyHelpers._unbox_buffer = Module._malloc(legacyHelpers._unbox_buffer_size); - legacyHelpers._class_int32 = find_corlib_class("System", "Int32"); - legacyHelpers._class_uint32 = find_corlib_class("System", "UInt32"); - legacyHelpers._class_double = find_corlib_class("System", "Double"); - legacyHelpers._class_boolean = find_corlib_class("System", "Boolean"); - legacyHelpers._null_root = mono_wasm_new_root(); - _create_primitive_converters(); - - 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 + "." + legacyHelpers.runtime_legacy_exports_classname + " class"; - - for (const sig of fn_signatures) { - const wf: any = legacyManagedExports; - const [lazy, jsname, csname, signature] = sig; - if (lazy) { - // lazy init on first run - wf[jsname] = function (...args: any[]) { - const fce = bind_runtime_method(csname, signature); - wf[jsname] = fce; - return fce(...args); - }; - } - else { - const fce = bind_runtime_method(csname, signature); - wf[jsname] = fce; - } - } -} - -export function get_method(method_name: string): MonoMethod { - const res = cwraps.mono_wasm_assembly_find_method(legacyHelpers.runtime_legacy_exports_class, method_name, -1); - if (!res) - throw "Can't find method " + runtimeHelpers.runtime_interop_namespace + "." + legacyHelpers.runtime_legacy_exports_classname + "." + method_name; - return res; -} \ No newline at end of file diff --git a/src/mono/browser/runtime/net6-legacy/cs-to-js.ts b/src/mono/browser/runtime/net6-legacy/cs-to-js.ts deleted file mode 100644 index f93a3d13c53fd..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/cs-to-js.ts +++ /dev/null @@ -1,354 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { MarshalType, MonoType, MarshalError, MonoTypeNull, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, GCHandle, MonoStringRef, MonoObjectRef, MonoString, JSHandleDisposed, is_nullish, WasmRoot } from "../types/internal"; -import { _are_promises_supported } from "../cancelable-promise"; -import { legacy_c_functions as cwraps } from "../cwraps"; -import { mono_wasm_get_jsobj_from_js_handle, _lookup_js_owned_object, setup_managed_proxy, mono_wasm_get_js_handle, teardown_managed_proxy, assert_not_disposed } from "../gc-handles"; -import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; -import { ManagedObject } from "../marshal"; -import { getU32, getI32, getF32, getF64, setI32_unchecked } from "../memory"; -import { mono_wasm_new_root, mono_wasm_new_external_root } from "../roots"; -import { monoStringToString, monoStringToStringUnsafe } from "../strings"; -import { legacyManagedExports } from "./corebindings"; -import { legacyHelpers } from "./globals"; -import { js_to_mono_obj_root } from "./js-to-cs"; -import { assert_legacy_interop, mono_bind_method, mono_method_get_call_signature_ref } from "./method-binding"; -import { createPromiseController } from "../globals"; - -const delegate_invoke_symbol = Symbol.for("wasm delegate_invoke"); - -// this is only used from Blazor -export function unbox_mono_obj(mono_obj: MonoObject): any { - assert_legacy_interop(); - - if (mono_obj === MonoObjectNull) - return undefined; - - const root = mono_wasm_new_root(mono_obj); - try { - return unbox_mono_obj_root(root); - } finally { - root.release(); - } -} - -function _unbox_cs_owned_root_as_js_object(root: WasmRoot) { - // we don't need in-flight reference as we already have it rooted here - const js_handle = legacyManagedExports._get_cs_owned_object_js_handle_ref(root.address, 0); - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - return js_obj; -} - -// eslint-disable-next-line @typescript-eslint/no-unused-vars -function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot, type: MarshalType, typePtr: MonoType, unbox_buffer: VoidPtr): any { - //See MARSHAL_TYPE_ defines in driver.c - switch (type) { - case MarshalType.NULL: - return null; - case MarshalType.INT64: - case MarshalType.UINT64: - // TODO: Fix this once emscripten offers HEAPI64/HEAPU64 or can return them - throw new Error("int64 not available"); - case MarshalType.STRING: - case MarshalType.STRING_INTERNED: - return monoStringToString(root); - case MarshalType.VT: - throw new Error("no idea on how to unbox value types"); - case MarshalType.DELEGATE: - return _wrap_delegate_root_as_function(root); - case MarshalType.TASK: - return _unbox_task_root_as_promise(root); - case MarshalType.OBJECT: - return _unbox_ref_type_root_as_js_object(root); - case MarshalType.ARRAY_BYTE: - case MarshalType.ARRAY_UBYTE: - case MarshalType.ARRAY_UBYTE_C: - case MarshalType.ARRAY_SHORT: - case MarshalType.ARRAY_USHORT: - case MarshalType.ARRAY_INT: - case MarshalType.ARRAY_UINT: - case MarshalType.ARRAY_FLOAT: - case MarshalType.ARRAY_DOUBLE: - throw new Error("Marshaling of primitive arrays are not supported."); - case 20: // clr .NET DateTime - return new Date(legacyManagedExports._get_date_value_ref(root.address)); - case 21: // clr .NET DateTimeOffset - return legacyManagedExports._object_to_string_ref(root.address); - case MarshalType.URI: - return legacyManagedExports._object_to_string_ref(root.address); - case MarshalType.SAFEHANDLE: - return _unbox_cs_owned_root_as_js_object(root); - case MarshalType.VOID: - return undefined; - default: - throw new Error(`no idea on how to unbox object of MarshalType ${type} at offset ${root.value} (root address is ${root.address})`); - } -} - -export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot, type: MarshalType, unbox_buffer: VoidPtr): any { - if (type >= MarshalError.FIRST) - throw new Error(`Got marshaling error ${type} when attempting to unbox object at address ${root.value} (root located at ${root.address})`); - - let typePtr = MonoTypeNull; - if ((type === MarshalType.VT) || (type == MarshalType.OBJECT)) { - typePtr = getU32(unbox_buffer); - if (typePtr < 1024) - throw new Error(`Got invalid MonoType ${typePtr} for object at address ${root.value} (root located at ${root.address})`); - } - - return _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root, type, typePtr, unbox_buffer); -} - -export function unbox_mono_obj_root(root: WasmRoot): any { - if (root.value === 0) - return undefined; - - const unbox_buffer = legacyHelpers._unbox_buffer; - const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.address, unbox_buffer, legacyHelpers._unbox_buffer_size); - switch (type) { - case MarshalType.INT: - return getI32(unbox_buffer); - case MarshalType.UINT32: - return getU32(unbox_buffer); - case MarshalType.POINTER: - // FIXME: Is this right? - return getU32(unbox_buffer); - case MarshalType.FP32: - return getF32(unbox_buffer); - case MarshalType.FP64: - return getF64(unbox_buffer); - case MarshalType.BOOL: - return (getI32(unbox_buffer)) !== 0; - case MarshalType.CHAR: - return String.fromCharCode(getI32(unbox_buffer)); - case MarshalType.NULL: - return null; - default: - return _unbox_mono_obj_root_with_known_nonprimitive_type(root, type, unbox_buffer); - } -} - -export function mono_array_to_js_array(mono_array: MonoArray): any[] | null { - assert_legacy_interop(); - if (mono_array === MonoArrayNull) - return null; - - const arrayRoot = mono_wasm_new_root(mono_array); - try { - return mono_array_root_to_js_array(arrayRoot); - } finally { - arrayRoot.release(); - } -} - -function is_nested_array_ref(ele: WasmRoot) { - return legacyManagedExports._is_simple_array_ref(ele.address); -} - -export function mono_array_root_to_js_array(arrayRoot: WasmRoot): any[] | null { - if (arrayRoot.value === MonoArrayNull) - return null; - - const arrayAddress = arrayRoot.address; - const elemRoot = mono_wasm_new_root(); - const elemAddress = elemRoot.address; - - try { - const len = cwraps.mono_wasm_array_length_ref(arrayAddress); - const res = new Array(len); - for (let i = 0; i < len; ++i) { - // TODO: pass arrayRoot.address and elemRoot.address into new API that copies - cwraps.mono_wasm_array_get_ref(arrayAddress, i, elemAddress); - - if (is_nested_array_ref(elemRoot)) - res[i] = mono_array_root_to_js_array(elemRoot); - else - res[i] = unbox_mono_obj_root(elemRoot); - } - return res; - } finally { - elemRoot.release(); - } -} - -export function _wrap_delegate_root_as_function(root: WasmRoot): Function | null { - if (root.value === MonoObjectNull) - return null; - - // get strong reference to the Delegate - const gc_handle = legacyManagedExports._get_js_owned_object_gc_handle_ref(root.address); - return _wrap_delegate_gc_handle_as_function(gc_handle); -} - -export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle): Function { - // see if we have js owned instance for this gc_handle already - let result = _lookup_js_owned_object(gc_handle); - - - // If the function for this gc_handle was already collected (or was never created) - if (!result) { - - // note that we do not implement function/delegate roundtrip - result = function (...args: any[]) { - assert_not_disposed(result); - const boundMethod = result[delegate_invoke_symbol]; - return boundMethod(...args); - }; - - // bind the method - const delegateRoot = mono_wasm_new_root(); - get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address); - try { - if (typeof result[delegate_invoke_symbol] === "undefined") { - const method = cwraps.mono_wasm_get_delegate_invoke_ref(delegateRoot.address); - const signature = mono_method_get_call_signature_ref(method, delegateRoot); - const js_method = mono_bind_method(method, signature, true); - result[delegate_invoke_symbol] = js_method.bind({ this_arg_gc_handle: gc_handle }); - if (!result[delegate_invoke_symbol]) { - throw new Error("System.Delegate Invoke method can not be resolved."); - } - } - } finally { - delegateRoot.release(); - } - - setup_managed_proxy(result, gc_handle); - } else { - assert_not_disposed(result); - } - - return result; -} - -export function mono_wasm_create_cs_owned_object_ref(core_name: MonoStringRef, args: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - const argsRoot = mono_wasm_new_external_root(args), - nameRoot = mono_wasm_new_external_root(core_name), - resultRoot = mono_wasm_new_external_root(result_address); - try { - const js_name = monoStringToString(nameRoot); - if (!js_name) { - wrap_error_root(is_exception, "Invalid name @" + nameRoot.value, resultRoot); - return; - } - - const coreObj = (globalThis)[js_name]; - if (coreObj === null || typeof coreObj === "undefined") { - wrap_error_root(is_exception, "JavaScript host object '" + js_name + "' not found.", resultRoot); - return; - } - - try { - const js_args = mono_array_root_to_js_array(argsRoot); - - // This is all experimental !!!!!! - const allocator = function (constructor: Function, js_args: any[] | null) { - // Not sure if we should be checking for anything here - let argsList = []; - argsList[0] = constructor; - if (js_args) - argsList = argsList.concat(js_args); - // eslint-disable-next-line prefer-spread - const tempCtor = constructor.bind.apply(constructor, argsList); - const js_obj = new tempCtor(); - return js_obj; - }; - - const js_obj = allocator(coreObj, js_args); - const js_handle = mono_wasm_get_js_handle(js_obj); - // returns boxed js_handle int, because on exception we need to return String on same method signature - // here we don't have anything to in-flight reference, as the JSObject doesn't exist yet - js_to_mono_obj_root(js_handle, resultRoot, false); - wrap_no_error_root(is_exception); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - return; - } - } finally { - resultRoot.release(); - argsRoot.release(); - nameRoot.release(); - } -} - -function _unbox_task_root_as_promise(root: WasmRoot) { - if (root.value === MonoObjectNull) - return null; - - if (!_are_promises_supported) - throw new Error("Promises are not supported thus 'System.Threading.Tasks.Task' can not work in this context."); - - // get strong reference to Task - const gc_handle = legacyManagedExports._get_js_owned_object_gc_handle_ref(root.address); - - // see if we have js owned instance for this gc_handle already - let result = _lookup_js_owned_object(gc_handle); - - // If the promise for this gc_handle was already collected (or was never created) - if (!result) { - const explicitFinalization = () => teardown_managed_proxy(result, gc_handle); - - const { promise, promise_control } = createPromiseController(explicitFinalization, explicitFinalization); - - // note that we do not implement promise/task roundtrip - // With more complexity we could recover original instance when this promise is marshaled back to C#. - result = promise; - - // register C# side of the continuation - legacyManagedExports._setup_js_cont_ref(root.address, promise_control); - - setup_managed_proxy(result, gc_handle); - } - - return result; -} - -export function _unbox_ref_type_root_as_js_object(root: WasmRoot): any { - - if (root.value === MonoObjectNull) - return null; - - // this could be JSObject proxy of a js native object - // we don't need in-flight reference as we already have it rooted here - const js_handle = legacyManagedExports._try_get_cs_owned_object_js_handle_ref(root.address, 0); - if (js_handle) { - if (js_handle === JSHandleDisposed) { - throw new Error("Cannot access a disposed JSObject at " + root.value); - } - return mono_wasm_get_jsobj_from_js_handle(js_handle); - } - // otherwise this is C# only object - - // get strong reference to Object - const gc_handle = legacyManagedExports._get_js_owned_object_gc_handle_ref(root.address); - - // see if we have js owned instance for this gc_handle already - let result = _lookup_js_owned_object(gc_handle); - - // If the JS object for this gc_handle was already collected (or was never created) - if (is_nullish(result)) { - result = new ManagedObject(); - - setup_managed_proxy(result, gc_handle); - } - - return result; -} - -export function get_js_owned_object_by_gc_handle_ref(gc_handle: GCHandle, result: MonoObjectRef): void { - if (!gc_handle) { - setI32_unchecked(result, 0); - return; - } - // this is always strong gc_handle - legacyManagedExports._get_js_owned_object_by_gc_handle_ref(gc_handle, result); -} - -/** - * @deprecated Not GC or thread safe - */ -export function conv_string(mono_obj: MonoString): string | null { - assert_legacy_interop(); - return monoStringToStringUnsafe(mono_obj); -} \ No newline at end of file diff --git a/src/mono/browser/runtime/net6-legacy/export-types.ts b/src/mono/browser/runtime/net6-legacy/export-types.ts deleted file mode 100644 index 7322fa543cb00..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/export-types.ts +++ /dev/null @@ -1,243 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import type { MemOffset, MonoArray, MonoObject, MonoObjectRef, MonoString, NumberOrPointer, WasmRoot, WasmRootBuffer } from "../types/internal"; -import type { VoidPtr } from "../types/emscripten"; - -/** - * @deprecated Please use methods in top level API object instead - */ -export type BINDINGType = { - /** - * @deprecated Please use [JSExportAttribute] instead - */ - bind_static_method: (fqn: string, signature?: string) => Function; - /** - * @deprecated Please use runMain() instead - */ - call_assembly_entry_point: (assembly: string, args?: any[], signature?: string) => number; - /** - * @deprecated Not GC or thread safe - */ - mono_obj_array_new: (size: number) => MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void; - /** - * @deprecated Not GC or thread safe - */ - js_string_to_mono_string: (string: string) => MonoString; - /** - * @deprecated Not GC or thread safe - */ - js_typed_array_to_array: (js_obj: any) => MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_array_to_js_array: (mono_array: MonoArray) => any[] | null; - /** - * @deprecated Not GC or thread safe - */ - js_to_mono_obj: (js_obj: any) => MonoObject; - /** - * @deprecated Not GC or thread safe - */ - conv_string: (mono_obj: MonoString) => string | null; - /** - * @deprecated Not GC or thread safe - */ - unbox_mono_obj: (mono_obj: MonoObject) => any; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_string_to_mono_string_root: (string: string, result: WasmRoot) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_typed_array_to_array_root: (js_obj: any, result: WasmRoot) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - js_to_mono_obj_root: (js_obj: any, result: WasmRoot, should_add_in_flight: boolean) => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - conv_string_root: (root: WasmRoot) => string | null; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - unbox_mono_obj_root: (root: WasmRoot) => any; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_array_root_to_js_array: (arrayRoot: WasmRoot) => any[] | null; -}; - -/** - * @deprecated Please use methods in top level API object instead - */ -export type MONOType = { - /** - * @deprecated Please use setEnvironmentVariable() instead - */ - mono_wasm_setenv: (name: string, value: string) => void; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_bytes_into_heap: (bytes: Uint8Array) => VoidPtr; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_icu_data: (offset: VoidPtr) => boolean; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_runtime_ready: () => void; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_root_buffer: (capacity: number, name?: string) => WasmRootBuffer; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_root: (value?: T | undefined) => WasmRoot; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_new_external_root: (address: VoidPtr | MonoObjectRef) => WasmRoot; - /** - * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead. - */ - mono_wasm_release_roots: (...args: WasmRoot[]) => void; - /** - * @deprecated Please use runMain instead - */ - mono_run_main: (main_assembly_name: string, args: string[]) => Promise; - /** - * @deprecated Please use runMainAndExit instead - */ - mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_add_assembly: (name: string, data: VoidPtr, size: number) => number; - /** - * @deprecated Please use config.assets instead - */ - mono_wasm_load_runtime: (unused: string, debugLevel: number) => void; - /** - * @deprecated Please use getConfig() instead - */ - config: any; - /** - * @deprecated Please use config.assets instead - */ - loaded_files: string[]; - /** - * @deprecated Please use setHeapB32 - */ - setB32: (offset: MemOffset, value: number | boolean) => void; - /** - * @deprecated Please use setHeapI8 - */ - setI8: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI16 - */ - setI16: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI32 - */ - setI32: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI52 - */ - setI52: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU52 - */ - setU52: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapI64Big - */ - setI64Big: (offset: MemOffset, value: bigint) => void; - /** - * @deprecated Please use setHeapU8 - */ - setU8: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU16 - */ - setU16: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapU32 - */ - setU32: (offset: MemOffset, value: NumberOrPointer) => void; - /** - * @deprecated Please use setHeapF32 - */ - setF32: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use setHeapF64 - */ - setF64: (offset: MemOffset, value: number) => void; - /** - * @deprecated Please use getHeapB32 - */ - getB32: (offset: MemOffset) => boolean; - /** - * @deprecated Please use getHeapI8 - */ - getI8: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI16 - */ - getI16: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI32 - */ - getI32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI52 - */ - getI52: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU52 - */ - getU52: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapI64Big - */ - getI64Big: (offset: MemOffset) => bigint; - /** - * @deprecated Please use getHeapU8 - */ - getU8: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU16 - */ - getU16: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapU32 - */ - getU32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapF32 - */ - getF32: (offset: MemOffset) => number; - /** - * @deprecated Please use getHeapF64 - */ - getF64: (offset: MemOffset) => number; -}; - -export { MonoArray, MonoObject, MonoString }; diff --git a/src/mono/browser/runtime/net6-legacy/exports-legacy.ts b/src/mono/browser/runtime/net6-legacy/exports-legacy.ts deleted file mode 100644 index b2f8aeda4953b..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/exports-legacy.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { legacy_c_functions as cwraps } from "../cwraps"; -import { mono_wasm_runtime_ready } from "../debug"; -import { mono_wasm_load_icu_data } from "../icu"; -import { mono_wasm_load_bytes_into_heap, setB32, setI8, setI16, setI32, setI52, setU52, setI64Big, setU8, setU16, setU32, setF32, setF64, getB32, getI8, getI16, getI32, getI52, getU52, getI64Big, getU8, getU16, getU32, getF32, getF64 } from "../memory"; -import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_root, mono_wasm_release_roots } from "../roots"; -import { mono_run_main, mono_run_main_and_exit } from "../run"; -import { mono_wasm_setenv } from "../startup"; -import { stringToMonoStringRoot, monoStringToString } from "../strings"; -import { mono_array_to_js_array, unbox_mono_obj, unbox_mono_obj_root, mono_array_root_to_js_array, conv_string } from "./cs-to-js"; -import { js_typed_array_to_array, js_to_mono_obj, js_typed_array_to_array_root, js_to_mono_obj_root } from "./js-to-cs"; -import { mono_bind_static_method, mono_call_assembly_entry_point } from "./method-calls"; -import { mono_wasm_load_runtime } from "../startup"; -import { BINDINGType, MONOType } from "./export-types"; -import { mono_method_resolve } from "./method-binding"; -import { runtimeHelpers } from "../globals"; -import { stringToMonoStringIntern, stringToMonoStringUnsafe } from "./strings"; - -export function export_mono_api(): MONOType { - return { - // legacy MONO API - mono_wasm_setenv, - mono_wasm_load_bytes_into_heap, - mono_wasm_load_icu_data, - mono_wasm_runtime_ready, - mono_wasm_new_root_buffer, - mono_wasm_new_root, - mono_wasm_new_external_root, - mono_wasm_release_roots, - mono_run_main, - mono_run_main_and_exit, - - // for Blazor's future! - mono_wasm_add_assembly: null, - mono_wasm_load_runtime, - - config: runtimeHelpers.config, - loaded_files: [], - - // memory accessors - setB32, - setI8, - setI16, - setI32, - setI52, - setU52, - setI64Big, - setU8, - setU16, - setU32, - setF32, - setF64, - getB32, - getI8, - getI16, - getI32, - getI52, - getU52, - getI64Big, - getU8, - getU16, - getU32, - getF32, - getF64, - }; -} - -export function cwraps_mono_api(mono: MONOType): void { - Object.assign(mono, { - mono_wasm_add_assembly: cwraps.mono_wasm_add_assembly, - }); -} - -export function export_internal_api(): any { - return { - stringToMonoStringIntern, // MarshalTests.cs - mono_method_resolve, //MarshalTests.cs - }; -} - -export function export_binding_api(): BINDINGType { - return { - // legacy BINDING API - bind_static_method: mono_bind_static_method, - call_assembly_entry_point: mono_call_assembly_entry_point, - mono_obj_array_new: null, - mono_obj_array_set: null, - js_string_to_mono_string: stringToMonoStringUnsafe, - js_typed_array_to_array, - mono_array_to_js_array, - js_to_mono_obj, - conv_string, - unbox_mono_obj, - - mono_obj_array_new_ref: null, - mono_obj_array_set_ref: null, - js_string_to_mono_string_root: stringToMonoStringRoot, - js_typed_array_to_array_root, - js_to_mono_obj_root, - conv_string_root: monoStringToString, - unbox_mono_obj_root, - mono_array_root_to_js_array, - }; -} - -export function cwraps_binding_api(binding: BINDINGType): void { - Object.assign(binding, { - mono_obj_array_new: cwraps.mono_wasm_obj_array_new, - mono_obj_array_set: cwraps.mono_wasm_obj_array_set, - mono_obj_array_new_ref: cwraps.mono_wasm_obj_array_new_ref, - mono_obj_array_set_ref: cwraps.mono_wasm_obj_array_set_ref, - }); -} diff --git a/src/mono/browser/runtime/net6-legacy/globals.ts b/src/mono/browser/runtime/net6-legacy/globals.ts deleted file mode 100644 index 3aabbe0830f38..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/globals.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import type { GlobalObjects, MonoClass } from "../types/internal"; -import type { VoidPtr } from "../types/emscripten"; -import type { BINDINGType, MONOType } from "./export-types"; - -export let MONO: MONOType; -export let BINDING: BINDINGType; - -export const legacyHelpers: LegacyHelpers = { -}; - -export function initializeLegacyExports( - globals: GlobalObjects, -): void { - MONO = globals.mono; - BINDING = globals.binding; -} - -export type LegacyHelpers = { - runtime_legacy_exports_classname: string; - runtime_legacy_exports_class: MonoClass; - - // A WasmRoot that is guaranteed to contain 0 - _null_root: any; - _class_int32: MonoClass; - _class_uint32: MonoClass; - _class_double: MonoClass; - _class_boolean: MonoClass; - _unbox_buffer_size: number; - _box_buffer: VoidPtr; - _unbox_buffer: VoidPtr; - _box_root: any; -} - -export const wasm_type_symbol = Symbol.for("wasm type"); diff --git a/src/mono/browser/runtime/net6-legacy/js-to-cs.ts b/src/mono/browser/runtime/net6-legacy/js-to-cs.ts deleted file mode 100644 index 9e9f5d9bb7c02..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/js-to-cs.ts +++ /dev/null @@ -1,294 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { isThenable } from "../cancelable-promise"; -import { legacy_c_functions as cwraps } from "../cwraps"; -import { js_owned_gc_handle_symbol, assert_not_disposed, cs_owned_js_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, mono_wasm_release_cs_owned_object, teardown_managed_proxy, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles"; -import { Module } from "../globals"; -import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; -import { setI32_unchecked, setU32_unchecked, setF64, setB32, localHeapViewU8 } from "../memory"; -import { mono_wasm_new_root, mono_wasm_release_roots, mono_wasm_new_external_root } from "../roots"; -import { stringToMonoStringRoot, stringToInternedMonoStringRoot } from "../strings"; -import { MonoObject, is_nullish, MonoClass, MonoArray, MonoObjectNull, JSHandle, MonoObjectRef, JSHandleNull, JSHandleDisposed, WasmRoot } from "../types/internal"; -import { TypedArray, Int32Ptr } from "../types/emscripten"; -import { has_backing_array_buffer } from "./buffers"; -import { legacyManagedExports } from "./corebindings"; -import { get_js_owned_object_by_gc_handle_ref } from "./cs-to-js"; -import { legacyHelpers, wasm_type_symbol } from "./globals"; -import { assert_legacy_interop } from "./method-binding"; - -export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { - switch (true) { - case js_obj === null: - case typeof js_obj === "undefined": - result.clear(); - return; - case typeof js_obj === "symbol": - case typeof js_obj === "string": - legacyManagedExports._create_uri_ref(js_obj, result.address); - return; - default: - _extract_mono_obj_root(should_add_in_flight, js_obj, result); - return; - } -} - -// this is only used from Blazor -/** - * @deprecated Not GC or thread safe. For blazor use only - */ -export function js_to_mono_obj(js_obj: any): MonoObject { - assert_legacy_interop(); - const temp = mono_wasm_new_root(); - try { - js_to_mono_obj_root(js_obj, temp, false); - return temp.value; - } finally { - temp.release(); - } -} - -/** - * @deprecated Not GC or thread safe - */ -export function _js_to_mono_obj_unsafe(should_add_in_flight: boolean, js_obj: any): MonoObject { - const temp = mono_wasm_new_root(); - try { - js_to_mono_obj_root(js_obj, temp, should_add_in_flight); - return temp.value; - } finally { - temp.release(); - } -} - -export function js_to_mono_obj_root(js_obj: any, result: WasmRoot, should_add_in_flight: boolean): void { - assert_legacy_interop(); - - if (is_nullish(result)) - throw new Error("Expected (value, WasmRoot, boolean)"); - - switch (true) { - case js_obj === null: - case typeof js_obj === "undefined": - result.clear(); - return; - case typeof js_obj === "number": { - let box_class: MonoClass; - if ((js_obj | 0) === js_obj) { - setI32_unchecked(legacyHelpers._box_buffer, js_obj); - box_class = legacyHelpers._class_int32; - } else if ((js_obj >>> 0) === js_obj) { - setU32_unchecked(legacyHelpers._box_buffer, js_obj); - box_class = legacyHelpers._class_uint32; - } else { - setF64(legacyHelpers._box_buffer, js_obj); - box_class = legacyHelpers._class_double; - } - - cwraps.mono_wasm_box_primitive_ref(box_class, legacyHelpers._box_buffer, 8, result.address); - return; - } - case typeof js_obj === "string": - stringToMonoStringRoot(js_obj, result); - return; - case typeof js_obj === "symbol": - stringToInternedMonoStringRoot(js_obj, result); - return; - case typeof js_obj === "boolean": - setB32(legacyHelpers._box_buffer, js_obj); - cwraps.mono_wasm_box_primitive_ref(legacyHelpers._class_boolean, legacyHelpers._box_buffer, 4, result.address); - return; - case isThenable(js_obj) === true: { - _wrap_js_thenable_as_task_root(js_obj, result); - return; - } - case js_obj.constructor.name === "Date": - // getTime() is always UTC - legacyManagedExports._create_date_time_ref(js_obj.getTime(), result.address); - return; - default: - _extract_mono_obj_root(should_add_in_flight, js_obj, result); - return; - } -} - -function _extract_mono_obj_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { - result.clear(); - - if (js_obj === null || typeof js_obj === "undefined") - return; - - if (js_obj[js_owned_gc_handle_symbol] !== undefined) { - // for js_owned_gc_handle we don't want to create new proxy - // since this is strong gc_handle we don't need to in-flight reference - const gc_handle = assert_not_disposed(js_obj); - get_js_owned_object_by_gc_handle_ref(gc_handle, result.address); - return; - } - if (js_obj[cs_owned_js_handle_symbol]) { - get_cs_owned_object_by_js_handle_ref(js_obj[cs_owned_js_handle_symbol], should_add_in_flight, result.address); - - // It's possible the managed object corresponding to this JS object was collected, - // in which case we need to make a new one. - // FIXME: This check is not thread safe - if (!result.value) { - delete js_obj[cs_owned_js_handle_symbol]; - } - } - - // FIXME: This check is not thread safe - if (!result.value) { - // Obtain the JS -> C# type mapping. - const wasm_type = js_obj[wasm_type_symbol]; - const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type; - - const js_handle = mono_wasm_get_js_handle(js_obj); - - legacyManagedExports._create_cs_owned_proxy_ref(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0, result.address); - } -} - -// https://github.com/Planeshifter/emscripten-examples/blob/master/01_PassingArrays/sum_post.js -function js_typedarray_to_heap(typedArray: TypedArray) { - assert_legacy_interop(); - const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT; - const ptr = Module._malloc(numBytes); - const heapU8 = localHeapViewU8(); - const heapBytes = new Uint8Array(heapU8.buffer, ptr, numBytes); - heapBytes.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, numBytes)); - // WARNING: returned memory view will get stale when linear memory grows on another thread. This is legacy interop so we don't try to fix it. The view will be fine when used in synchronous calls. - return heapBytes; -} - -export function js_typed_array_to_array_root(js_obj: any, result: WasmRoot): void { - // JavaScript typed arrays are array-like objects and provide a mechanism for accessing - // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays - // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) - // is an object representing a chunk of data; it has no format to speak of, and offers no - // mechanism for accessing its contents. In order to access the memory contained in a buffer, - // you need to use a view. A view provides a context - that is, a data type, starting offset, - // and number of elements - that turns the data into an actual typed array. - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays - if (has_backing_array_buffer(js_obj) && js_obj.BYTES_PER_ELEMENT) { - const arrayType = js_obj[wasm_type_symbol]; - const heapBytes = js_typedarray_to_heap(js_obj); - cwraps.mono_wasm_typed_array_new_ref(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType, result.address); - Module._free(heapBytes.byteOffset); - } - else { - throw new Error("Object '" + js_obj + "' is not a typed array"); - } -} - -/** - * @deprecated Not GC or thread safe - */ -export function js_typed_array_to_array(js_obj: any): MonoArray { - const temp = mono_wasm_new_root(); - try { - js_typed_array_to_array_root(js_obj, temp); - return temp.value; - } finally { - temp.release(); - } -} - -export function js_to_mono_enum(js_obj: any): number { - if (typeof (js_obj) !== "number") - throw new Error(`Expected numeric value for enum argument, got '${js_obj}'`); - - return js_obj | 0; -} - -export function js_array_to_mono_array(js_array: any[], asString: boolean, should_add_in_flight: boolean): MonoArray { - const arrayRoot = mono_wasm_new_root(); - if (asString) - cwraps.mono_wasm_string_array_new_ref(js_array.length, arrayRoot.address); - else - cwraps.mono_wasm_obj_array_new_ref(js_array.length, arrayRoot.address); - const elemRoot = mono_wasm_new_root(MonoObjectNull); - const arrayAddress = arrayRoot.address; - const elemAddress = elemRoot.address; - - try { - for (let i = 0; i < js_array.length; ++i) { - let obj = js_array[i]; - if (asString) - obj = obj.toString(); - - js_to_mono_obj_root(obj, elemRoot, should_add_in_flight); - cwraps.mono_wasm_obj_array_set_ref(arrayAddress, i, elemAddress); - } - - return arrayRoot.value; - } finally { - mono_wasm_release_roots(arrayRoot, elemRoot); - } -} - -export function _wrap_js_thenable_as_task_root(thenable: Promise, resultRoot: WasmRoot): { - then_js_handle: JSHandle, -} { - if (!thenable) { - resultRoot.clear(); - return null; - } - - // hold strong JS reference to thenable while in flight - // ideally, this should be hold alive by lifespan of the resulting C# Task, but this is good cheap aproximation - const thenable_js_handle = mono_wasm_get_js_handle(thenable); - - // Note that we do not implement promise/task roundtrip. - // With more complexity we could recover original instance when this Task is marshaled back to JS. - // TODO optimization: return the tcs.Task on this same call instead of _get_tcs_task - const tcs_gc_handle = legacyManagedExports._create_tcs(); - const holder: any = { tcs_gc_handle }; - setup_managed_proxy(holder, tcs_gc_handle); - thenable.then((result) => { - legacyManagedExports._set_tcs_result_ref(tcs_gc_handle, result); - }, (reason) => { - legacyManagedExports._set_tcs_failure(tcs_gc_handle, reason ? reason.toString() : ""); - }).finally(() => { - // let go of the thenable reference - mono_wasm_release_cs_owned_object(thenable_js_handle); - teardown_managed_proxy(holder, tcs_gc_handle); // this holds holder alive for finalizer, until the promise is freed - }); - - - legacyManagedExports._get_tcs_task_ref(tcs_gc_handle, resultRoot.address); - - // returns raw pointer to tcs.Task - return { - then_js_handle: thenable_js_handle, - }; -} - -export function mono_wasm_typed_array_to_array_ref(js_handle: JSHandle, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - const resultRoot = mono_wasm_new_external_root(result_address); - try { - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(js_obj)) { - wrap_error_root(is_exception, "ERR06: Invalid JS object handle '" + js_handle + "'", resultRoot); - return; - } - - // returns pointer to C# array - js_typed_array_to_array_root(js_obj, resultRoot); - wrap_no_error_root(is_exception); - } catch (exc) { - wrap_error_root(is_exception, String(exc), resultRoot); - } finally { - resultRoot.release(); - } -} - -// when should_add_in_flight === true, the JSObject would be temporarily hold by Normal gc_handle, so that it would not get collected during transition to the managed stack. -// its InFlight gc_handle would be freed when the instance arrives to managed side via Interop.Runtime.ReleaseInFlight -export function get_cs_owned_object_by_js_handle_ref(js_handle: JSHandle, should_add_in_flight: boolean, result: MonoObjectRef): void { - if (js_handle === JSHandleNull || js_handle === JSHandleDisposed) { - setI32_unchecked(result, 0); - return; - } - legacyManagedExports._get_cs_owned_object_by_js_handle_ref(js_handle, should_add_in_flight ? 1 : 0, result); -} - diff --git a/src/mono/browser/runtime/net6-legacy/method-binding.ts b/src/mono/browser/runtime/net6-legacy/method-binding.ts deleted file mode 100644 index aa710700924e8..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/method-binding.ts +++ /dev/null @@ -1,682 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import MonoWasmThreads from "consts:monoWasmThreads"; - -import { legacy_c_functions as cwraps } from "../cwraps"; -import { ENVIRONMENT_IS_PTHREAD, Module, mono_assert } from "../globals"; -import { parseFQN } from "../invoke-cs"; -import { setI32, setU32, setF32, setF64, setU52, setI52, setB32, setI32_unchecked, setU32_unchecked, _zero_region, _create_temp_frame, getB32, getI32, getU32, getF32, getF64 } from "../memory"; -import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots"; -import { stringToMonoStringRoot, stringToInternedMonoStringRoot, monoStringToString } from "../strings"; -import { MonoMethod, MonoObject, VoidPtrNull, MarshalType, MonoString, MonoObjectNull, WasmRootBuffer, WasmRoot } from "../types/internal"; -import { VoidPtr } from "../types/emscripten"; -import { legacyManagedExports } from "./corebindings"; -import { get_js_owned_object_by_gc_handle_ref, _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js"; -import { legacyHelpers } from "./globals"; -import { js_to_mono_obj_root, _js_to_mono_uri_root, js_to_mono_enum } from "./js-to-cs"; -import { _teardown_after_call } from "./method-calls"; -import { mono_log_warn } from "../logging"; -import { assert_js_interop } from "../invoke-js"; - - -const escapeRE = /[^A-Za-z0-9_$]/g; -const primitiveConverters = new Map(); -const _signature_converters = new Map(); -const boundMethodsByMethod: Map = new Map(); - -function _create_named_function(name: string, argumentNames: string[], body: string, closure: any): Function { - let result = null; - let closureArgumentList: any[] | null = null; - let closureArgumentNames = null; - - if (closure) { - closureArgumentNames = Object.keys(closure); - closureArgumentList = new Array(closureArgumentNames.length); - for (let i = 0, l = closureArgumentNames.length; i < l; i++) - closureArgumentList[i] = closure[closureArgumentNames[i]]; - } - - const constructor = _create_rebindable_named_function(name, argumentNames, body, closureArgumentNames); - // eslint-disable-next-line prefer-spread - result = constructor.apply(null, closureArgumentList); - - return result; -} - -function _create_rebindable_named_function(name: string, argumentNames: string[], body: string, closureArgNames: string[] | null): Function { - const strictPrefix = "\"use strict\";\r\n"; - let uriPrefix = "", escapedFunctionIdentifier = ""; - - if (name) { - uriPrefix = "//# sourceURL=https://dotnet.generated.invalid/" + name + "\r\n"; - escapedFunctionIdentifier = name; - } else { - escapedFunctionIdentifier = "unnamed"; - } - - let rawFunctionText = "function " + escapedFunctionIdentifier + "(" + - argumentNames.join(", ") + - ") {\r\n" + - body + - "\r\n};\r\n"; - - const lineBreakRE = /\r(\n?)/g; - - rawFunctionText = - uriPrefix + strictPrefix + - rawFunctionText.replace(lineBreakRE, "\r\n ") + - ` return ${escapedFunctionIdentifier};\r\n`; - - let result = null, keys = null; - - if (closureArgNames) { - keys = closureArgNames.concat([rawFunctionText]); - } else { - keys = [rawFunctionText]; - } - - result = Function.apply(Function, keys); - return result; -} - -export function _create_primitive_converters(): void { - const result = primitiveConverters; - result.set("m", { steps: [{}], size: 0 }); - result.set("s", { steps: [{ convert_root: stringToMonoStringRoot.bind(Module) }], size: 0, needs_root: true }); - result.set("S", { steps: [{ convert_root: stringToInternedMonoStringRoot.bind(Module) }], size: 0, needs_root: true }); - // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, - // because we will root the reference, so we don't need in-flight reference - // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end - result.set("o", { steps: [{ convert_root: js_to_mono_obj_root.bind(Module) }], size: 0, needs_root: true }); - result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(Module, false) }], size: 0, needs_root: true }); - // ref object aka T&& - result.set("R", { steps: [{ convert_root: js_to_mono_obj_root.bind(Module), byref: true }], size: 0, needs_root: true }); - - // result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); - result.set("j", { steps: [{ convert: js_to_mono_enum.bind(Module), indirect: "i32" }], size: 8 }); - - result.set("b", { steps: [{ indirect: "bool" }], size: 8 }); - result.set("i", { steps: [{ indirect: "i32" }], size: 8 }); - result.set("I", { steps: [{ indirect: "u32" }], size: 8 }); - result.set("l", { steps: [{ indirect: "i52" }], size: 8 }); - result.set("L", { steps: [{ indirect: "u52" }], size: 8 }); - result.set("f", { steps: [{ indirect: "float" }], size: 8 }); - result.set("d", { steps: [{ indirect: "double" }], size: 8 }); -} - -function _create_converter_for_marshal_string(args_marshal: string/*ArgsMarshalString*/): Converter { - const steps = []; - let size = 0; - let is_result_definitely_unmarshaled = false, - is_result_possibly_unmarshaled = false, - result_unmarshaled_if_argc = -1, - needs_root_buffer = false; - - for (let i = 0; i < args_marshal.length; ++i) { - const key = args_marshal[i]; - - if (i === args_marshal.length - 1) { - if (key === "!") { - is_result_definitely_unmarshaled = true; - continue; - } else if (key === "m") { - is_result_possibly_unmarshaled = true; - result_unmarshaled_if_argc = args_marshal.length - 1; - } - } else if (key === "!") - throw new Error("! must be at the end of the signature"); - - const conv = primitiveConverters.get(key); - if (!conv) - throw new Error("Unknown parameter type " + key); - - const localStep = Object.create(conv.steps[0]); - localStep.size = conv.size; - if (conv.needs_root) - needs_root_buffer = true; - localStep.needs_root = conv.needs_root; - localStep.key = key; - steps.push(localStep); - size += conv.size; - } - - return { - steps, size, args_marshal, - is_result_definitely_unmarshaled, - is_result_possibly_unmarshaled, - result_unmarshaled_if_argc, - needs_root_buffer - }; -} - -function _get_converter_for_marshal_string(args_marshal: string/*ArgsMarshalString*/): Converter { - let converter = _signature_converters.get(args_marshal); - if (!converter) { - converter = _create_converter_for_marshal_string(args_marshal); - _signature_converters.set(args_marshal, converter); - } - - return converter; -} - -function _compile_converter_for_marshal_string(args_marshal: string/*ArgsMarshalString*/): Converter { - const converter = _get_converter_for_marshal_string(args_marshal); - if (typeof (converter.args_marshal) !== "string") - throw new Error("Corrupt converter for '" + args_marshal + "'"); - - if (converter.compiled_function && converter.compiled_variadic_function) - return converter; - - const converterName = args_marshal.replace("!", "_result_unmarshaled"); - converter.name = converterName; - - let body = []; - let argumentNames = ["method"]; - - const closure: any = { - Module, - setI32, - setU32, - setF32, - setF64, - setU52, - setI52, - setB32, - setI32_unchecked, - setU32_unchecked, - scratchValueRoot: converter.scratchValueRoot, - stackAlloc: Module.stackAlloc, - _zero_region - }; - let indirectLocalOffset = 0; - - // ensure the indirect values are 8-byte aligned so that aligned loads and stores will work - const indirectBaseOffset = ((((args_marshal.length * 4) + 7) / 8) | 0) * 8; - // worst-case allocation size instead of allocating dynamically, plus padding - // the padding is necessary to ensure that we don't overrun the buffer due to - // the 8-byte alignment we did above - const bufferSizeBytes = converter.size + (args_marshal.length * 4) + 16; - - body.push( - "if (!method) throw new Error('no method provided');", - `const buffer = stackAlloc(${bufferSizeBytes});`, - `_zero_region(buffer, ${bufferSizeBytes});`, - `const indirectStart = buffer + ${indirectBaseOffset};`, - "" - ); - - for (let i = 0; i < converter.steps.length; i++) { - const step = converter.steps[i]; - const closureKey = "step" + i; - const valueKey = "value" + i; - - const argKey = "arg" + i; - const offsetText = `(indirectStart + ${indirectLocalOffset})`; - argumentNames.push(argKey); - - if (step.convert_root) { - mono_assert(!step.indirect, "converter step cannot both be rooted and indirect"); - if (!converter.scratchValueRoot) { - // HACK: new_external_root rightly won't accept a null address - const dummyAddress = Module.stackSave(); - converter.scratchValueRoot = mono_wasm_new_external_root(dummyAddress); - closure.scratchValueRoot = converter.scratchValueRoot; - } - - closure[closureKey] = step.convert_root; - // Update our scratch external root to point to the indirect slot where our - // managed pointer is destined to live - body.push(`scratchValueRoot._set_address(${offsetText});`); - // Convert the object and store the managed reference through our scratch external root - body.push(`${closureKey}(${argKey}, scratchValueRoot);`); - if (step.byref) { - // for T&& we pass the address of the pointer stored on the stack - body.push(`let ${valueKey} = ${offsetText};`); - } else { - // It is safe to pass the pointer by value now since we know it is pinned - body.push(`let ${valueKey} = scratchValueRoot.value;`); - } - } else if (step.convert) { - closure[closureKey] = step.convert; - body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`); - } else { - body.push(`let ${valueKey} = ${argKey};`); - } - - if (step.needs_root && !step.convert_root) { - body.push("if (!rootBuffer) throw new Error('no root buffer provided');"); - body.push(`rootBuffer.set (${i}, ${valueKey});`); - } - - if (step.indirect) { - switch (step.indirect) { - case "bool": - body.push(`setB32(${offsetText}, ${valueKey});`); - break; - case "u32": - body.push(`setU32(${offsetText}, ${valueKey});`); - break; - case "i32": - body.push(`setI32(${offsetText}, ${valueKey});`); - break; - case "float": - body.push(`setF32(${offsetText}, ${valueKey});`); - break; - case "double": - body.push(`setF64(${offsetText}, ${valueKey});`); - break; - case "i52": - body.push(`setI52(${offsetText}, ${valueKey});`); - break; - case "u52": - body.push(`setU52(${offsetText}, ${valueKey});`); - break; - default: - throw new Error("Unimplemented indirect type: " + step.indirect); - } - - body.push(`setU32_unchecked(buffer + (${i} * 4), ${offsetText});`); - indirectLocalOffset += step.size!; - } else { - body.push(`setU32_unchecked(buffer + (${i} * 4), ${valueKey});`); - indirectLocalOffset += 4; - } - body.push(""); - } - - body.push("return buffer;"); - - let bodyJs = body.join("\r\n"), compiledFunction = null, compiledVariadicFunction = null; - try { - compiledFunction = _create_named_function("converter_" + converterName, argumentNames, bodyJs, closure); - converter.compiled_function = compiledFunction; - } catch (exc) { - converter.compiled_function = null; - mono_log_warn("compiling converter failed for", bodyJs, "with error", exc); - throw exc; - } - - - argumentNames = ["method", "args"]; - const variadicClosure = { - converter: compiledFunction - }; - body = [ - "return converter(", - " method," - ]; - - for (let i = 0; i < converter.steps.length; i++) { - body.push( - " args[" + i + - ( - (i == converter.steps.length - 1) - ? "]" - : "], " - ) - ); - } - - body.push(");"); - - bodyJs = body.join("\r\n"); - try { - compiledVariadicFunction = _create_named_function("variadic_converter_" + converterName, argumentNames, bodyJs, variadicClosure); - converter.compiled_variadic_function = compiledVariadicFunction; - } catch (exc) { - converter.compiled_variadic_function = null; - mono_log_warn("compiling converter failed for", bodyJs, "with error", exc); - throw exc; - } - - converter.scratchRootBuffer = null; - converter.scratchBuffer = VoidPtrNull; - - return converter; -} - -function _maybe_produce_signature_warning(converter: Converter) { - if (converter.has_warned_about_signature) - return; - - mono_log_warn("Deprecated raw return value signature: '" + converter.args_marshal + "'. End the signature with '!' instead of 'm'."); - converter.has_warned_about_signature = true; -} - -export function _decide_if_result_is_marshaled(converter: Converter, argc: number): boolean { - if (!converter) - return true; - - if ( - converter.is_result_possibly_unmarshaled && - (argc === converter.result_unmarshaled_if_argc) - ) { - if (argc < converter.result_unmarshaled_if_argc) - throw new Error(`Expected >= ${converter.result_unmarshaled_if_argc} argument(s) but got ${argc} for signature '${converter.args_marshal}'`); - - _maybe_produce_signature_warning(converter); - return false; - } else { - if (argc < converter.steps.length) - throw new Error(`Expected ${converter.steps.length} argument(s) but got ${argc} for signature '${converter.args_marshal}'`); - - return !converter.is_result_definitely_unmarshaled; - } -} - - -export function mono_bind_method(method: MonoMethod, args_marshal: string/*ArgsMarshalString*/, has_this_arg: boolean, friendly_name?: string): Function { - assert_legacy_interop(); - if (typeof (args_marshal) !== "string") - throw new Error("args_marshal argument invalid, expected string"); - - const key = `managed_${method}_${args_marshal}`; - let result = boundMethodsByMethod.get(key); - if (result) { - return result; - } - if (!friendly_name) { - friendly_name = key; - } - - let converter: Converter | null = null; - if (typeof (args_marshal) === "string") { - converter = _compile_converter_for_marshal_string(args_marshal); - } - - // FIXME - const unbox_buffer_size = 128; - const unbox_buffer = Module._malloc(unbox_buffer_size); - - const token: BoundMethodToken = { - method, - converter, - scratchRootBuffer: null, - scratchBuffer: VoidPtrNull, - scratchResultRoot: mono_wasm_new_root(), - scratchExceptionRoot: mono_wasm_new_root(), - scratchThisArgRoot: mono_wasm_new_root() - }; - const closure: any = { - Module, - mono_wasm_new_root, - get_js_owned_object_by_gc_handle_ref, - _create_temp_frame, - _handle_exception_for_call, - _teardown_after_call, - mono_wasm_try_unbox_primitive_and_get_type_ref: cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref, - _unbox_mono_obj_root_with_known_nonprimitive_type, - invoke_method_ref: cwraps.mono_wasm_invoke_method_ref, - method, - token, - unbox_buffer, - unbox_buffer_size, - getB32, - getI32, - getU32, - getF32, - getF64, - stackSave: Module.stackSave - }; - - const converterKey = converter ? "converter_" + converter.name : ""; - if (converter) - closure[converterKey] = converter; - - const argumentNames = []; - const body = [ - "_create_temp_frame();", - "let resultRoot = token.scratchResultRoot, exceptionRoot = token.scratchExceptionRoot, thisArgRoot = token.scratchThisArgRoot , sp = stackSave();", - "token.scratchResultRoot = null;", - "token.scratchExceptionRoot = null;", - "token.scratchThisArgRoot = null;", - "if (resultRoot === null)", - " resultRoot = mono_wasm_new_root ();", - "if (exceptionRoot === null)", - " exceptionRoot = mono_wasm_new_root ();", - "if (thisArgRoot === null)", - " thisArgRoot = mono_wasm_new_root ();", - "" - ]; - - if (converter) { - body.push( - `let buffer = ${converterKey}.compiled_function(`, - " method," - ); - - for (let i = 0; i < converter.steps.length; i++) { - const argName = "arg" + i; - argumentNames.push(argName); - body.push( - " " + argName + - ( - (i == converter.steps.length - 1) - ? "" - : ", " - ) - ); - } - - body.push(");"); - - } else { - body.push("let buffer = 0;"); - } - - if (converter && converter.is_result_definitely_unmarshaled) { - body.push("let is_result_marshaled = false;"); - } else if (converter && converter.is_result_possibly_unmarshaled) { - body.push(`let is_result_marshaled = arguments.length !== ${converter.result_unmarshaled_if_argc};`); - } else { - body.push("let is_result_marshaled = true;"); - } - - // We inline a bunch of the invoke and marshaling logic here in order to eliminate the GC pressure normally - // created by the unboxing part of the call process. Because unbox_mono_obj(_root) can return non-numeric - // types, v8 and spidermonkey allocate and store its result on the heap (in the nursery, to be fair). - // For a bound method however, we know the result will always be the same type because C# methods have known - // return types. Inlining the invoke and marshaling logic means that even though the bound method has logic - // for handling various types, only one path through the method (for its appropriate return type) will ever - // be taken, and the JIT will see that the 'result' local and thus the return value of this function are - // always of the exact same type. All of the branches related to this end up being predicted and low-cost. - // The end result is that bound method invocations don't always allocate, so no more nursery GCs. Yay! -kg - body.push( - "", - "", - "", - ); - if (has_this_arg) { - body.push("get_js_owned_object_by_gc_handle_ref(this.this_arg_gc_handle, thisArgRoot.address);"); - body.push("invoke_method_ref (method, thisArgRoot.address, buffer, exceptionRoot.address, resultRoot.address);"); - } else { - body.push("invoke_method_ref (method, 0, buffer, exceptionRoot.address, resultRoot.address);"); - } - - body.push( - `_handle_exception_for_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, thisArgRoot, sp);`, - "", - "let resultPtr = resultRoot.value, result = undefined;" - ); - - if (converter) { - if (converter.is_result_possibly_unmarshaled) - body.push("if (!is_result_marshaled) "); - - if (converter.is_result_definitely_unmarshaled || converter.is_result_possibly_unmarshaled) - body.push(" result = resultPtr;"); - - if (!converter.is_result_definitely_unmarshaled) - body.push( - "if (is_result_marshaled) {", - // For the common scenario where the return type is a primitive, we want to try and unbox it directly - // into our existing heap allocation and then read it out of the heap. Doing this all in one operation - // means that we only need to enter a gc safe region twice (instead of 3+ times with the normal, - // slower check-type-and-then-unbox flow which has extra checks since unbox verifies the type). - " let resultType = mono_wasm_try_unbox_primitive_and_get_type_ref (resultRoot.address, unbox_buffer, unbox_buffer_size);", - " switch (resultType) {", - ` case ${MarshalType.INT}:`, - " result = getI32(unbox_buffer); break;", - ` case ${MarshalType.POINTER}:`, // FIXME: Is this right? - ` case ${MarshalType.UINT32}:`, - " result = getU32(unbox_buffer); break;", - ` case ${MarshalType.FP32}:`, - " result = getF32(unbox_buffer); break;", - ` case ${MarshalType.FP64}:`, - " result = getF64(unbox_buffer); break;", - ` case ${MarshalType.BOOL}:`, - " result = getB32(unbox_buffer); break;", - ` case ${MarshalType.CHAR}:`, - " result = String.fromCharCode(getI32(unbox_buffer)); break;", - ` case ${MarshalType.NULL}:`, - " result = null; break;", - " default:", - " result = _unbox_mono_obj_root_with_known_nonprimitive_type (resultRoot, resultType, unbox_buffer); break;", - " }", - "}" - ); - } else { - throw new Error("No converter"); - } - - let displayName = friendly_name.replace(escapeRE, "_"); - - if (has_this_arg) - displayName += "_this"; - - body.push( - `_teardown_after_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, thisArgRoot, sp);`, - "return result;" - ); - - const bodyJs = body.join("\r\n"); - - result = _create_named_function(displayName, argumentNames, bodyJs, closure); - boundMethodsByMethod.set(key, result); - - return result; -} - -/* -We currently don't use these types because it makes typeScript compiler very slow. - -declare const enum ArgsMarshal { - Int32 = "i", // int32 - Int32Enum = "j", // int32 - Enum with underlying type of int32 - Int64 = "l", // int64 - Int64Enum = "k", // int64 - Enum with underlying type of int64 - Float32 = "f", // float - Float64 = "d", // double - String = "s", // string - Char = "s", // interned string - JSObj = "o", // js object will be converted to a C# object (this will box numbers/bool/promises) - MONOObj = "m", // raw mono object. Don't use it unless you know what you're doing -} - -// to suppress marshaling of the return value, place '!' at the end of args_marshal, i.e. 'ii!' instead of 'ii' -type _ExtraArgsMarshalOperators = "!" | ""; - -export type ArgsMarshalString = "" - | `${ArgsMarshal}${_ExtraArgsMarshalOperators}` - | `${ArgsMarshal}${ArgsMarshal}${_ExtraArgsMarshalOperators}` - | `${ArgsMarshal}${ArgsMarshal}${ArgsMarshal}${_ExtraArgsMarshalOperators}` - | `${ArgsMarshal}${ArgsMarshal}${ArgsMarshal}${ArgsMarshal}${_ExtraArgsMarshalOperators}`; -*/ - -type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "u52" | "i52" | "reference" | "bool" -type VariadicConverterFunction = (method: MonoMethod, ...args: unknown[]) => VoidPtr; -type ConverterFunction = (method: MonoMethod /* , ... */) => VoidPtr; - -export type Converter = { - steps: { - // (value: any, method: MonoMethod, arg_index: int) - convert?: boolean | Function; - // (value: any, result_root: WasmRoot) - convert_root?: Function; - needs_root?: boolean; - byref?: boolean; - indirect?: ConverterStepIndirects; - size?: number; - }[]; - size: number; - args_marshal?: string/*ArgsMarshalString*/; - is_result_definitely_unmarshaled?: boolean; - is_result_possibly_unmarshaled?: boolean; - result_unmarshaled_if_argc?: number; - needs_root_buffer?: boolean; - key?: string; - name?: string; - needs_root?: boolean; - compiled_variadic_function?: VariadicConverterFunction | null; - compiled_function?: ConverterFunction | null; - scratchRootBuffer?: WasmRootBuffer | null; - scratchBuffer?: VoidPtr; - scratchValueRoot?: WasmRoot; - has_warned_about_signature?: boolean; - convert?: Function | null; - method?: MonoMethod | null; -} - -export type BoundMethodToken = { - method: MonoMethod; - converter: Converter | null; - scratchRootBuffer: WasmRootBuffer | null; - scratchBuffer: VoidPtr; - scratchResultRoot: WasmRoot; - scratchExceptionRoot: WasmRoot; - scratchThisArgRoot: WasmRoot; -} - -function _handle_exception_for_call( - converter: Converter | undefined, token: BoundMethodToken | null, - buffer: VoidPtr, resultRoot: WasmRoot, - exceptionRoot: WasmRoot, - thisArgRoot: WasmRoot, - sp: VoidPtr -): void { - const exc = _convert_exception_for_method_call(resultRoot, exceptionRoot); - if (!exc) - return; - - _teardown_after_call(converter, token, buffer, resultRoot, exceptionRoot, thisArgRoot, sp); - throw exc; -} - -function _convert_exception_for_method_call(result: WasmRoot, exception: WasmRoot) { - if (exception.value === MonoObjectNull) - return null; - - const msg = monoStringToString(result); - const err = new Error(msg!); //the convention is that invoke_method ToString () any outgoing exception - // console.warn (`error ${msg} at location ${err.stack}); - return err; -} - -export function mono_method_resolve(fqn: string): MonoMethod { - const { assembly, namespace, classname, methodname } = parseFQN(fqn); - - const asm = cwraps.mono_wasm_assembly_load(assembly); - if (!asm) - throw new Error("Could not find assembly: " + assembly); - - const klass = cwraps.mono_wasm_assembly_find_class(asm, namespace, classname); - if (!klass) - throw new Error("Could not find class: " + namespace + ":" + classname + " in assembly " + assembly); - - const method = cwraps.mono_wasm_assembly_find_method(klass, methodname, -1); - if (!method) - throw new Error("Could not find method: " + methodname); - return method; -} - -export function mono_method_get_call_signature_ref(method: MonoMethod, mono_obj?: WasmRoot): string/*ArgsMarshalString*/ { - return legacyManagedExports._get_call_sig_ref(method, mono_obj ? mono_obj.address : legacyHelpers._null_root.address); -} - -export function assert_legacy_interop(): void { - if (MonoWasmThreads) { - mono_assert(!ENVIRONMENT_IS_PTHREAD, "Legacy interop is not supported with WebAssembly threads."); - } - assert_js_interop(); -} \ No newline at end of file diff --git a/src/mono/browser/runtime/net6-legacy/method-calls.ts b/src/mono/browser/runtime/net6-legacy/method-calls.ts deleted file mode 100644 index a2033b256f000..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/method-calls.ts +++ /dev/null @@ -1,307 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { mono_wasm_get_jsobj_from_js_handle } from "../gc-handles"; -import { Module, INTERNAL, loaderHelpers } from "../globals"; -import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; -import { _release_temp_frame } from "../memory"; -import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots"; -import { find_entry_point } from "../run"; -import { monoStringToString, stringToMonoStringRoot } from "../strings"; -import { JSHandle, MonoStringRef, MonoObjectRef, MonoArray, MonoString, MonoObject, is_nullish, WasmRoot } from "../types/internal"; -import { Int32Ptr, VoidPtr } from "../types/emscripten"; -import { mono_array_root_to_js_array, unbox_mono_obj_root } from "./cs-to-js"; -import { js_array_to_mono_array, js_to_mono_obj_root } from "./js-to-cs"; -import { Converter, BoundMethodToken, mono_method_resolve, mono_method_get_call_signature_ref, mono_bind_method, assert_legacy_interop } from "./method-binding"; - -const boundMethodsByFqn: Map = new Map(); - -export function _teardown_after_call( - converter: Converter | undefined, token: BoundMethodToken | null, - buffer: VoidPtr, - resultRoot: WasmRoot, - exceptionRoot: WasmRoot, - thisArgRoot: WasmRoot, - sp: VoidPtr -): void { - _release_temp_frame(); - Module.stackRestore(sp); - - if (typeof (resultRoot) === "object") { - resultRoot.clear(); - if ((token !== null) && (token.scratchResultRoot === null)) - token.scratchResultRoot = resultRoot; - else - resultRoot.release(); - } - if (typeof (exceptionRoot) === "object") { - exceptionRoot.clear(); - if ((token !== null) && (token.scratchExceptionRoot === null)) - token.scratchExceptionRoot = exceptionRoot; - else - exceptionRoot.release(); - } - if (typeof (thisArgRoot) === "object") { - thisArgRoot.clear(); - if ((token !== null) && (token.scratchThisArgRoot === null)) - token.scratchThisArgRoot = thisArgRoot; - else - thisArgRoot.release(); - } -} - -export function mono_bind_static_method(fqn: string, signature?: string/*ArgsMarshalString*/): Function { - assert_legacy_interop(); - - const key = `${fqn}-${signature}`; - let js_method = boundMethodsByFqn.get(key); - if (js_method === undefined) { - const method = mono_method_resolve(fqn); - - if (typeof signature === "undefined") - signature = mono_method_get_call_signature_ref(method, undefined); - - js_method = mono_bind_method(method, signature!, false, fqn); - boundMethodsByFqn.set(key, js_method); - } - return js_method; -} - -export function mono_bind_assembly_entry_point(assembly: string, signature?: string/*ArgsMarshalString*/): Function { - assert_legacy_interop(); - const method = find_entry_point(assembly); - if (typeof (signature) !== "string") - signature = mono_method_get_call_signature_ref(method, undefined); - - const js_method = mono_bind_method(method, signature!, false, "_" + assembly + "__entrypoint"); - - return async function (...args: any[]) { - loaderHelpers.assert_runtime_running(); - if (args.length > 0 && Array.isArray(args[0])) - args[0] = js_array_to_mono_array(args[0], true, false); - return js_method(...args); - }; -} - -export function mono_call_assembly_entry_point(assembly: string, args?: any[], signature?: string/*ArgsMarshalString*/): number { - assert_legacy_interop(); - if (!args) { - args = [[]]; - } - return mono_bind_assembly_entry_point(assembly, signature)(...args); -} - -export function mono_wasm_invoke_js_with_args_ref(js_handle: JSHandle, method_name: MonoStringRef, args: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): any { - assert_legacy_interop(); - const argsRoot = mono_wasm_new_external_root(args), - nameRoot = mono_wasm_new_external_root(method_name), - resultRoot = mono_wasm_new_external_root(result_address); - try { - const js_name = monoStringToString(nameRoot); - if (!js_name || (typeof (js_name) !== "string")) { - wrap_error_root(is_exception, "ERR12: Invalid method name object @" + nameRoot.value, resultRoot); - return; - } - - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(obj)) { - wrap_error_root(is_exception, "ERR13: Invalid JS object handle '" + js_handle + "' while invoking '" + js_name + "'", resultRoot); - return; - } - - const js_args = mono_array_root_to_js_array(argsRoot); - - try { - const m = obj[js_name]; - if (typeof m === "undefined") - throw new Error("Method: '" + js_name + "' not found for: '" + Object.prototype.toString.call(obj) + "'"); - const res = m.apply(obj, js_args); - - js_to_mono_obj_root(res, resultRoot, true); - wrap_no_error_root(is_exception); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } - } finally { - argsRoot.release(); - nameRoot.release(); - resultRoot.release(); - } -} - -export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoStringRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - assert_legacy_interop(); - const nameRoot = mono_wasm_new_external_root(property_name), - resultRoot = mono_wasm_new_external_root(result_address); - try { - const js_name = monoStringToString(nameRoot); - if (!js_name) { - wrap_error_root(is_exception, "Invalid property name object '" + nameRoot.value + "'", resultRoot); - return; - } - - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(obj)) { - wrap_error_root(is_exception, "ERR01: Invalid JS object handle '" + js_handle + "' while geting '" + js_name + "'", resultRoot); - return; - } - - const m = obj[js_name]; - js_to_mono_obj_root(m, resultRoot, true); - wrap_no_error_root(is_exception); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } finally { - resultRoot.release(); - nameRoot.release(); - } -} - -export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoStringRef, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - assert_legacy_interop(); - const valueRoot = mono_wasm_new_external_root(value), - nameRoot = mono_wasm_new_external_root(property_name), - resultRoot = mono_wasm_new_external_root(result_address); - try { - - const property = monoStringToString(nameRoot); - if (!property) { - wrap_error_root(is_exception, "Invalid property name object '" + property_name + "'", resultRoot); - return; - } - - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(js_obj)) { - wrap_error_root(is_exception, "ERR02: Invalid JS object handle '" + js_handle + "' while setting '" + property + "'", resultRoot); - return; - } - - const js_value = unbox_mono_obj_root(valueRoot); - - if (createIfNotExist) { - js_obj[property] = js_value; - } - else { - if (!createIfNotExist) { - if (!Object.prototype.hasOwnProperty.call(js_obj, property)) { - return; - } - } - if (hasOwnProperty === true) { - if (Object.prototype.hasOwnProperty.call(js_obj, property)) { - js_obj[property] = js_value; - } - } - else { - js_obj[property] = js_value; - } - } - wrap_no_error_root(is_exception, resultRoot); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } finally { - resultRoot.release(); - nameRoot.release(); - valueRoot.release(); - } -} - -export function mono_wasm_get_by_index_ref(js_handle: JSHandle, property_index: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - assert_legacy_interop(); - const resultRoot = mono_wasm_new_external_root(result_address); - try { - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(obj)) { - wrap_error_root(is_exception, "ERR03: Invalid JS object handle '" + js_handle + "' while getting [" + property_index + "]", resultRoot); - return; - } - - const m = obj[property_index]; - js_to_mono_obj_root(m, resultRoot, true); - wrap_no_error_root(is_exception); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } finally { - resultRoot.release(); - } -} - -export function mono_wasm_set_by_index_ref(js_handle: JSHandle, property_index: number, value: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - assert_legacy_interop(); - const valueRoot = mono_wasm_new_external_root(value), - resultRoot = mono_wasm_new_external_root(result_address); - try { - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (is_nullish(obj)) { - wrap_error_root(is_exception, "ERR04: Invalid JS object handle '" + js_handle + "' while setting [" + property_index + "]", resultRoot); - return; - } - - const js_value = unbox_mono_obj_root(valueRoot); - obj[property_index] = js_value; - wrap_no_error_root(is_exception, resultRoot); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } finally { - resultRoot.release(); - valueRoot.release(); - } -} - -export function mono_wasm_get_global_object_ref(global_name: MonoStringRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - assert_legacy_interop(); - const nameRoot = mono_wasm_new_external_root(global_name), - resultRoot = mono_wasm_new_external_root(result_address); - try { - const js_name = monoStringToString(nameRoot); - - let globalObj; - - if (!js_name) { - globalObj = globalThis; - } - else if (js_name == "Module") { - globalObj = Module; - } - else if (js_name == "INTERNAL") { - globalObj = INTERNAL; - } - else { - globalObj = (globalThis)[js_name]; - } - - // TODO returning null may be useful when probing for browser features - if (globalObj === null || typeof globalObj === undefined) { - wrap_error_root(is_exception, "Global object '" + js_name + "' not found.", resultRoot); - return; - } - - js_to_mono_obj_root(globalObj, resultRoot, true); - wrap_no_error_root(is_exception); - } catch (ex) { - wrap_error_root(is_exception, ex, resultRoot); - } finally { - resultRoot.release(); - nameRoot.release(); - } -} - -// Blazor specific custom routine -export function mono_wasm_invoke_js_blazor(exceptionMessage: Int32Ptr, callInfo: any, arg0: any, arg1: any, arg2: any): void | number { - try { - assert_legacy_interop(); - const blazorExports = (globalThis).Blazor; - if (!blazorExports) { - throw new Error("The blazor.webassembly.js library is not loaded."); - } - - return blazorExports._internal.invokeJSFromDotNet(callInfo, arg0, arg1, arg2); - } catch (ex: any) { - const exceptionJsString = ex.message + "\n" + ex.stack; - const exceptionRoot = mono_wasm_new_root(); - stringToMonoStringRoot(exceptionJsString, exceptionRoot); - exceptionRoot.copy_to_address(exceptionMessage); - exceptionRoot.release(); - return 0; - } -} diff --git a/src/mono/browser/runtime/net6-legacy/strings.ts b/src/mono/browser/runtime/net6-legacy/strings.ts deleted file mode 100644 index f651100c67290..0000000000000 --- a/src/mono/browser/runtime/net6-legacy/strings.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { mono_assert } from "../globals"; -import { mono_wasm_new_root } from "../roots"; -import { interned_string_table, mono_wasm_empty_string, stringToInternedMonoStringRoot, stringToMonoStringRoot } from "../strings"; -import { MonoString, is_nullish } from "../types/internal"; - -import { assert_legacy_interop } from "./method-binding"; - -/** - * @deprecated Not GC or thread safe - */ -export function stringToMonoStringUnsafe(string: string): MonoString { - assert_legacy_interop(); - const temp = mono_wasm_new_root(); - try { - stringToMonoStringRoot(string, temp); - return temp.value; - } finally { - temp.release(); - } -} - -// this is only used in legacy unit tests -export function stringToMonoStringIntern(string: string): string { - if (string.length === 0) - return mono_wasm_empty_string; - - const root = mono_wasm_new_root(); - try { - stringToInternedMonoStringRoot(string, root); - const result = interned_string_table.get(root.value); - mono_assert(!is_nullish(result), "internal error: interned_string_table did not contain string after stringToMonoStringIntern"); - return result; - } - finally { - root.release(); - } -} diff --git a/src/mono/browser/runtime/rollup.config.js b/src/mono/browser/runtime/rollup.config.js index 4c1622e8f829f..769d6a01518ae 100644 --- a/src/mono/browser/runtime/rollup.config.js +++ b/src/mono/browser/runtime/rollup.config.js @@ -22,11 +22,10 @@ const wasmObjDir = process.env.WasmObjDir ? process.env.WasmObjDir.replace(/"/g, const monoWasmThreads = process.env.MonoWasmThreads === "true" ? true : false; const wasmEnableSIMD = process.env.WASM_ENABLE_SIMD === "1" ? true : false; const wasmEnableExceptionHandling = process.env.WASM_ENABLE_EH === "1" ? true : false; -const wasmEnableLegacyJsInterop = process.env.DISABLE_LEGACY_JS_INTEROP !== "1" ? true : false; const wasmEnableJsInteropByValue = process.env.ENABLE_JS_INTEROP_BY_VALUE == "1" ? true : false; const monoDiagnosticsMock = process.env.MonoDiagnosticsMock === "true" ? true : false; // because of stack walk at src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs -// and unit test at src\libraries\System.Runtime.InteropServices.JavaScript\tests\System.Runtime.InteropServices.JavaScript.Legacy.UnitTests\timers.mjs +// and unit test at with timers.mjs const keep_fnames = /(mono_wasm_runtime_ready|mono_wasm_fire_debugger_agent_message_with_data|mono_wasm_fire_debugger_agent_message_with_data_to_pause|mono_wasm_schedule_timer_tick)/; const keep_classnames = /(ManagedObject|ManagedError|Span|ArraySegment|WasmRootBuffer|SessionOptionsBuilder)/; const terserConfig = { @@ -103,7 +102,6 @@ const envConstants = { wasmEnableExceptionHandling, monoDiagnosticsMock, gitHash, - wasmEnableLegacyJsInterop, wasmEnableJsInteropByValue, isContinuousIntegrationBuild, }; @@ -215,20 +213,6 @@ const typesConfig = { external: externalDependencies, plugins: [dts()], }; -const legacyTypesConfig = { - input: "./net6-legacy/export-types.ts", - output: [ - { - format: "es", - file: nativeBinDir + "/dotnet-legacy.d.ts", - banner: banner_dts, - plugins: [writeOnChangePlugin()], - } - ], - external: externalDependencies, - plugins: [dts()], -}; - let diagnosticMockTypesConfig = undefined; @@ -241,12 +225,6 @@ if (isDebug) { banner: banner_dts, plugins: [alwaysLF(), writeOnChangePlugin()], }); - legacyTypesConfig.output.push({ - format: "es", - file: "./dotnet-legacy.d.ts", - banner: banner_dts, - plugins: [alwaysLF(), writeOnChangePlugin()], - }); // export types into the source code and commit to git diagnosticMockTypesConfig = { @@ -289,7 +267,6 @@ const allConfigs = [ runtimeConfig, wasmImportsConfig, typesConfig, - legacyTypesConfig, ].concat(workerConfigs) .concat(diagnosticMockTypesConfig ? [diagnosticMockTypesConfig] : []); export default defineConfig(allConfigs); diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts index 8ba863664e9d9..55088f67fe72a 100644 --- a/src/mono/browser/runtime/startup.ts +++ b/src/mono/browser/runtime/startup.ts @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import { DotnetModuleInternal, CharPtrNull } from "./types/internal"; -import { linkerDisableLegacyJsInterop, ENVIRONMENT_IS_PTHREAD, ENVIRONMENT_IS_NODE, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers, createPromiseController, mono_assert, linkerWasmEnableSIMD, linkerWasmEnableEH, ENVIRONMENT_IS_WORKER } from "./globals"; +import { ENVIRONMENT_IS_NODE, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers, createPromiseController, mono_assert, linkerWasmEnableSIMD, linkerWasmEnableEH, ENVIRONMENT_IS_WORKER } from "./globals"; import cwraps, { init_c_exports, threads_c_functions as tcwraps } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; @@ -30,11 +29,6 @@ import { preAllocatePThreadWorkerPool, instantiateWasmPThreadWorkerPool } from " import { currentWorkerThreadEvents, dotnetPthreadCreated, initWorkerThreadEvents } from "./pthreads/worker"; import { mono_wasm_main_thread_ptr } from "./pthreads/shared"; import { jiterpreter_allocate_tables } from "./jiterpreter-support"; - -// legacy -import { init_legacy_exports } from "./net6-legacy/corebindings"; -import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy"; -import { BINDING, MONO } from "./net6-legacy/globals"; import { localHeapViewU8 } from "./memory"; import { assertNoProxies } from "./gc-handles"; @@ -382,10 +376,6 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { init_c_exports(); cwraps_internal(INTERNAL); - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { - cwraps_mono_api(MONO); - cwraps_binding_api(BINDING); - } // removeRunDependency triggers the dependenciesFulfilled callback (runCaller) in // emscripten - on a worker since we don't have any other dependencies that causes run() to get // called too soon; and then it will get called a second time when dotnet.native.js calls it directly. @@ -409,24 +399,6 @@ async function mono_wasm_pre_init_essential_async(): Promise { async function mono_wasm_after_user_runtime_initialized(): Promise { mono_log_debug("mono_wasm_after_user_runtime_initialized"); try { - if (!Module.disableDotnet6Compatibility && Module.exports) { - // Export emscripten defined in module through EXPORTED_RUNTIME_METHODS - // Useful to export IDBFS or other similar types generally exposed as - // global types when emscripten is not modularized. - const globalThisAny = globalThis as any; - for (let i = 0; i < Module.exports.length; ++i) { - const exportName = Module.exports[i]; - const exportValue = (Module)[exportName]; - - if (exportValue != undefined) { - globalThisAny[exportName] = exportValue; - } - else { - mono_log_warn(`The exported symbol ${exportName} could not be found in the emscripten module`); - } - } - } - mono_log_debug("Initializing mono runtime"); if (Module.onDotnetReady) { @@ -606,9 +578,6 @@ export function bindings_init(): void { const mark = startMeasure(); strings_init(); init_managed_exports(); - if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop && !ENVIRONMENT_IS_PTHREAD) { - init_legacy_exports(); - } initialize_marshalers_to_js(); initialize_marshalers_to_cs(); runtimeHelpers._i52_error_scratch_buffer = Module._malloc(4); diff --git a/src/mono/browser/runtime/tsconfig.shared.json b/src/mono/browser/runtime/tsconfig.shared.json index 94b120645d1d1..7515efada53d7 100644 --- a/src/mono/browser/runtime/tsconfig.shared.json +++ b/src/mono/browser/runtime/tsconfig.shared.json @@ -16,7 +16,6 @@ }, "exclude": [ "dotnet.d.ts", - "dotnet-legacy.d.ts", "diagnostics-mock.d.ts", "bin" ] diff --git a/src/mono/browser/runtime/types/emscripten.ts b/src/mono/browser/runtime/types/emscripten.ts index 66ad8bb5aad01..a9691cde49061 100644 --- a/src/mono/browser/runtime/types/emscripten.ts +++ b/src/mono/browser/runtime/types/emscripten.ts @@ -23,25 +23,6 @@ export declare interface CharPtrPtr extends NativePointer { } export declare interface EmscriptenModule { - /** @deprecated Please use localHeapViewI8() instead.*/ - HEAP8: Int8Array, - /** @deprecated Please use localHeapViewI16() instead.*/ - HEAP16: Int16Array; - /** @deprecated Please use localHeapViewI32() instead. */ - HEAP32: Int32Array; - /** @deprecated Please use localHeapViewI64() instead. */ - HEAP64: BigInt64Array; - /** @deprecated Please use localHeapViewU8() instead. */ - HEAPU8: Uint8Array; - /** @deprecated Please use localHeapViewU16() instead. */ - HEAPU16: Uint16Array; - /** @deprecated Please use localHeapViewU32() instead */ - HEAPU32: Uint32Array; - /** @deprecated Please use localHeapViewF32() instead */ - HEAPF32: Float32Array; - /** @deprecated Please use localHeapViewF64() instead. */ - HEAPF64: Float64Array; - // this should match emcc -s EXPORTED_FUNCTIONS _malloc(size: number): VoidPtr; _free(ptr: VoidPtr): void; diff --git a/src/mono/browser/runtime/types/index.ts b/src/mono/browser/runtime/types/index.ts index c47d4bd2bd72a..13e71c1fc240e 100644 --- a/src/mono/browser/runtime/types/index.ts +++ b/src/mono/browser/runtime/types/index.ts @@ -329,8 +329,6 @@ export const enum GlobalizationMode { } export type DotnetModuleConfig = { - disableDotnet6Compatibility?: boolean, - config?: MonoConfig, configSrc?: string, onConfigLoaded?: (config: MonoConfig) => void | Promise; @@ -387,14 +385,6 @@ export type APIType = { } export type RuntimeAPI = { - /** - * @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts - */ - MONO: any, - /** - * @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts - */ - BINDING: any, INTERNAL: any, Module: EmscriptenModule, runtimeId: number, diff --git a/src/mono/browser/runtime/types/internal.ts b/src/mono/browser/runtime/types/internal.ts index c97d4c98f0211..00b02c60ad396 100644 --- a/src/mono/browser/runtime/types/internal.ts +++ b/src/mono/browser/runtime/types/internal.ts @@ -284,7 +284,6 @@ export function is_nullish(value: T | null | undefined): value is null | unde export type EmscriptenInternals = { isPThread: boolean, - linkerDisableLegacyJsInterop: boolean, linkerWasmEnableSIMD: boolean, linkerWasmEnableEH: boolean, linkerEnableAotProfiler: boolean, @@ -453,6 +452,16 @@ export interface WasmRootBuffer { } export declare interface EmscriptenModuleInternal { + HEAP8: Int8Array, + HEAP16: Int16Array; + HEAP32: Int32Array; + HEAP64: BigInt64Array; + HEAPU8: Uint8Array; + HEAPU16: Uint16Array; + HEAPU32: Uint32Array; + HEAPF32: Float32Array; + HEAPF64: Float64Array; + __locateFile?: (path: string, prefix?: string) => string; locateFile?: (path: string, prefix?: string) => string; mainScriptUrlOrBlob?: string; diff --git a/src/mono/browser/runtime/wasm-config.h.in b/src/mono/browser/runtime/wasm-config.h.in index 044bac4959808..d8a2d8127c2ec 100644 --- a/src/mono/browser/runtime/wasm-config.h.in +++ b/src/mono/browser/runtime/wasm-config.h.in @@ -7,9 +7,6 @@ /* Support for threads is disabled */ #cmakedefine DISABLE_THREADS -/* Support for legacy JS interop is disabled */ -#cmakedefine DISABLE_LEGACY_JS_INTEROP - /* Support for JS interop without pointers to managed objects */ #cmakedefine ENABLE_JS_INTEROP_BY_VALUE 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 acbf0c5ecdaaf..028b54fd5677f 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 @@ -45,7 +45,6 @@ <_WasmPropertiesDifferFromRuntimePackThusNativeBuildNeeded Condition=" - '$(WasmEnableLegacyJsInterop)' == 'false' or '$(WasmEnableSIMD)' == 'false' or '$(WasmEnableExceptionHandling)' == 'false' or '$(InvariantTimezone)' == 'true' or 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 a16c12098f18e..fee308d1230f9 100644 --- a/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj +++ b/src/mono/sample/wasm/browser-advanced/Wasm.Advanced.Sample.csproj @@ -4,7 +4,6 @@ true true true - false false true true diff --git a/src/mono/sample/wasm/browser-bench/JSInterop.cs b/src/mono/sample/wasm/browser-bench/JSInterop.cs index 2c1830f39987a..285491644a1a0 100644 --- a/src/mono/sample/wasm/browser-bench/JSInterop.cs +++ b/src/mono/sample/wasm/browser-bench/JSInterop.cs @@ -25,9 +25,7 @@ class JSInteropTask : BenchTask public JSInteropTask() { measurements = new Measurement[] { - new LegacyExportIntMeasurement(), new JSExportIntMeasurement(), - new LegacyExportStringMeasurement(), new JSExportStringMeasurement(), new JSImportIntMeasurement(), new JSImportStringMeasurement(), @@ -38,18 +36,6 @@ public JSInteropTask() }; } - public class LegacyExportIntMeasurement : BenchTask.Measurement - { - public override int InitialSamples => 3; - public override string Name => "LegacyExportInt"; - // because of the aggressive trimming of methods reachable via JS legacy bind_static_method - [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "Sample.ImportsExportsHelper", Test.AssemblyName)] - public override void RunStep() - { - ImportsExportsHelper.RunLegacyExportInt(10000); - } - } - public class JSExportIntMeasurement : BenchTask.Measurement { public override int InitialSamples => 10; @@ -60,19 +46,6 @@ public override void RunStep() } } - public class LegacyExportStringMeasurement : BenchTask.Measurement - { - public override int InitialSamples => 3; - public override string Name => "LegacyExportString"; - - // because of the aggressive trimming of methods reachable via JS legacy bind_static_method - [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "Sample.ImportsExportsHelper", Test.AssemblyName)] - public override void RunStep() - { - ImportsExportsHelper.RunLegacyExportString(10000); - } - } - public class JSExportStringMeasurement : BenchTask.Measurement { public override int InitialSamples => 3; @@ -187,15 +160,9 @@ public override void RunStep() partial class ImportsExportsHelper { - [JSImport("Sample.Test.runLegacyExportInt", "main.js")] - public static partial void RunLegacyExportInt(int count); - [JSImport("Sample.Test.runJSExportInt", "main.js")] public static partial void RunJSExportInt(int count); - [JSImport("Sample.Test.runLegacyExportString", "main.js")] - public static partial void RunLegacyExportString(int count); - [JSImport("Sample.Test.runJSExportString", "main.js")] public static partial void RunJSExportString(int count); @@ -211,12 +178,6 @@ partial class ImportsExportsHelper [JSImport("Sample.Test.importTargetThrows", "main.js")] public static partial void ImportTargetThrows(int value); - [MethodImpl(MethodImplOptions.NoInlining)] - public static int LegacyExportTargetInt(int value) - { - return value + 1; - } - [JSImport("Sample.Test.importTargetManyArgs", "main.js")] public static partial double ImportTargetManyArgs(int arg1, int arg2, string arg3, string arg4, IntPtr arg5, bool arg6, [JSMarshalAs] long arg7, int? arg8, double arg9, @@ -229,12 +190,6 @@ public static int JSExportTargetInt(int value) return value + 1; } - [MethodImpl(MethodImplOptions.NoInlining)] - public static string LegacyExportTargetString(string value) - { - return value + "A"; - } - [JSExport] public static string JSExportTargetString(string value) { diff --git a/src/mono/sample/wasm/browser-bench/main.js b/src/mono/sample/wasm/browser-bench/main.js index f0302ae161164..da1d7255e7393 100644 --- a/src/mono/sample/wasm/browser-bench/main.js +++ b/src/mono/sample/wasm/browser-bench/main.js @@ -9,30 +9,16 @@ let runBenchmark; let setTasks; let setExclusions; let getFullJsonResults; -let legacyExportTargetInt; let jsExportTargetInt; -let legacyExportTargetString; let jsExportTargetString; let _jiterpreter_dump_stats, _interp_pgo_save_data; -function runLegacyExportInt(count) { - for (let i = 0; i < count; i++) { - legacyExportTargetInt(i); - } -} - function runJSExportInt(count) { for (let i = 0; i < count; i++) { jsExportTargetInt(i); } } -function runLegacyExportString(count) { - for (let i = 0; i < count; i++) { - legacyExportTargetString("A" + i); - } -} - function runJSExportString(count) { for (let i = 0; i < count; i++) { jsExportTargetString("A" + i); @@ -61,7 +47,7 @@ function importTargetThrows(value) { } class MainApp { - async init({ getAssemblyExports, setModuleImports, BINDING, INTERNAL }) { + async init({ getAssemblyExports, setModuleImports, INTERNAL }) { const exports = await getAssemblyExports("Wasm.Browser.Bench.Sample.dll"); // Capture these two internal APIs for use at the end of the benchmark run _jiterpreter_dump_stats = INTERNAL.jiterpreter_dump_stats.bind(INTERNAL); @@ -71,17 +57,13 @@ class MainApp { setExclusions = exports.Sample.Test.SetExclusions; getFullJsonResults = exports.Sample.Test.GetFullJsonResults; - legacyExportTargetInt = BINDING.bind_static_method("[Wasm.Browser.Bench.Sample]Sample.ImportsExportsHelper:LegacyExportTargetInt"); jsExportTargetInt = exports.Sample.ImportsExportsHelper.JSExportTargetInt; - legacyExportTargetString = BINDING.bind_static_method("[Wasm.Browser.Bench.Sample]Sample.ImportsExportsHelper:LegacyExportTargetString"); jsExportTargetString = exports.Sample.ImportsExportsHelper.JSExportTargetString; setModuleImports("main.js", { Sample: { Test: { - runLegacyExportInt, runJSExportInt, - runLegacyExportString, runJSExportString, importTargetInt, importTargetString, @@ -209,9 +191,9 @@ class MainApp { return; console.error(`waitFor ${eventName} timed out`); promiseResolve(); - // Make sure this timeout is big enough that it won't cause measurements - // to be truncated! i.e. "Blazor Reach managed cold" is nearly 10k in some - // configurations right now + // Make sure this timeout is big enough that it won't cause measurements + // to be truncated! i.e. "Blazor Reach managed cold" is nearly 10k in some + // configurations right now }, 20000); document.body.appendChild(this._frame); diff --git a/src/mono/sample/wasm/browser-webpack/Wasm.Browser.WebPack.Sample.csproj b/src/mono/sample/wasm/browser-webpack/Wasm.Browser.WebPack.Sample.csproj index 8c59adb0a7b9e..6914ae4ef6780 100644 --- a/src/mono/sample/wasm/browser-webpack/Wasm.Browser.WebPack.Sample.csproj +++ b/src/mono/sample/wasm/browser-webpack/Wasm.Browser.WebPack.Sample.csproj @@ -15,7 +15,6 @@ $(WasmAppDir)/dotnet.native.js; $(WasmAppDir)/dotnet.native.wasm; $(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts; - $(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts; $(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json;" Outputs="bin/dotnet-runtime/.npm-stamp"> @@ -23,7 +22,6 @@ - diff --git a/src/mono/sample/wasm/console-node-ts/Wasm.Console.Node.TS.Sample.csproj b/src/mono/sample/wasm/console-node-ts/Wasm.Console.Node.TS.Sample.csproj index 97375d88fd50f..ed001522008a1 100644 --- a/src/mono/sample/wasm/console-node-ts/Wasm.Console.Node.TS.Sample.csproj +++ b/src/mono/sample/wasm/console-node-ts/Wasm.Console.Node.TS.Sample.csproj @@ -9,11 +9,9 @@ --> - diff --git a/src/mono/sample/wasm/node-webpack/Wasm.Node.WebPack.Sample.csproj b/src/mono/sample/wasm/node-webpack/Wasm.Node.WebPack.Sample.csproj index 88216d3e1258b..175391e345791 100644 --- a/src/mono/sample/wasm/node-webpack/Wasm.Node.WebPack.Sample.csproj +++ b/src/mono/sample/wasm/node-webpack/Wasm.Node.WebPack.Sample.csproj @@ -9,7 +9,6 @@ $(WasmAppDir)/_framework/dotnet.native.js; $(WasmAppDir)/_framework/dotnet.native.wasm; $(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet.d.ts; - $(MicrosoftNetCoreAppRuntimePackNativeDir)/dotnet-legacy.d.ts; $(MicrosoftNetCoreAppRuntimePackNativeDir)/package.json;" Outputs="bin/dotnet-runtime/.npm-stamp"> @@ -17,7 +16,6 @@ - diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs index 643b247484794..fba17daea55d9 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/WorkloadRequiredTests.cs @@ -22,7 +22,6 @@ public class WorkloadRequiredTests : BlazorWasmTestBase public static (string propertyName, bool triggerValue)[] PropertiesWithTriggerValues = new[] { ("RunAOTCompilation", true), - ("WasmEnableLegacyJsInterop", false), ("WasmEnableSIMD", false), ("WasmEnableExceptionHandling", false), ("InvariantTimezone", true), diff --git a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs index 7974e22506da3..0fd78da40da58 100644 --- a/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/WasmNativeDefaultsTests.cs @@ -23,7 +23,6 @@ public static TheoryData SettingDifferentFromV { List<(string propertyName, bool defaultValueInRuntimePack)> defaults = new() { - ("WasmEnableLegacyJsInterop", true), ("WasmEnableSIMD", true), ("WasmEnableExceptionHandling", true), ("InvariantTimezone", false), @@ -128,10 +127,10 @@ public void DefaultsWithPublish(string config, string extraProperties, bool aot, public static TheoryData SetWasmNativeStripExplicitlyWithWasmBuildNativeTestData() => new() { - { "Debug", "falsefalse", true, false }, - { "Release", "falsefalse", true, false }, - { "Debug", "truefalse", true, true }, - { "Release", "truefalse", true, true } + { "Debug", "falsetrue", true, false }, + { "Release", "falsetrue", true, false }, + { "Debug", "truetrue", true, true }, + { "Release", "truetrue", true, true } }; [Theory] diff --git a/src/mono/wasm/build/README.md b/src/mono/wasm/build/README.md index 33b0a14394656..473ecf376bb50 100644 --- a/src/mono/wasm/build/README.md +++ b/src/mono/wasm/build/README.md @@ -32,8 +32,6 @@ Implementation: - *after* any of the wasm build targets, use `AfterTargets="WasmBuildApp"` on that target - Avoid depending on this target, because it is available only when the workload is installed. Use `$(WasmNativeWorkload)` to check if it is installed. -- When `Module.disableDotnet6Compatibility` is set it would not pollute global namespace. - ## `Publish` Implementation: diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index ba7cf7f700ac3..3f3a97fff9b3f 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -68,7 +68,6 @@ - $(RunAOTCompilationAfterBuild) - Run AOT compilation even after Build. By default, it is run only for publish. Defaults to false. - $(WasmAotProfilePath) - Path to an AOT profile file. - - $(WasmEnableLegacyJsInterop) - Include support for legacy JS interop. Defaults to true. - $(WasmEnableExceptionHandling) - Enable support for the WASM post MVP Exception Handling runtime extension. - $(WasmEnableSIMD) - Enable support for the WASM post MVP SIMD runtime extension. - $(WasmEnableWebcil) - Enable conversion of assembly .dlls to Webcil wrapped in .wasm (default: true) diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index a8cd689ae0c32..8ba47325c39e6 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -220,51 +220,29 @@ let mono_exit = (code, reason) => { }; const App = { - /** Runs a particular test in legacy interop tests - * @type {(method_name: string, args: any[]=, signature: any=) => return number} - */ - call_test_method: function (method_name, args, signature) { - // note: arguments here is the array of arguments passsed to this function - if ((arguments.length > 2) && (typeof (signature) !== "string")) - throw new Error("Invalid number of arguments for call_test_method"); - - const fqn = "[System.Runtime.InteropServices.JavaScript.Legacy.Tests]System.Runtime.InteropServices.JavaScript.Tests.HelperMarshal:" + method_name; - try { - const method = App.runtime.BINDING.bind_static_method(fqn, signature); - return method.apply(null, args || []); - } catch (exc) { - console.error("exception thrown in", fqn); - throw exc; - } - }, - create_function(...args) { const code = args.pop(); const arg_count = args.length; - args.push("MONO"); - args.push("BINDING"); args.push("INTERNAL"); const userFunction = new Function(...args, code); return function (...args) { - args[arg_count + 0] = globalThis.App.runtime.MONO; - args[arg_count + 1] = globalThis.App.runtime.BINDING; - args[arg_count + 2] = globalThis.App.runtime.INTERNAL; + args[arg_count] = globalThis.App.runtime.INTERNAL; return userFunction(...args); }; }, invoke_js(js_code) { - const closedEval = function (Module, MONO, BINDING, INTERNAL, code) { + const closedEval = function (Module, INTERNAL, code) { return eval(code); }; - const res = closedEval(globalThis.App.runtime.Module, globalThis.App.runtime.MONO, globalThis.App.runtime.BINDING, globalThis.App.runtime.INTERNAL, js_code); + const res = closedEval(globalThis.App.runtime.Module, globalThis.App.runtime.INTERNAL, js_code); return (res === undefined || res === null || typeof res === "string") ? null : res.toString(); } }; -globalThis.App = App; // Necessary as System.Runtime.InteropServices.JavaScript.Tests.MarshalTests (among others) call the App.call_test_method directly +globalThis.App = App; // Necessary as tests use it function configureRuntime(dotnet, runArgs) { dotnet