Skip to content

Commit

Permalink
Merge pull request #18120 from unoplatform/dev/jela/jsinvoke-adjust
Browse files Browse the repository at this point in the history
feat(wasm): Remove dependency on js invocation internal calls
  • Loading branch information
jeromelaban committed Sep 6, 2024
2 parents 57cd135 + 70a016a commit d627ae8
Show file tree
Hide file tree
Showing 51 changed files with 157 additions and 2,215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,8 @@ private static void GenerateUnmarshaler(INamedTypeSymbol parametersType, Indente

if (isElementString)
{
using (sb.BlockInvariant("if(value !== 0)"))
{
sb.AppendLineIndented($"ret.{field.Name}.push({elementTSType}(MonoRuntime.conv_string(value)));");
}
sb.AppendLineIndented("else");
using (sb.BlockInvariant(""))
{
sb.AppendLineIndented($"ret.{field.Name}.push(null);");
}
// array string conversion has been removed from net9
throw new NotSupportedException("String is not supported anymore");
}
else
{
Expand Down
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
@@ -1,61 +1,31 @@
using System;
#nullable enable

using System;
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
66 changes: 0 additions & 66 deletions src/Uno.UI.Wasm.Tests/Tests/TSBindingsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,62 +136,6 @@ public void When_NullArrayOfInt()

Assert.AreEqual("true", ret.Value);
}

[TestMethod]
public void When_ArrayOfStrings()
{
var param = new When_ArrayOfStringsParams()
{
MyArray_Length = 4,
MyArray = new[] { "1", "2", "3", "42" }
};

var ret = (GenericReturn)TSInteropMarshaller.InvokeJS("TSBindingsUnitTests:When_ArrayOfStrings", param, typeof(GenericReturn));

Assert.AreEqual("1;2;3;42", ret.Value);
}

[TestMethod]
public void When_ArrayOfUnicodeStrings()
{
var param = new When_ArrayOfStringsParams()
{
MyArray_Length = 1,
MyArray = new[] { "🎉🤣😊👆🎁" }
};

var ret = (GenericReturn)TSInteropMarshaller.InvokeJS("TSBindingsUnitTests:When_ArrayOfUnicodeStrings", param, typeof(GenericReturn));

Assert.AreEqual(param.MyArray[0], ret.Value);
}

[TestMethod]
public void When_NullArrayOfStrings()
{
var param = new When_ArrayOfStringsParams()
{
MyArray_Length = 0,
MyArray = null
};

var ret = (GenericReturn)TSInteropMarshaller.InvokeJS("TSBindingsUnitTests:When_NullArrayOfStrings", param, typeof(GenericReturn));

Assert.AreEqual("true", ret.Value);
}

[TestMethod]
public void When_ArrayOfNullStrings()
{
var param = new When_ArrayOfStringsParams()
{
MyArray_Length = 4,
MyArray = new string[4]
};

var ret = (GenericReturn)TSInteropMarshaller.InvokeJS("TSBindingsUnitTests:When_ArrayOfNullStrings", param, typeof(GenericReturn));

Assert.AreEqual("true;true;true;true", ret.Value);
}
}

partial class TestImport
Expand All @@ -200,16 +144,6 @@ partial class TestImport
internal static partial string When_SingleStringNet7(string value);
}

[TSInteropMessage]
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct When_ArrayOfStringsParams
{
public int MyArray_Length;

[MarshalAs(UnmanagedType.LPArray, ArraySubType = TSInteropMarshaller.LPUTF8Str)]
public string[] MyArray;
}

[TSInteropMessage]
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct When_ArrayOfIntParams
Expand Down
Loading

0 comments on commit d627ae8

Please sign in to comment.