diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 1cd0730d41f53..e083c09a41f6f 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -45,7 +45,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
}
catch (Exception ex)
{
- Environment.FailFast("CallEntrypoint: Unexpected synchronous failure. " + ex);
+ Environment.FailFast($"CallEntrypoint: Unexpected synchronous failure (ManagedThreadId {Environment.CurrentManagedThreadId}): " + ex);
}
}
@@ -110,7 +110,7 @@ public static void ReleaseJSOwnedObjectByGCHandle(JSMarshalerArgument* arguments
}
catch (Exception ex)
{
- Environment.FailFast("ReleaseJSOwnedObjectByGCHandle: Unexpected synchronous failure. " + ex);
+ Environment.FailFast($"ReleaseJSOwnedObjectByGCHandle: Unexpected synchronous failure (ManagedThreadId {Environment.CurrentManagedThreadId}): " + ex);
}
}
@@ -205,7 +205,7 @@ public static void CompleteTask(JSMarshalerArgument* arguments_buffer)
}
catch (Exception ex)
{
- Environment.FailFast("CompleteTask: Unexpected synchronous failure. " + ex);
+ Environment.FailFast($"CompleteTask: Unexpected synchronous failure (ManagedThreadId {Environment.CurrentManagedThreadId}): " + ex);
}
}
@@ -280,7 +280,7 @@ public static void BindAssemblyExports(JSMarshalerArgument* arguments_buffer)
}
catch (Exception ex)
{
- Environment.FailFast("BindAssemblyExports: Unexpected synchronous failure. " + ex);
+ Environment.FailFast($"BindAssemblyExports: Unexpected synchronous failure (ManagedThreadId {Environment.CurrentManagedThreadId}): " + ex);
}
}
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 666f2caeb5a4a..974b0ce7e3eb7 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
@@ -151,7 +151,9 @@ internal unsafe JSBindingType this[int position]
///
/// Generated metadata about the method signature used for marshaling.
/// The intermediate buffer with marshalled arguments.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static void InvokeJS(JSFunctionBinding signature, Span arguments)
{
InvokeJSImportImpl(signature, arguments);
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHost.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHost.cs
index 0a685e996882d..20570bbab0fff 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHost.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHost.cs
@@ -44,7 +44,9 @@ public static JSObject DotnetInstance
/// The location of the module file.
/// The token to monitor for cancellation requests.
/// A proxy for the JavaScript object that contains the module's exports.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static Task ImportAsync(string moduleName, string moduleUrl, CancellationToken cancellationToken = default)
{
return JSHostImplementation.ImportAsync(moduleName, moduleUrl, cancellationToken);
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
index 736f2de5a134d..232613b132841 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs
@@ -64,7 +64,9 @@ public static MethodInfo GetTaskResultMethodInfo(Type taskType)
throw new InvalidOperationException();
}
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static void ThrowException(ref JSMarshalerArgument arg)
{
arg.ToManaged(out Exception? ex);
@@ -85,7 +87,9 @@ public static async Task ImportAsync(string moduleName, string moduleU
ConfigureAwaitOptions.ForceYielding); // this helps to finish the import before we bind the module in [JSImport]
}
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static async Task CancellationHelper(Task jsTask, CancellationToken cancellationToken)
{
if (jsTask.IsCompletedSuccessfully)
@@ -293,6 +297,7 @@ public static unsafe JSFunctionBinding BindManagedFunction(string fullyQualified
var signature = GetMethodSignature(signatures, null, null);
+ // this will hit JS side possibly on another thread, depending on JSProxyContext.CurrentThreadContext
JavaScriptImports.BindCSFunction(monoMethod, assemblyName, nameSpace, shortClassName, methodName, signatureHash, (IntPtr)signature.Header);
FreeMethodSignatureBuffer(signature);
@@ -310,7 +315,9 @@ public static void SetHasExternalEventLoop(Thread thread)
}
#endif
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static RuntimeMethodHandle GetMethodHandleFromIntPtr(IntPtr ptr)
{
var temp = new IntPtrAndHandle { ptr = ptr };
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSMarshalerArgument.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSMarshalerArgument.cs
index cdb4b0bc62775..9402aa5e8b80e 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSMarshalerArgument.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSMarshalerArgument.cs
@@ -71,7 +71,9 @@ internal struct JSMarshalerArgumentImpl
///
/// This API supports JSImport infrastructure and is not intended to be used directly from your code.
///
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void Initialize()
{
slot.Type = MarshalerType.None;
@@ -85,7 +87,9 @@ public unsafe void Initialize()
}
#if FEATURE_WASM_MANAGED_THREADS
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
internal unsafe void InitializeWithContext(JSProxyContext knownProxyContext)
{
slot.Type = MarshalerType.None;
@@ -111,11 +115,11 @@ internal JSProxyContext ToManagedContext
// during JSExport, this is marshaling parameters and it would be set by:
// - alloc_stack_frame
// - set_js_handle/set_gc_handle
- var proxyContextGCHandle = (GCHandle)slot.ContextHandle;
- if (proxyContextGCHandle == default)
+ if (slot.ContextHandle == IntPtr.Zero)
{
- Environment.FailFast($"ContextHandle not set, ManagedThreadId: {Environment.CurrentManagedThreadId}. {Environment.NewLine} {Environment.StackTrace}");
+ Environment.FailFast($"ContextHandle not set (ManagedThreadId {Environment.CurrentManagedThreadId}): {Environment.NewLine} {Environment.StackTrace}");
}
+ var proxyContextGCHandle = (GCHandle)slot.ContextHandle;
var argumentContext = (JSProxyContext)proxyContextGCHandle.Target!;
return argumentContext;
#endif
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 35424deea557b..48c6cbc32862c 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
@@ -42,7 +42,9 @@ internal JSObject(IntPtr jsHandle, JSProxyContext ctx)
///
public override string ToString() => $"(js-obj js '{JSHandle}')";
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
internal void AssertNotDisposed()
{
lock (ProxyContext)
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 e03f924de110c..7a86f173d11e1 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
@@ -41,7 +41,9 @@ private JSProxyContext()
public bool IsMainThread;
public JSSynchronizationContext SynchronizationContext;
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public bool IsCurrentThread()
{
return ManagedTID == Environment.CurrentManagedThreadId;
@@ -232,7 +234,9 @@ public static JSProxyContext CurrentOperationContext
#endif
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public static JSProxyContext AssertIsInteropThread()
{
#if FEATURE_WASM_MANAGED_THREADS
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.BigInt64.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.BigInt64.cs
index a2bce80d13b89..87eaa76966039 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.BigInt64.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.BigInt64.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManagedBig(out long value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManagedBig(out long value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJSBig(long value)
{
slot.Type = MarshalerType.BigInt64;
@@ -40,7 +44,9 @@ public void ToJSBig(long value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManagedBig(out long? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManagedBig(out long? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJSBig(long? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Bool.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Bool.cs
index 375e4b97f4a5a..51ae3b6aed043 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Bool.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Bool.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out bool value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out bool value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(bool value)
{
slot.Type = MarshalerType.Boolean;
@@ -40,7 +44,9 @@ public void ToJS(bool value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out bool? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out bool? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(bool? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Byte.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Byte.cs
index 5392fca48fae8..113d4f1a06908 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Byte.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Byte.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out byte value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out byte value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(byte value)
{
slot.Type = MarshalerType.Byte;
@@ -40,7 +44,9 @@ public void ToJS(byte value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out byte? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out byte? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(byte? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Char.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Char.cs
index 7daddfb0fd444..d31a8d3cd35c8 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Char.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Char.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out char value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out char value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(char value)
{
slot.Type = MarshalerType.Char;
@@ -40,7 +44,9 @@ public void ToJS(char value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out char? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out char? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(char? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.DateTime.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.DateTime.cs
index 6521ac0c54b9a..7f63e5034c3b8 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.DateTime.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.DateTime.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out DateTimeOffset value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out DateTimeOffset value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(DateTimeOffset value)
{
slot.Type = MarshalerType.DateTimeOffset;
@@ -40,7 +44,9 @@ public void ToJS(DateTimeOffset value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out DateTimeOffset? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out DateTimeOffset? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(DateTimeOffset? value)
{
if (value.HasValue)
@@ -75,7 +83,9 @@ public void ToJS(DateTimeOffset? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out DateTime value)
{
if (slot.Type == MarshalerType.None)
@@ -91,7 +101,9 @@ public unsafe void ToManaged(out DateTime value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(DateTime value)
{
slot.Type = MarshalerType.DateTime;
@@ -103,7 +115,9 @@ public void ToJS(DateTime value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out DateTime? value)
{
if (slot.Type == MarshalerType.None)
@@ -119,7 +133,9 @@ public unsafe void ToManaged(out DateTime? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(DateTime? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Double.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Double.cs
index 9b7f48ed4b3ac..c83930bda8254 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Double.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Double.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out double value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out double value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(double value)
{
slot.Type = MarshalerType.Double;
@@ -40,7 +44,9 @@ public void ToJS(double value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out double? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out double? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(double? value)
{
if (value.HasValue)
@@ -75,7 +83,9 @@ public void ToJS(double? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out double[]? value)
{
if (slot.Type == MarshalerType.None)
@@ -93,7 +103,9 @@ public unsafe void ToManaged(out double[]? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(double[] value)
{
if (value == null)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Exception.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Exception.cs
index e526fe4b52c89..86a57b48b345a 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Exception.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Exception.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out Exception? value)
{
if (slot.Type == MarshalerType.None)
@@ -48,7 +50,9 @@ public unsafe void ToManaged(out Exception? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(Exception? value)
{
if (value == null)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int16.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int16.cs
index 6a2fec5e0f2fa..54ef3ee53c242 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int16.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int16.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out short value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out short value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(short value)
{
slot.Type = MarshalerType.Int16;
@@ -40,7 +44,9 @@ public void ToJS(short value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out short? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out short? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(short? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int32.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int32.cs
index 501484af3ab4f..a6990113c8ff4 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int32.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int32.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out int value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out int value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(int value)
{
slot.Type = MarshalerType.Int32;
@@ -40,7 +44,9 @@ public void ToJS(int value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out int? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out int? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(int? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int52.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int52.cs
index 4893f32f5f20b..6b639ae77ef87 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int52.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Int52.cs
@@ -15,7 +15,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out long value)
{
if (slot.Type == MarshalerType.None)
@@ -31,7 +33,9 @@ public unsafe void ToManaged(out long value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(long value)
{
if (value < I52_MIN_VALUE || value > I52_MAX_VALUE)
@@ -48,7 +52,9 @@ public void ToJS(long value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out long? value)
{
if (slot.Type == MarshalerType.None)
@@ -64,7 +70,9 @@ public unsafe void ToManaged(out long? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(long? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.IntPtr.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.IntPtr.cs
index 251db16215122..2737005542df4 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.IntPtr.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.IntPtr.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out IntPtr value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out IntPtr value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(IntPtr value)
{
slot.Type = MarshalerType.IntPtr;
@@ -40,7 +44,9 @@ public void ToJS(IntPtr value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out IntPtr? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out IntPtr? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(IntPtr? value)
{
if (value.HasValue)
@@ -75,7 +83,9 @@ public void ToJS(IntPtr? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out void* value)
{
if (slot.Type == MarshalerType.None)
@@ -91,7 +101,9 @@ public unsafe void ToManaged(out void* value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(void* value)
{
slot.Type = MarshalerType.IntPtr;
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.JSObject.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.JSObject.cs
index 7eb4440c565d6..bdaf228f6a720 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.JSObject.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.JSObject.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out JSObject? value)
{
if (slot.Type == MarshalerType.None)
@@ -29,7 +31,9 @@ public unsafe void ToManaged(out JSObject? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(JSObject? value)
{
if (value == null)
@@ -64,7 +68,9 @@ public void ToJS(JSObject? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out JSObject?[]? value)
{
if (slot.Type == MarshalerType.None)
@@ -90,7 +96,9 @@ public unsafe void ToManaged(out JSObject?[]? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(JSObject?[] value)
{
if (value == null)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Object.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Object.cs
index 3ce627aeff21c..8a5105cbce828 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Object.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Object.cs
@@ -18,7 +18,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out object? value)
{
if (slot.Type == MarshalerType.None)
@@ -110,7 +112,9 @@ public unsafe void ToManaged(out object? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(object? value)
{
if (value == null)
@@ -327,7 +331,9 @@ public void ToJS(object? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out object?[]? value)
{
if (slot.Type == MarshalerType.None)
@@ -356,7 +362,9 @@ public unsafe void ToManaged(out object?[]? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(object?[] value)
{
if (value == null)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Single.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Single.cs
index c22d26c86520a..696cc9a60089b 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Single.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Single.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out float value)
{
if (slot.Type == MarshalerType.None)
@@ -28,7 +30,9 @@ public unsafe void ToManaged(out float value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(float value)
{
slot.Type = MarshalerType.Single;
@@ -40,7 +44,9 @@ public void ToJS(float value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out float? value)
{
if (slot.Type == MarshalerType.None)
@@ -56,7 +62,9 @@ public unsafe void ToManaged(out float? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public void ToJS(float? value)
{
if (value.HasValue)
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.String.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.String.cs
index efe764cd837fb..247aad1ec613a 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.String.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.String.cs
@@ -12,7 +12,9 @@ public partial struct JSMarshalerArgument
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out string? value)
{
if (slot.Type == MarshalerType.None)
@@ -36,7 +38,9 @@ public unsafe void ToManaged(out string? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(string? value)
{
if (value == null)
@@ -69,7 +73,9 @@ public unsafe void ToJS(string? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToManaged(out string?[]? value)
{
if (slot.Type == MarshalerType.None)
@@ -98,7 +104,9 @@ public unsafe void ToManaged(out string?[]? value)
/// It's used by JSImport code generator and should not be used by developers in source code.
///
/// The value to be marshaled.
+#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
+#endif
public unsafe void ToJS(string?[] value)
{
if (value == null)
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 c3881268f2a6c..ef19eaa15fc20 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
@@ -20,17 +20,17 @@
false
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
@@ -41,19 +41,19 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/src/mono/browser/runtime/corebindings.c b/src/mono/browser/runtime/corebindings.c
index 7329fb4bcd192..abaa7cab7b6f6 100644
--- a/src/mono/browser/runtime/corebindings.c
+++ b/src/mono/browser/runtime/corebindings.c
@@ -253,31 +253,37 @@ void mono_wasm_get_assembly_export (char *assembly_name, char *namespace, char *
#ifndef DISABLE_THREADS
+// async
void mono_wasm_release_cs_owned_object_post (pthread_t target_tid, int js_handle)
{
mono_threads_wasm_async_run_in_target_thread_vi (target_tid, (void (*) (gpointer))mono_wasm_release_cs_owned_object, (gpointer)js_handle);
}
+// async
void mono_wasm_resolve_or_reject_promise_post (pthread_t target_tid, void* args)
{
mono_threads_wasm_async_run_in_target_thread_vi (target_tid, (void (*) (gpointer))mono_wasm_resolve_or_reject_promise, (gpointer)args);
}
+// async
void mono_wasm_cancel_promise_post (pthread_t target_tid, int task_holder_gc_handle)
{
mono_threads_wasm_async_run_in_target_thread_vi (target_tid, (void (*) (gpointer))mono_wasm_cancel_promise, (gpointer)task_holder_gc_handle);
}
+// async
void mono_wasm_invoke_jsimport_async_post (pthread_t target_tid, void* signature, void* args)
{
mono_threads_wasm_async_run_in_target_thread_vii (target_tid, (void (*) (gpointer, gpointer))mono_wasm_invoke_jsimport, (gpointer)signature, (gpointer)args);
}
+// sync
void mono_wasm_invoke_jsimport_sync_send (pthread_t target_tid, void* signature, void* args)
{
mono_threads_wasm_sync_run_in_target_thread_vii (target_tid, (void (*) (gpointer, gpointer))mono_wasm_invoke_jsimport, (gpointer)signature, (gpointer)args);
}
+// sync
void mono_wasm_invoke_js_function_send (pthread_t target_tid, int function_js_handle, void *args)
{
mono_threads_wasm_sync_run_in_target_thread_vii (target_tid, (void (*) (gpointer, gpointer))mono_wasm_invoke_js_function, (gpointer)function_js_handle, (gpointer)args);
diff --git a/src/mono/browser/runtime/invoke-cs.ts b/src/mono/browser/runtime/invoke-cs.ts
index 287ee5ca6f681..f8aa906ce2df5 100644
--- a/src/mono/browser/runtime/invoke-cs.ts
+++ b/src/mono/browser/runtime/invoke-cs.ts
@@ -100,7 +100,9 @@ export function mono_wasm_bind_cs_function(method: MonoMethod, assemblyName: str
// in Release configuration, it would be a trimmed by rollup
if (BuildConfiguration === "Debug" && !runtimeHelpers.cspPolicy) {
try {
- bound_fn = new Function("fn", "return (function JSExport_" + methodName + "(){ return fn.apply(this, arguments)});")(bound_fn);
+ const url = `//# sourceURL=https://dotnet/JSExport/${methodName}`;
+ const body = `return (function JSExport_${methodName}(){ return fn.apply(this, arguments)});`;
+ bound_fn = new Function("fn", url + "\r\n" + body)(bound_fn);
}
catch (ex) {
runtimeHelpers.cspPolicy = true;
@@ -123,7 +125,8 @@ function bind_fn_0V(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(2);
+ const size = 2;
+ const args = alloc_stack_frame(size);
// call C# side
invoke_sync_jsexport(method, args);
} finally {
@@ -144,7 +147,8 @@ function bind_fn_1V(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
marshaler1(args, arg1);
// call C# side
@@ -168,7 +172,8 @@ function bind_fn_1R(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
marshaler1(args, arg1);
// call C# side
@@ -195,14 +200,15 @@ function bind_fn_1RA(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
marshaler1(args, arg1);
// pre-allocate the promise
let promise = res_converter(args);
// call C# side
- invoke_async_jsexport(method, args, 3);
+ invoke_async_jsexport(method, args, size);
// in case the C# side returned synchronously
promise = end_marshal_task_to_js(args, undefined, promise);
@@ -228,7 +234,8 @@ function bind_fn_2R(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(4);
+ const size = 4;
+ const args = alloc_stack_frame(size);
marshaler1(args, arg1);
marshaler2(args, arg2);
@@ -257,7 +264,8 @@ function bind_fn_2RA(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(4);
+ const size = 4;
+ const args = alloc_stack_frame(size);
marshaler1(args, arg1);
marshaler2(args, arg2);
@@ -265,7 +273,7 @@ function bind_fn_2RA(closure: BindingClosure) {
let promise = res_converter(args);
// call C# side
- invoke_async_jsexport(method, args, 4);
+ invoke_async_jsexport(method, args, size);
// in case the C# side returned synchronously
promise = end_marshal_task_to_js(args, undefined, promise);
@@ -293,7 +301,8 @@ function bind_fn(closure: BindingClosure) {
mono_assert(!WasmEnableThreads || !closure.isDisposed, "The function was already disposed");
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(2 + args_count);
+ const size = 2 + args_count;
+ const args = alloc_stack_frame(size);
for (let index = 0; index < args_count; index++) {
const marshaler = arg_marshalers[index];
if (marshaler) {
@@ -309,13 +318,13 @@ function bind_fn(closure: BindingClosure) {
// call C# side
if (is_async) {
- invoke_async_jsexport(method, args, 2 + args_count);
+ invoke_async_jsexport(method, args, size);
// in case the C# side returned synchronously
js_result = end_marshal_task_to_js(args, undefined, js_result);
}
else if (is_discard_no_wait) {
// call C# side, fire and forget
- invoke_async_jsexport(method, args, 2 + args_count);
+ invoke_async_jsexport(method, args, size);
}
else {
invoke_sync_jsexport(method, args);
diff --git a/src/mono/browser/runtime/invoke-js.ts b/src/mono/browser/runtime/invoke-js.ts
index 75d7c96b9c737..d4c0459a0f1a3 100644
--- a/src/mono/browser/runtime/invoke-js.ts
+++ b/src/mono/browser/runtime/invoke-js.ts
@@ -132,31 +132,16 @@ function bind_js_import(signature: JSFunctionSignature): Function {
}
}
- // this is just to make debugging easier by naming the function in the stack trace.
- // It's not CSP compliant and possibly not performant, that's why it's only enabled in debug builds
- // in Release configuration, it would be a trimmed by rollup
- if (BuildConfiguration === "Debug" && !runtimeHelpers.cspPolicy) {
- try {
- bound_fn = new Function("fn", "return (function JSImport_" + js_function_name.replaceAll(".", "_") + "(){ return fn.apply(this, arguments)});")(bound_fn);
- }
- catch (ex) {
- runtimeHelpers.cspPolicy = true;
- }
- }
-
function async_bound_fn(args: JSMarshalerArguments): void {
- if (WasmEnableThreads) {
- forceThreadMemoryViewRefresh();
- }
+ forceThreadMemoryViewRefresh();
bound_fn(args);
}
+
function sync_bound_fn(args: JSMarshalerArguments): void {
const previous = runtimeHelpers.isPendingSynchronousCall;
try {
+ forceThreadMemoryViewRefresh();
runtimeHelpers.isPendingSynchronousCall = true;
- if (WasmEnableThreads) {
- forceThreadMemoryViewRefresh();
- }
bound_fn(args);
}
finally {
@@ -164,12 +149,29 @@ function bind_js_import(signature: JSFunctionSignature): Function {
}
}
- let wrapped_fn: WrappedJSFunction;
- if (is_async || is_discard_no_wait) {
- wrapped_fn = async_bound_fn;
+ let wrapped_fn: WrappedJSFunction = bound_fn;
+ if (WasmEnableThreads) {
+ if (is_async || is_discard_no_wait) {
+ wrapped_fn = async_bound_fn;
+ }
+ else {
+ wrapped_fn = sync_bound_fn;
+ }
}
- else {
- wrapped_fn = sync_bound_fn;
+
+ // this is just to make debugging easier by naming the function in the stack trace.
+ // It's not CSP compliant and possibly not performant, that's why it's only enabled in debug builds
+ // in Release configuration, it would be a trimmed by rollup
+ if (BuildConfiguration === "Debug" && !runtimeHelpers.cspPolicy) {
+ try {
+ const fname = js_function_name.replaceAll(".", "_");
+ const url = `//# sourceURL=https://dotnet/JSImport/${fname}`;
+ const body = `return (function JSImport_${fname}(){ return fn.apply(this, arguments)});`;
+ wrapped_fn = new Function("fn", url + "\r\n" + body)(wrapped_fn);
+ }
+ catch (ex) {
+ runtimeHelpers.cspPolicy = true;
+ }
}
(wrapped_fn)[imported_js_function_symbol] = closure;
diff --git a/src/mono/browser/runtime/loader/assets.ts b/src/mono/browser/runtime/loader/assets.ts
index 49d2f0f8ac6d8..2416f931b52f1 100644
--- a/src/mono/browser/runtime/loader/assets.ts
+++ b/src/mono/browser/runtime/loader/assets.ts
@@ -737,7 +737,6 @@ export async function streamingCompileWasm() {
loaderHelpers.wasmCompilePromise.promise_control.reject(err);
}
}
-
export function preloadWorkers() {
if (!WasmEnableThreads) return;
const jsModuleWorker = resolve_single_asset_path("js-module-threads");
diff --git a/src/mono/browser/runtime/loader/exit.ts b/src/mono/browser/runtime/loader/exit.ts
index 7f62ef7b56066..057197f87d452 100644
--- a/src/mono/browser/runtime/loader/exit.ts
+++ b/src/mono/browser/runtime/loader/exit.ts
@@ -22,7 +22,12 @@ export function assert_runtime_running() {
mono_assert(runtimeHelpers.runtimeReady, ".NET runtime didn't start yet. Please call dotnet.create() first.");
}
} else {
- mono_assert(!loaderHelpers.assertAfterExit, () => `.NET runtime already exited with ${loaderHelpers.exitCode} ${loaderHelpers.exitReason}. You can use runtime.runMain() which doesn't exit the runtime.`);
+ const message = `.NET runtime already exited with ${loaderHelpers.exitCode} ${loaderHelpers.exitReason}. You can use runtime.runMain() which doesn't exit the runtime.`;
+ if (loaderHelpers.assertAfterExit) {
+ mono_assert(false, message);
+ } else {
+ mono_log_warn(message);
+ }
}
}
diff --git a/src/mono/browser/runtime/managed-exports.ts b/src/mono/browser/runtime/managed-exports.ts
index c8aabae88e37b..62fee7656e282 100644
--- a/src/mono/browser/runtime/managed-exports.ts
+++ b/src/mono/browser/runtime/managed-exports.ts
@@ -9,7 +9,7 @@ import { runtimeHelpers, Module, loaderHelpers, mono_assert } from "./globals";
import { JavaScriptMarshalerArgSize, alloc_stack_frame, get_arg, get_arg_gc_handle, is_args_exception, set_arg_intptr, set_arg_type, set_gc_handle } from "./marshal";
import { marshal_array_to_cs, marshal_array_to_cs_impl, marshal_bool_to_cs, marshal_exception_to_cs, marshal_intptr_to_cs, marshal_string_to_cs } from "./marshal-to-cs";
import { marshal_int32_to_js, end_marshal_task_to_js, marshal_string_to_js, begin_marshal_task_to_js, marshal_exception_to_js } from "./marshal-to-js";
-import { do_not_force_dispose } from "./gc-handles";
+import { do_not_force_dispose, is_gcv_handle } from "./gc-handles";
import { assert_c_interop, assert_js_interop } from "./invoke-js";
import { mono_wasm_main_thread_ptr } from "./pthreads";
import { _zero_region } from "./memory";
@@ -47,7 +47,8 @@ export function call_entry_point(main_assembly_name: string, program_args: strin
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(5);
+ const size = 5;
+ const args = alloc_stack_frame(size);
const res = get_arg(args, 1);
const arg1 = get_arg(args, 2);
const arg2 = get_arg(args, 3);
@@ -60,7 +61,7 @@ export function call_entry_point(main_assembly_name: string, program_args: strin
// because this is async, we could pre-allocate the promise
let promise = begin_marshal_task_to_js(res, MarshalerType.TaskPreCreated, marshal_int32_to_js);
- invoke_async_jsexport(managedExports.CallEntrypoint, args, 5);
+ invoke_async_jsexport(managedExports.CallEntrypoint, args, size);
// in case the C# side returned synchronously
promise = end_marshal_task_to_js(args, marshal_int32_to_js, promise);
@@ -80,7 +81,8 @@ export function call_entry_point(main_assembly_name: string, program_args: strin
export function load_satellite_assembly(dll: Uint8Array): void {
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
const arg1 = get_arg(args, 2);
set_arg_type(arg1, MarshalerType.Array);
marshal_array_to_cs(arg1, dll, MarshalerType.Byte);
@@ -94,7 +96,8 @@ export function load_satellite_assembly(dll: Uint8Array): void {
export function load_lazy_assembly(dll: Uint8Array, pdb: Uint8Array | null): void {
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(4);
+ const size = 4;
+ const args = alloc_stack_frame(size);
const arg1 = get_arg(args, 2);
const arg2 = get_arg(args, 3);
set_arg_type(arg1, MarshalerType.Array);
@@ -113,12 +116,17 @@ export function release_js_owned_object_by_gc_handle(gc_handle: GCHandle) {
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
const arg1 = get_arg(args, 2);
set_arg_type(arg1, MarshalerType.Object);
set_gc_handle(arg1, gc_handle);
- // this must stay synchronous for free_gcv_handle sake
- invoke_sync_jsexport(managedExports.ReleaseJSOwnedObjectByGCHandle, args);
+ if (is_gcv_handle(gc_handle)) {
+ // this must stay synchronous for free_gcv_handle sake
+ invoke_sync_jsexport(managedExports.ReleaseJSOwnedObjectByGCHandle, args);
+ } else {
+ invoke_async_jsexport(managedExports.ReleaseJSOwnedObjectByGCHandle, args, size);
+ }
} finally {
Module.stackRestore(sp);
}
@@ -129,7 +137,8 @@ export function complete_task(holder_gc_handle: GCHandle, isCanceling: boolean,
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(5);
+ const size = 5;
+ const args = alloc_stack_frame(size);
const res = get_arg(args, 1);
const arg1 = get_arg(args, 2);
set_arg_type(arg1, MarshalerType.Object);
@@ -146,7 +155,7 @@ export function complete_task(holder_gc_handle: GCHandle, isCanceling: boolean,
mono_assert(res_converter, "res_converter missing");
res_converter(arg3, data);
}
- invoke_async_jsexport(managedExports.CompleteTask, args, 4);
+ invoke_async_jsexport(managedExports.CompleteTask, args, size);
} finally {
Module.stackRestore(sp);
}
@@ -157,7 +166,8 @@ export function call_delegate(callback_gc_handle: GCHandle, arg1_js: any, arg2_j
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(6);
+ const size = 6;
+ const args = alloc_stack_frame(size);
const arg1 = get_arg(args, 2);
set_arg_type(arg1, MarshalerType.Object);
@@ -193,7 +203,8 @@ export function get_managed_stack_trace(exception_gc_handle: GCHandle) {
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
const arg1 = get_arg(args, 2);
set_arg_type(arg1, MarshalerType.Exception);
@@ -237,7 +248,7 @@ export function install_main_synchronization_context(): GCHandle {
export function invoke_async_jsexport(method: MonoMethod, args: JSMarshalerArguments, size: number): void {
assert_js_interop();
- if (!WasmEnableThreads || runtimeHelpers.isCurrentThread) {
+ if (!WasmEnableThreads || runtimeHelpers.isManagedRunningOnCurrentThread) {
cwraps.mono_wasm_invoke_jsexport(method, args as any);
if (is_args_exception(args)) {
const exc = get_arg(args, 0);
@@ -257,12 +268,12 @@ export function invoke_async_jsexport(method: MonoMethod, args: JSMarshalerArgum
export function invoke_sync_jsexport(method: MonoMethod, args: JSMarshalerArguments): void {
assert_js_interop();
- if (!WasmEnableThreads || runtimeHelpers.isCurrentThread) {
+ if (!WasmEnableThreads || runtimeHelpers.isManagedRunningOnCurrentThread) {
cwraps.mono_wasm_invoke_jsexport(method, args as any);
} else {
throw new Error("Should be unreachable until we implement deputy.");
/*
- if (!runtimeHelpers.isCurrentThread && runtimeHelpers.isPendingSynchronousCall) {
+ if (!runtimeHelpers.isManagedRunningOnCurrentThread && runtimeHelpers.isPendingSynchronousCall) {
throw new Error("Cannot call synchronous C# method from inside a synchronous call to a JS method.");
}
// this is blocking too
@@ -280,7 +291,8 @@ export function bind_assembly_exports(assemblyName: string): Promise {
loaderHelpers.assert_runtime_running();
const sp = Module.stackSave();
try {
- const args = alloc_stack_frame(3);
+ const size = 3;
+ const args = alloc_stack_frame(size);
const res = get_arg(args, 1);
const arg1 = get_arg(args, 2);
marshal_string_to_cs(arg1, assemblyName);
@@ -288,7 +300,7 @@ export function bind_assembly_exports(assemblyName: string): Promise {
// because this is async, we could pre-allocate the promise
let promise = begin_marshal_task_to_js(res, MarshalerType.TaskPreCreated);
- invoke_async_jsexport(managedExports.BindAssemblyExports, args, 3);
+ invoke_async_jsexport(managedExports.BindAssemblyExports, args, size);
// in case the C# side returned synchronously
promise = end_marshal_task_to_js(args, marshal_int32_to_js, promise);
diff --git a/src/mono/browser/runtime/marshal-to-cs.ts b/src/mono/browser/runtime/marshal-to-cs.ts
index a42eb724a9215..f6ddf436d2165 100644
--- a/src/mono/browser/runtime/marshal-to-cs.ts
+++ b/src/mono/browser/runtime/marshal-to-cs.ts
@@ -11,11 +11,11 @@ import { alloc_gcv_handle, assert_not_disposed, cs_owned_js_handle_symbol, js_ow
import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
import {
ManagedError,
- set_gc_handle, set_js_handle, set_arg_type, set_arg_i32, set_arg_f64, set_arg_i52, set_arg_f32, set_arg_i16, set_arg_u8, set_arg_b8, set_arg_date,
+ set_gc_handle, set_js_handle, set_arg_type, set_arg_i32, set_arg_f64, set_arg_i52, set_arg_f32, set_arg_i16, set_arg_u8, set_arg_bool, set_arg_date,
set_arg_length, get_arg, get_signature_arg1_type, get_signature_arg2_type, js_to_cs_marshalers,
get_signature_res_type, bound_js_function_symbol, set_arg_u16, array_element_size,
get_string_root, Span, ArraySegment, MemoryViewType, get_signature_arg3_type, set_arg_i64_big, set_arg_intptr,
- set_arg_element_type, ManagedObject, JavaScriptMarshalerArgSize, proxy_debug_symbol, get_arg_gc_handle, get_arg_type
+ set_arg_element_type, ManagedObject, JavaScriptMarshalerArgSize, proxy_debug_symbol, get_arg_gc_handle, get_arg_type, set_arg_proxy_context
} from "./marshal";
import { get_marshaler_to_js_by_type } from "./marshal-to-js";
import { _zero_region, forceThreadMemoryViewRefresh, localHeapViewF64, localHeapViewI32, localHeapViewU8 } from "./memory";
@@ -105,7 +105,7 @@ export function marshal_bool_to_cs(arg: JSMarshalerArgument, value: any): void {
}
else {
set_arg_type(arg, MarshalerType.Boolean);
- set_arg_b8(arg, value);
+ set_arg_bool(arg, value);
}
}
@@ -285,7 +285,7 @@ function _marshal_function_to_cs(arg: JSMarshalerArgument, value: Function, _?:
if (arg3_converter) {
arg3_js = arg3_converter(arg3);
}
- runtimeHelpers.isPendingSynchronousCall = true; // this is alway synchronous call for now
+ runtimeHelpers.isPendingSynchronousCall = true; // this is always synchronous call for now
const res_js = value(arg1_js, arg2_js, arg3_js);
if (res_converter) {
res_converter(res, res_js);
@@ -441,6 +441,7 @@ export function marshal_exception_to_cs(arg: JSMarshalerArgument, value: any): v
export function marshal_js_object_to_cs(arg: JSMarshalerArgument, value: any): void {
if (value === undefined || value === null) {
set_arg_type(arg, MarshalerType.None);
+ set_arg_proxy_context(arg);
}
else {
// if value was ManagedObject, it would be double proxied, but the C# signature requires that
@@ -459,6 +460,7 @@ export function marshal_js_object_to_cs(arg: JSMarshalerArgument, value: any): v
function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void {
if (value === undefined || value === null) {
set_arg_type(arg, MarshalerType.None);
+ set_arg_proxy_context(arg);
}
else {
const gc_handle = value[js_owned_gc_handle_symbol];
@@ -478,7 +480,7 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void {
}
else if (js_type === "boolean") {
set_arg_type(arg, MarshalerType.Boolean);
- set_arg_b8(arg, value);
+ set_arg_bool(arg, value);
}
else if (value instanceof Date) {
set_arg_type(arg, MarshalerType.DateTime);
diff --git a/src/mono/browser/runtime/marshal-to-js.ts b/src/mono/browser/runtime/marshal-to-js.ts
index f02c81765e6a4..bee7d560c8890 100644
--- a/src/mono/browser/runtime/marshal-to-js.ts
+++ b/src/mono/browser/runtime/marshal-to-js.ts
@@ -11,7 +11,7 @@ import { Module, loaderHelpers, mono_assert } from "./globals";
import {
ManagedObject, ManagedError,
get_arg_gc_handle, get_arg_js_handle, get_arg_type, get_arg_i32, get_arg_f64, get_arg_i52, get_arg_i16, get_arg_u8, get_arg_f32,
- get_arg_b8, get_arg_date, get_arg_length, get_arg, set_arg_type,
+ get_arg_bool, get_arg_date, get_arg_length, get_arg, set_arg_type,
get_signature_arg2_type, get_signature_arg1_type, cs_to_js_marshalers,
get_signature_res_type, get_arg_u16, array_element_size, get_string_root,
ArraySegment, Span, MemoryViewType, get_signature_arg3_type, get_arg_i64_big, get_arg_intptr, get_arg_element_type, JavaScriptMarshalerArgSize, proxy_debug_symbol, set_js_handle, is_receiver_should_free
@@ -101,7 +101,7 @@ function _marshal_bool_to_js(arg: JSMarshalerArgument): boolean | null {
if (type == MarshalerType.None) {
return null;
}
- return get_arg_b8(arg);
+ return get_arg_bool(arg);
}
function _marshal_byte_to_js(arg: JSMarshalerArgument): number | null {
diff --git a/src/mono/browser/runtime/marshal.ts b/src/mono/browser/runtime/marshal.ts
index c3c07d1c18895..b6f825c4f5738 100644
--- a/src/mono/browser/runtime/marshal.ts
+++ b/src/mono/browser/runtime/marshal.ts
@@ -85,7 +85,7 @@ export function is_args_exception(args: JSMarshalerArguments): boolean {
}
export function is_receiver_should_free(args: JSMarshalerArguments): boolean {
- if (WasmEnableThreads) return false;
+ if (!WasmEnableThreads) return false;
mono_assert(args, "Null args");
return getB32(args + JSMarshalerArgumentOffsets.ReceiverShouldFree);
}
@@ -193,9 +193,9 @@ export function set_arg_element_type(arg: JSMarshalerArgument, type: MarshalerTy
setU8(arg + JSMarshalerArgumentOffsets.ElementType, type);
}
-export function get_arg_b8(arg: JSMarshalerArgument): boolean {
+export function get_arg_bool(arg: JSMarshalerArgument): boolean {
mono_assert(arg, "Null arg");
- return !!getU8(arg);
+ return getB32(arg);
}
export function get_arg_u8(arg: JSMarshalerArgument): number {
@@ -251,10 +251,10 @@ export function get_arg_f64(arg: JSMarshalerArgument): number {
return getF64(arg);
}
-export function set_arg_b8(arg: JSMarshalerArgument, value: boolean): void {
+export function set_arg_bool(arg: JSMarshalerArgument, value: boolean): void {
mono_assert(arg, "Null arg");
mono_check(typeof value === "boolean", () => `Value is not a Boolean: ${value} (${typeof (value)})`);
- setU8(arg, value ? 1 : 0);
+ setB32(arg, value ? 1 : 0);
}
export function set_arg_u8(arg: JSMarshalerArgument, value: number): void {
diff --git a/src/mono/browser/runtime/polyfills.ts b/src/mono/browser/runtime/polyfills.ts
index 0f8700f84754e..26150c797c81e 100644
--- a/src/mono/browser/runtime/polyfills.ts
+++ b/src/mono/browser/runtime/polyfills.ts
@@ -5,7 +5,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads";
import type { EmscriptenReplacements } from "./types/internal";
import type { TypedArray } from "./types/emscripten";
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_WORKER, INTERNAL, Module, loaderHelpers, runtimeHelpers } from "./globals";
-import { replaceEmscriptenPThreadWorker } from "./pthreads";
+import { replaceEmscriptenTLSInit } from "./pthreads";
import { replaceEmscriptenPThreadUI } from "./pthreads";
const dummyPerformance = {
@@ -36,7 +36,7 @@ export function initializeReplacements(replacements: EmscriptenReplacements): vo
// threads
if (WasmEnableThreads && replacements.modulePThread) {
if (ENVIRONMENT_IS_WORKER) {
- replaceEmscriptenPThreadWorker(replacements.modulePThread);
+ replaceEmscriptenTLSInit(replacements.modulePThread);
} else {
replaceEmscriptenPThreadUI(replacements.modulePThread);
}
diff --git a/src/mono/browser/runtime/pthreads/index.ts b/src/mono/browser/runtime/pthreads/index.ts
index a7b5da11e03fb..74d9a4be7561b 100644
--- a/src/mono/browser/runtime/pthreads/index.ts
+++ b/src/mono/browser/runtime/pthreads/index.ts
@@ -14,5 +14,5 @@ export { addUnsettledPromise, settleUnsettledPromise, mono_wasm_eventloop_has_un
export {
mono_wasm_pthread_on_pthread_attached, mono_wasm_pthread_on_pthread_unregistered,
mono_wasm_pthread_on_pthread_registered, mono_wasm_pthread_set_name, currentWorkerThreadEvents,
- dotnetPthreadCreated, initWorkerThreadEvents, replaceEmscriptenPThreadWorker, pthread_self
+ dotnetPthreadCreated, initWorkerThreadEvents, replaceEmscriptenTLSInit, pthread_self
} from "./worker-thread";
diff --git a/src/mono/browser/runtime/pthreads/shared.ts b/src/mono/browser/runtime/pthreads/shared.ts
index 97c41197d35e0..eda95db4c6226 100644
--- a/src/mono/browser/runtime/pthreads/shared.ts
+++ b/src/mono/browser/runtime/pthreads/shared.ts
@@ -39,7 +39,7 @@ export function mono_wasm_install_js_worker_interop(context_gc_handle: GCHandle)
runtimeHelpers.proxyGCHandle = context_gc_handle;
if (ENVIRONMENT_IS_PTHREAD) {
runtimeHelpers.managedThreadTID = mono_wasm_pthread_ptr();
- runtimeHelpers.isCurrentThread = true;
+ runtimeHelpers.isManagedRunningOnCurrentThread = true;
}
Module.runtimeKeepalivePush();
monoThreadInfo.isDirtyBecauseOfInterop = true;
@@ -87,11 +87,16 @@ export function update_thread_info(): void {
set_thread_prefix(monoThreadInfo.threadPrefix!);
}
- (globalThis as any).monoThreadInfo = monoThreadInfo;
+ // this is just to make debugging easier by naming the thread debugger window.
+ // It's not CSP compliant and possibly not performant, that's why it's only enabled in debug builds
+ // in Release configuration, it would be a trimmed by rollup
if (WasmEnableThreads && BuildConfiguration === "Debug" && !runtimeHelpers.cspPolicy) {
monoThreadInfo.updateCount++;
try {
- (globalThis as any).monoThreadInfoFn = new Function(`//# sourceURL=https://${monoThreadInfo.updateCount}WorkerInfo${monoThreadInfo.isAttached ? monoThreadInfo.threadPrefix : ""}/\r\nconsole.log("${JSON.stringify(monoThreadInfo)}");`);
+ const url = `//# sourceURL=https://dotnet/thread/${monoThreadInfo.updateCount}-${monoThreadInfo.threadPrefix}`;
+ const infoJson = JSON.stringify(monoThreadInfo, null, 2);
+ const body = `const monoThreadInfo=${infoJson};\r\nconsole.log(monoThreadInfo);`;
+ (globalThis as any).monoThreadInfoFn = new Function(body + "\r\n" + url);
}
catch (ex) {
runtimeHelpers.cspPolicy = true;
diff --git a/src/mono/browser/runtime/pthreads/ui-thread.ts b/src/mono/browser/runtime/pthreads/ui-thread.ts
index 878ee38eadbb9..d145af3c50a6c 100644
--- a/src/mono/browser/runtime/pthreads/ui-thread.ts
+++ b/src/mono/browser/runtime/pthreads/ui-thread.ts
@@ -5,7 +5,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads";
import BuildConfiguration from "consts:configuration";
import { } from "../globals";
-import { mono_log_warn } from "../logging";
+import { mono_log_debug, mono_log_warn } from "../logging";
import { MonoWorkerToMainMessage, monoThreadInfo, mono_wasm_pthread_ptr, update_thread_info, worker_empty_prefix } from "./shared";
import { Module, ENVIRONMENT_IS_WORKER, createPromiseController, loaderHelpers, mono_assert, runtimeHelpers } from "../globals";
import { PThreadLibrary, MainToWorkerMessageType, MonoThreadMessage, PThreadInfo, PThreadPtr, PThreadPtrNull, PThreadWorker, PromiseAndController, PromiseController, Thread, WorkerToMainMessageType, monoMessageSymbol } from "../types/internal";
@@ -148,10 +148,11 @@ export async function mono_wasm_init_threads() {
if (!WasmEnableThreads) return;
// setup the UI thread
- monoThreadInfo.pthreadId = mono_wasm_pthread_ptr();
+ runtimeHelpers.currentThreadTID = monoThreadInfo.pthreadId = mono_wasm_pthread_ptr();
monoThreadInfo.threadName = "UI Thread";
monoThreadInfo.isUI = true;
monoThreadInfo.isRunning = true;
+ monoThreadInfo.workerNumber = 0;
update_thread_info();
// wait until all workers in the pool are loaded - ready to be used as pthread synchronously
@@ -211,7 +212,11 @@ export function init_finalizer_thread() {
// we don't need it immediately, so we can wait a bit, to keep CPU working on normal startup
setTimeout(() => {
try {
- cwraps.mono_wasm_init_finalizer_thread();
+ if (loaderHelpers.is_runtime_running()) {
+ cwraps.mono_wasm_init_finalizer_thread();
+ } else {
+ mono_log_debug("init_finalizer_thread skipped");
+ }
}
catch (err) {
mono_log_error("init_finalizer_thread() failed", err);
diff --git a/src/mono/browser/runtime/pthreads/worker-thread.ts b/src/mono/browser/runtime/pthreads/worker-thread.ts
index 083f87d7de025..5631c2475e652 100644
--- a/src/mono/browser/runtime/pthreads/worker-thread.ts
+++ b/src/mono/browser/runtime/pthreads/worker-thread.ts
@@ -5,11 +5,9 @@
import WasmEnableThreads from "consts:wasmEnableThreads";
-import { Module } from "../globals";
-
-import { ENVIRONMENT_IS_PTHREAD, loaderHelpers, mono_assert, runtimeHelpers } from "../globals";
+import { ENVIRONMENT_IS_PTHREAD, Module, loaderHelpers, mono_assert, runtimeHelpers } from "../globals";
import { PThreadSelf, monoThreadInfo, mono_wasm_pthread_ptr, postMessageToMain, update_thread_info } from "./shared";
-import { PThreadLibrary, MonoThreadMessage, PThreadInfo, PThreadPtr, WorkerToMainMessageType, is_nullish } from "../types/internal";
+import { PThreadLibrary, MonoThreadMessage, PThreadInfo, PThreadPtr, WorkerToMainMessageType } from "../types/internal";
import {
makeWorkerThreadEvent,
dotnetPthreadCreated,
@@ -71,7 +69,7 @@ function monoDedicatedChannelMessageFromMainToWorker(event: MessageEvent
}
export function on_emscripten_thread_init(pthread_ptr: PThreadPtr) {
- monoThreadInfo.pthreadId = pthread_ptr;
+ runtimeHelpers.currentThreadTID = monoThreadInfo.pthreadId = pthread_ptr;
forceThreadMemoryViewRefresh();
}
@@ -82,10 +80,9 @@ export function mono_wasm_pthread_on_pthread_created(): void {
if (!WasmEnableThreads) return;
try {
forceThreadMemoryViewRefresh();
-
const pthread_id = mono_wasm_pthread_ptr();
- mono_assert(!is_nullish(pthread_id), "pthread_self() returned null");
- monoThreadInfo.pthreadId = pthread_id;
+ mono_assert(pthread_id == monoThreadInfo.pthreadId, `needs to match (mono_wasm_pthread_ptr ${pthread_id}, threadId from thread info ${monoThreadInfo.pthreadId})`);
+
monoThreadInfo.reuseCount++;
monoThreadInfo.updateCount++;
monoThreadInfo.threadName = "pthread-assigned";
@@ -206,18 +203,24 @@ export function mono_wasm_pthread_on_pthread_unregistered(pthread_id: PThreadPtr
}
}
-export function replaceEmscriptenPThreadWorker(modulePThread: PThreadLibrary): void {
+export function replaceEmscriptenTLSInit(modulePThread: PThreadLibrary): void {
if (!WasmEnableThreads) return;
const originalThreadInitTLS = modulePThread.threadInitTLS;
- const original_emscripten_thread_init = (Module as any)["__emscripten_thread_init"];
- (Module as any)["__emscripten_thread_init"] = (pthread_ptr: PThreadPtr, isMainBrowserThread: number, isMainRuntimeThread: number, canBlock: number) => {
- on_emscripten_thread_init(pthread_ptr);
- original_emscripten_thread_init(pthread_ptr, isMainBrowserThread, isMainRuntimeThread, canBlock);
- };
modulePThread.threadInitTLS = (): void => {
originalThreadInitTLS();
mono_wasm_pthread_on_pthread_created();
};
-}
\ No newline at end of file
+}
+
+export function replaceEmscriptenPThreadInit(): void {
+ const original_emscripten_thread_init = Module["__emscripten_thread_init"];
+ function emscripten_thread_init_wrapper(pthread_ptr: PThreadPtr, isMainBrowserThread: number, isMainRuntimeThread: number, canBlock: number) {
+ on_emscripten_thread_init(pthread_ptr);
+ original_emscripten_thread_init(pthread_ptr, isMainBrowserThread, isMainRuntimeThread, canBlock);
+ // re-install self
+ Module["__emscripten_thread_init"] = emscripten_thread_init_wrapper;
+ }
+ Module["__emscripten_thread_init"] = emscripten_thread_init_wrapper;
+}
diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts
index 9759e879254b0..8d98635b55637 100644
--- a/src/mono/browser/runtime/startup.ts
+++ b/src/mono/browser/runtime/startup.ts
@@ -32,6 +32,7 @@ import { assertNoProxies } from "./gc-handles";
import { runtimeList } from "./exports";
import { nativeAbort, nativeExit } from "./run";
import { mono_wasm_init_diagnostics } from "./diagnostics";
+import { replaceEmscriptenPThreadInit } from "./pthreads/worker-thread";
export async function configureRuntimeStartup(): Promise {
await init_polyfills_async();
@@ -125,6 +126,7 @@ async function instantiateWasmWorker(
await loaderHelpers.afterConfigLoaded.promise;
replace_linker_placeholders(imports);
+ replaceEmscriptenPThreadInit();
// Instantiate from the module posted from the main thread.
// We can just use sync instantiation in the worker.
@@ -268,13 +270,9 @@ async function onRuntimeInitializedAsync(userOnRuntimeInitialized: () => void) {
Module.runtimeKeepalivePush();
- // load runtime and apply environment settings (if necessary)
+ // load mono runtime and apply environment settings (if necessary)
await start_runtime();
- if (runtimeHelpers.config.interpreterPgo) {
- await interp_pgo_load_data();
- }
-
if (!ENVIRONMENT_IS_WORKER) {
Module.runtimeKeepalivePush();
}
@@ -515,12 +513,12 @@ export async function start_runtime() {
if (WasmEnableThreads) {
monoThreadInfo.isAttached = true;
+ monoThreadInfo.isRunning = true;
monoThreadInfo.isRegistered = true;
- monoThreadInfo.pthreadId = runtimeHelpers.managedThreadTID = mono_wasm_pthread_ptr();
- monoThreadInfo.workerNumber = 0;
+ runtimeHelpers.currentThreadTID = monoThreadInfo.pthreadId = runtimeHelpers.managedThreadTID = mono_wasm_pthread_ptr();
update_thread_info();
runtimeHelpers.proxyGCHandle = install_main_synchronization_context();
- runtimeHelpers.isCurrentThread = true;
+ runtimeHelpers.isManagedRunningOnCurrentThread = true;
// start finalizer thread, lazy
init_finalizer_thread();
@@ -529,6 +527,10 @@ export async function start_runtime() {
// get GCHandle of the ctx
runtimeHelpers.afterMonoStarted.promise_control.resolve(runtimeHelpers.proxyGCHandle);
+ if (runtimeHelpers.config.interpreterPgo) {
+ await interp_pgo_load_data();
+ }
+
endMeasure(mark, MeasuredBlock.startRuntime);
} catch (err) {
mono_log_error("start_runtime() failed", err);
diff --git a/src/mono/browser/runtime/types/internal.ts b/src/mono/browser/runtime/types/internal.ts
index ae4ce1ff4813a..e92c24faa03b2 100644
--- a/src/mono/browser/runtime/types/internal.ts
+++ b/src/mono/browser/runtime/types/internal.ts
@@ -207,8 +207,9 @@ export type RuntimeHelpers = {
monoThreadInfo: PThreadInfo,
proxyGCHandle: GCHandle | undefined,
managedThreadTID: PThreadPtr,
- isCurrentThread: boolean,
- isPendingSynchronousCall: boolean, // true when we are in the middle of a synchronous call from managed code with the same JSProxyContext
+ currentThreadTID: PThreadPtr,
+ isManagedRunningOnCurrentThread: boolean,
+ isPendingSynchronousCall: boolean, // true when we are in the middle of a synchronous call from managed code from same thread
cspPolicy: boolean,
allAssetsInMemory: PromiseAndController,
@@ -426,6 +427,7 @@ export declare interface EmscriptenModuleInternal {
runtimeKeepalivePush(): void;
runtimeKeepalivePop(): void;
maybeExit(): void;
+ __emscripten_thread_init(pthread_ptr: PThreadPtr, isMainBrowserThread: number, isMainRuntimeThread: number, canBlock: number): void;
}
/// A PromiseController encapsulates a Promise together with easy access to its resolve and reject functions.
diff --git a/src/mono/sample/wasm/browser-threads/Program.cs b/src/mono/sample/wasm/browser-threads/Program.cs
index 148a002dfe1ed..907b3d3356b3c 100644
--- a/src/mono/sample/wasm/browser-threads/Program.cs
+++ b/src/mono/sample/wasm/browser-threads/Program.cs
@@ -8,153 +8,72 @@
using System.Threading.Tasks;
using System.Collections.Generic;
-namespace Sample
-{
- public partial class Test
- {
- public static int Main(string[] args)
- {
- Console.WriteLine("Hello, World!");
- return 0;
- }
-
- [JSImport("globalThis.console.log")]
- public static partial void ConsoleLog(string status);
-
- [JSImport("Sample.Test.updateProgress", "main.js")]
- static partial void updateProgress(string status);
+namespace Sample;
- internal static void UpdateProgress(string status) => updateProgress(status);
+public partial class Test
+{
+ private static int _animationCounter = 0;
+ private static int _callCounter = 0;
+ private static bool _isRunning = false;
+ private static readonly IReadOnlyList _animations = new string[] { "\u2680", "\u2681", "\u2682", "\u2683", "\u2684", "\u2685" };
- static Demo _demo = null;
+ public static int Main(string[] args)
+ {
+ Console.WriteLine("Hello, World!");
+ return 0;
+ }
- [JSExport]
- public static void Start(int n)
- {
- var comp = new ExpensiveComputation(n);
- comp.Start();
- #pragma warning disable CS4014
- WaitForCompletion(comp);
- _demo = new Demo(UpdateProgress, comp);
- }
+ [JSImport("globalThis.console.log")]
+ public static partial void ConsoleLog(string status);
- public static async Task WaitForCompletion (ExpensiveComputation comp) {
- Console.WriteLine($"WaitForCompletion started on thread {Thread.CurrentThread.ManagedThreadId}");
- await comp.Completion;
- Console.WriteLine($"WaitForCompletion completed on thread {Thread.CurrentThread.ManagedThreadId}");
- UpdateProgress("\u270C\uFE0E");
- }
+ [JSImport("Sample.Test.updateProgress", "main.js")]
+ private static partial Task updateProgress(string status);
- [JSExport]
- public static int Progress()
+ [JSExport]
+ public static bool Progress()
+ {
+ updateProgress(""+_animations[_animationCounter++]);
+ if (_animationCounter >= _animations.Count)
{
- if (_demo.Progress())
- return 0; /* done */
- else
- return 1; /* continue */
+ _animationCounter = 0;
}
-
- [JSExport]
- public static int GetAnswer() { return _demo.Result; }
+ return _isRunning;
}
-}
-
-public class ExpensiveComputation
-{
- private readonly TaskCompletionSource _tcs = new();
- private readonly int UpTo;
- public ExpensiveComputation(int n) { UpTo = n; }
- public long CallCounter { get; private set; }
- public Task Completion => _tcs.Task;
-
- public void Start()
+ [JSExport]
+ [return: JSMarshalAs>]
+ public static Task Fib(int n)
{
- new Thread((o) => ((ExpensiveComputation)o).Run()).Start(this);
+ return Task.Run(()=>{
+ _isRunning = true;
+ var res = FibImpl(n);
+ _isRunning = false;
+ return Task.FromResult(res);
+ });
}
- public void Run()
+ private static long FibImpl(int n)
{
- Console.WriteLine("Hello from ManagedThreadId " + Thread.CurrentThread.ManagedThreadId);
- long result = Fib(UpTo);
- if (result < (long)int.MaxValue)
- _tcs.SetResult((int)result);
- else
- _tcs.SetException(new Exception("Fibonacci computation exceeded Int32.MaxValue"));
- }
- public long Fib(int n)
- {
- CallCounter++;
+ _callCounter++;
// make some garbage every 1000 calls
- if (CallCounter % 1000 == 0)
+ if (_callCounter % 1000 == 0)
{
AllocateGarbage();
}
// and collect it every once in a while
- if (CallCounter % 500000 == 0)
+ if (_callCounter % 500000 == 0)
GC.Collect();
if (n < 2)
return n;
- return Fib(n - 1) + Fib(n - 2);
+ return FibImpl(n - 1) + FibImpl(n - 2);
}
[MethodImpl(MethodImplOptions.NoInlining)]
- private void AllocateGarbage()
+ private static void AllocateGarbage()
{
object[] garbage = new object[200];
garbage[12] = new object();
garbage[197] = garbage;
}
-
-}
-
-public class Demo
-{
- public class Animation
- {
- private readonly Action _updateProgress;
- private int _counter = 0;
-
- private readonly IReadOnlyList _animations = new string[] { "\u2680", "\u2681", "\u2682", "\u2683", "\u2684", "\u2685" };
-
- public void Step(string suffix = "")
- {
- _updateProgress(_animations[_counter++] + suffix);
- if (_counter >= _animations.Count)
- {
- _counter = 0;
- }
- }
-
- public Animation(Action updateProgress)
- {
- _updateProgress = updateProgress;
- }
-
-
- }
-
- private readonly Action _updateProgress;
- private readonly Animation _animation;
- private readonly ExpensiveComputation _expensiveComputation;
-
- public Demo(Action updateProgress, ExpensiveComputation comp)
- {
- _updateProgress = updateProgress;
- _animation = new Animation(updateProgress);
- _expensiveComputation = comp;
- }
-
- public bool Progress()
- {
- if (!_expensiveComputation.Completion.IsCompleted)
- {
- _animation.Step($"{_expensiveComputation.CallCounter} calls");
- }
-
- return _expensiveComputation.Completion.IsCompleted;
- }
-
- public int Result => _expensiveComputation.Completion.Result;
}
diff --git a/src/mono/sample/wasm/browser-threads/main.js b/src/mono/sample/wasm/browser-threads/main.js
index d53e59304e10d..127e2402f7854 100644
--- a/src/mono/sample/wasm/browser-threads/main.js
+++ b/src/mono/sample/wasm/browser-threads/main.js
@@ -4,54 +4,14 @@
import { dotnet, exit } from './_framework/dotnet.js'
let progressElement = null;
-
-function updateProgress(status) {
- if (progressElement) {
- progressElement.innerText = status;
- } else {
- console.log("Progress: " + status);
- }
-}
-
+let inputElement = null;
+let exports = null;
const assemblyName = "Wasm.Browser.Threads.Sample.dll";
-function delay(ms) {
- return new Promise(resolve => setTimeout(resolve, ms));
-}
-
-async function Run(exports, N) {
- while (true) {
- await delay(50);
- const p = exports.Sample.Test.Progress();
- if (p === 0)
- break;
- }
- const answer = exports.Sample.Test.GetAnswer();
- document.getElementById("out").innerText = `Fib(${N}) = ${answer}`;
-}
-
-async function doMathSlowly(exports) {
+try {
progressElement = document.getElementById("progressElement");
- const N = parseInt(document.getElementById("inputN").value);
- exports.Sample.Test.Start(N);
- await Run(exports, N);
-}
-
-function setEditable(inputElement, isEditable) {
- inputElement.disabled = !isEditable;
-}
-
-function onInputValueChanged(exports, inputElement) {
- async function handler() {
- setEditable(inputElement, false);
- await doMathSlowly(exports);
- setEditable(inputElement, true);
- }
- return handler;
-}
+ inputElement = document.getElementById("inputN");
-try {
- const inputElement = document.getElementById("inputN");
const { setModuleImports, getAssemblyExports, runMain } = await dotnet
.withEnvironmentVariable("MONO_LOG_LEVEL", "debug")
.withElementOnExit()
@@ -67,14 +27,52 @@ try {
}
});
- const exports = await getAssemblyExports(assemblyName);
+ exports = await getAssemblyExports(assemblyName);
- await doMathSlowly(exports);
- setEditable(inputElement, true);
- inputElement.addEventListener("change", onInputValueChanged(exports, inputElement));
+ await doSlowMath();
+ setEditable(true);
+ inputElement.addEventListener("change", onInputValueChanged);
let exit_code = await runMain(assemblyName, []);
+ // comment out the following line for interactive testing, otherwise further call would be rejected by runtime
exit(exit_code);
} catch (err) {
exit(2, err);
}
+
+async function doSlowMath() {
+ const N = parseInt(document.getElementById("inputN").value);
+ const resultPromise = exports.Sample.Test.Fib(N);
+
+ while (true) {
+ await delay(50);
+ const isRunning = exports.Sample.Test.Progress();
+ if (!isRunning)
+ break;
+ }
+ const answer = await resultPromise;
+ document.getElementById("out").innerText = `Fib(${N}) = ${answer}`;
+
+}
+
+export async function updateProgress(status) {
+ if (progressElement) {
+ progressElement.innerText = status;
+ } else {
+ console.log("Progress: " + status);
+ }
+}
+
+function delay(ms) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+
+function setEditable(isEditable) {
+ inputElement.disabled = !isEditable;
+}
+
+async function onInputValueChanged() {
+ setEditable(false);
+ await doSlowMath(exports);
+ setEditable(true);
+}
diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
index 2e3491374c7d9..ccea19a5b4970 100644
--- a/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/BlazorWasmTestBase.cs
@@ -198,7 +198,7 @@ public async Task BlazorRunTest(string runArgs,
var page = await runner.RunAsync(runCommand, runArgs, onConsoleMessage: OnConsoleMessage, onError: OnErrorMessage, modifyBrowserUrl: browserUrl => browserUrl + runOptions.QueryString);
_testOutput.WriteLine("Waiting for page to load");
- await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
+ await page.WaitForLoadStateAsync(LoadState.DOMContentLoaded, new () { Timeout = 1 * 60 * 1000 });
if (runOptions.CheckCounter)
{
diff --git a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs
index 5f1e1711151c0..bdee6a275a0ed 100644
--- a/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/Blazor/SimpleMultiThreadedTests.cs
@@ -38,7 +38,7 @@ public SimpleMultiThreadedTests(ITestOutputHelper output, SharedBuildPerTestClas
// }
[ConditionalTheory(typeof(BuildTestBase), nameof(IsWorkloadWithMultiThreadingForDefaultFramework))]
- [InlineData("Debug", false)]
+ // [InlineData("Debug", false)] // ActiveIssue https://github.com/dotnet/runtime/issues/98758
// [InlineData("Debug", true)]
[InlineData("Release", false)]
// [InlineData("Release", true)]
diff --git a/src/mono/wasm/Wasm.Build.Tests/Common/EnvironmentVariables.cs b/src/mono/wasm/Wasm.Build.Tests/Common/EnvironmentVariables.cs
index 841aa6a9b3456..50bf882d072d3 100644
--- a/src/mono/wasm/Wasm.Build.Tests/Common/EnvironmentVariables.cs
+++ b/src/mono/wasm/Wasm.Build.Tests/Common/EnvironmentVariables.cs
@@ -18,10 +18,10 @@ internal static class EnvironmentVariables
internal static readonly string? BuiltNuGetsPath = Environment.GetEnvironmentVariable("BUILT_NUGETS_PATH");
internal static readonly string? BrowserPathForTests = Environment.GetEnvironmentVariable("BROWSER_PATH_FOR_TESTS");
internal static readonly string? V8PathForTests = Environment.GetEnvironmentVariable("V8_PATH_FOR_TESTS");
- internal static readonly bool ShowBuildOutput = Environment.GetEnvironmentVariable("SHOW_BUILD_OUTPUT") is not null;
+ internal static readonly bool IsRunningOnCI = Environment.GetEnvironmentVariable("IS_RUNNING_ON_CI") is "true";
+ internal static readonly bool ShowBuildOutput = IsRunningOnCI || Environment.GetEnvironmentVariable("SHOW_BUILD_OUTPUT") is not null;
internal static readonly bool UseWebcil = Environment.GetEnvironmentVariable("USE_WEBCIL_FOR_TESTS") is "true";
internal static readonly string? SdkDirName = Environment.GetEnvironmentVariable("SDK_DIR_NAME");
internal static readonly string? WasiSdkPath = Environment.GetEnvironmentVariable("WASI_SDK_PATH");
- internal static readonly bool IsRunningOnCI = Environment.GetEnvironmentVariable("IS_RUNNING_ON_CI") is "true";
}
}