Skip to content

Commit

Permalink
feat(wasm): Remove dependency on js invocation internal calls
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Sep 5, 2024
1 parent 05b4e32 commit c9f9377
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 72 deletions.
40 changes: 9 additions & 31 deletions src/Uno.Foundation.Runtime.WebAssembly/Interop/Runtime.wasm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

/// <summary>
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary>
/// Mono specific internal call.
/// </summary>
[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);

/// <summary>
/// Invokes Javascript code in the hosting environment
/// </summary>
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)]
Expand Down
5 changes: 3 additions & 2 deletions src/Uno.Foundation/FoundationFeatureConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ public static class Runtime
/// </summary>
public static bool RethrowNativeExceptions
{
get => WebAssembly.Runtime.RethrowNativeExceptions;
set => WebAssembly.Runtime.RethrowNativeExceptions = value;
// Obsolete, remove in next major
get => true;
set { }
}
}
#endif
Expand Down
6 changes: 5 additions & 1 deletion src/Uno.UI/ts/Interop/Runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
private static init(): any {
return "";
}

public static InvokeJS(command: string) : string {
return eval(command);
}
}
}
}
17 changes: 17 additions & 0 deletions src/Uno.UI/ts/MonoSupport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit c9f9377

Please sign in to comment.