diff --git a/src/Uno.Foundation.Runtime.WebAssembly/Interop/Runtime.wasm.cs b/src/Uno.Foundation.Runtime.WebAssembly/Interop/Runtime.wasm.cs index 16d1077e3737..982c579ddc24 100644 --- a/src/Uno.Foundation.Runtime.WebAssembly/Interop/Runtime.wasm.cs +++ b/src/Uno.Foundation.Runtime.WebAssembly/Interop/Runtime.wasm.cs @@ -43,7 +43,7 @@ private static IntPtr GetMethodId(string methodName) { if (!MethodMap.TryGetValue(methodName, out var methodId)) { - MethodMap[methodName] = methodId = WebAssembly.JSInterop.InternalCalls.InvokeJSUnmarshalled(out _, methodName, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + MethodMap[methodName] = methodId = WebAssembly.Runtime.InvokeJSUnmarshalled(methodName, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); } return methodId; @@ -129,22 +129,15 @@ private static bool InnerInvokeJSUnmarshalled(string functionIdentifier, IntPtr exception = null; var methodId = GetMethodId(functionIdentifier); - var res = WebAssembly.JSInterop.InternalCalls.InvokeJSUnmarshalled(out var exceptionMessage, null, methodId, arg0, IntPtr.Zero); - - if (!string.IsNullOrEmpty(exceptionMessage)) + try { - if (_trace.IsEnabled) - { - _trace.WriteEvent( - TraceProvider.InvokeException, - new object[] { functionIdentifier, exceptionMessage } - ); - } - - exception = new Exception(exceptionMessage); + return WebAssembly.Runtime.InvokeJSUnmarshalled(null, methodId, arg0, IntPtr.Zero) != 0; + } + catch (Exception e) + { + exception = e; + return false; } - - return res != IntPtr.Zero; } /// @@ -181,22 +174,7 @@ private static bool InnerInvokeJSUnmarshalled(string functionIdentifier, IntPtr { var methodId = GetMethodId(functionIdentifier); - var res = WebAssembly.JSInterop.InternalCalls.InvokeJSUnmarshalled(out var exception, null, methodId, arg0, arg1); - - if (exception != null) - { - if (_trace.IsEnabled) - { - _trace.WriteEvent( - TraceProvider.InvokeException, - new object[] { functionIdentifier, exception.ToString() } - ); - } - - throw new Exception(exception); - } - - return res != IntPtr.Zero; + return WebAssembly.Runtime.InvokeJSUnmarshalled(null, methodId, arg0, arg1) != 0; } #pragma warning disable CA2211 diff --git a/src/Uno.Foundation.Runtime.WebAssembly/Interop/WebAssembly.Runtime.cs b/src/Uno.Foundation.Runtime.WebAssembly/Interop/WebAssembly.Runtime.cs index 359ab371fbe3..ea1b962275f3 100644 --- a/src/Uno.Foundation.Runtime.WebAssembly/Interop/WebAssembly.Runtime.cs +++ b/src/Uno.Foundation.Runtime.WebAssembly/Interop/WebAssembly.Runtime.cs @@ -2,60 +2,28 @@ using System.ComponentModel; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices.JavaScript; using Uno.Foundation.Runtime.WebAssembly.Interop; namespace WebAssembly { [Obfuscation(Feature = "renaming", Exclude = true)] - internal sealed class Runtime + internal sealed partial class Runtime { - internal static bool RethrowNativeExceptions { get; set; } = true; - - /// - /// Mono specific internal call. - /// - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern string InvokeJS(string str, out int exceptional_result); - - // Disable inlining to avoid the interpreter to evaluate an internal call that may not be available - [MethodImpl(MethodImplOptions.NoInlining)] - private static string NetCoreInvokeJS(string str, out int exceptionResult) - => Interop.Runtime.InvokeJS(str, out exceptionResult); - /// /// Invokes Javascript code in the hosting environment /// - internal static string InvokeJS(string str) - { - int exceptionResult; - var result = NetCoreInvokeJS(str, out exceptionResult); + [JSImport("globalThis.Uno.UI.Interop.Runtime.InvokeJS")] + internal static partial string InvokeJS(string value); - if (exceptionResult != 0) - { - var errorMessage = $"Error #{exceptionResult} \"{result}\" executing javascript: \"{str}\""; - if (RethrowNativeExceptions) - { - throw new InvalidOperationException(errorMessage); - } - else - { - Console.Error.WriteLine(errorMessage); - } - } - return result; - } + [JSImport("globalThis.MonoSupport.jsCallDispatcher.invokeJSUnmarshalled")] + internal static partial IntPtr InvokeJSUnmarshalled(string functionIdentifier, IntPtr arg0, IntPtr arg1, IntPtr arg2); } namespace JSInterop { internal static class InternalCalls { - // Matches this signature: - // https://github.com/mono/mono/blob/f24d652d567c4611f9b4e3095be4e2a1a2ab23a4/sdks/wasm/driver.c#L21 - [MethodImpl(MethodImplOptions.InternalCall)] - [EditorBrowsable(EditorBrowsableState.Never)] - public static extern IntPtr InvokeJSUnmarshalled(out string exceptionMessage, string functionIdentifier, IntPtr arg0, IntPtr arg1, IntPtr arg2); - // Uno-Specific implementation for https://github.com/dotnet/runtime/issues/69409. // To be removed when the runtime will support the main SynchronizationContext. [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/Uno.Foundation/FoundationFeatureConfiguration.cs b/src/Uno.Foundation/FoundationFeatureConfiguration.cs index b1b433ca7f48..5ea990c914e9 100644 --- a/src/Uno.Foundation/FoundationFeatureConfiguration.cs +++ b/src/Uno.Foundation/FoundationFeatureConfiguration.cs @@ -38,8 +38,9 @@ public static class Runtime /// public static bool RethrowNativeExceptions { - get => WebAssembly.Runtime.RethrowNativeExceptions; - set => WebAssembly.Runtime.RethrowNativeExceptions = value; + // Obsolete, remove in next major + get => true; + set { } } } #endif diff --git a/src/Uno.UI/ts/Interop/Runtime.ts b/src/Uno.UI/ts/Interop/Runtime.ts index 2d269098047e..8babfa74e0d4 100644 --- a/src/Uno.UI/ts/Interop/Runtime.ts +++ b/src/Uno.UI/ts/Interop/Runtime.ts @@ -5,5 +5,9 @@ private static init(): any { return ""; } + + public static InvokeJS(command: string) : string { + return eval(command); + } } -} \ No newline at end of file +} diff --git a/src/Uno.UI/ts/MonoSupport.ts b/src/Uno.UI/ts/MonoSupport.ts index faa7ad6c07bd..949427808fae 100644 --- a/src/Uno.UI/ts/MonoSupport.ts +++ b/src/Uno.UI/ts/MonoSupport.ts @@ -22,6 +22,23 @@ namespace MonoSupport { jsCallDispatcher.registrations.set(identifier, instance); } + public static invokeJSUnmarshalled(funcName: string, arg0: any, arg1: any, arg2: any): void | number { + const funcInstance = jsCallDispatcher.findJSFunction(funcName); + + let ret = funcInstance.call(null, arg0, arg1, arg2); + + switch (typeof ret) { + case "boolean": + return ret ? 1 : 0; + case "undefined": + return 0; + case "number": + return ret; + default: + throw new Error(`Function ${funcName} returned an unsupported type: ${typeof ret}`); + } + } + public static findJSFunction(identifier: string): any { if (!identifier) {