From 518799b1305abc22cc84db48fdf397ee501e3d12 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 10:51:21 +0100 Subject: [PATCH 1/9] another attempt --- .../Marshaling/JSMarshalerArgument.Task.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index e01b292cc172b..47406498850e8 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -229,18 +229,18 @@ public void ToJS(Task? value) { Task? task = value; var ctx = ToJSContext; - var isCurrentThread = ctx.IsCurrentThread(); + var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; if (task == null) { - if (!isCurrentThread) + if (!isCurrentThreadOrParameter) { - Environment.FailFast("Marshalling null task to JS is not supported in MT"); + Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); } slot.Type = MarshalerType.None; return; } - if (isCurrentThread && task.IsCompleted) + if (isCurrentThreadOrParameter && task.IsCompleted) { if (task.Exception != null) { @@ -303,19 +303,19 @@ public void ToJS(Task? value, ArgumentToJSCallback marshaler) { Task? task = value; var ctx = ToJSContext; - var isCurrentThread = ctx.IsCurrentThread(); + var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; if (task == null) { - if (!isCurrentThread) + if (!isCurrentThreadOrParameter) { - Environment.FailFast("NULL not supported in MT"); + Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); } slot.Type = MarshalerType.None; return; } - if (isCurrentThread && task.IsCompleted) + if (isCurrentThreadOrParameter && task.IsCompleted) { if (task.Exception != null) { From 4463f28b70f5b1574a63962bdb9b6eaf56d7bd9a Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 11:27:52 +0100 Subject: [PATCH 2/9] more --- .../JavaScript/Marshaling/JSMarshalerArgument.Task.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index 47406498850e8..ecbb048c61399 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -140,13 +140,21 @@ internal void ToJSDynamic(Task? value) { Task? task = value; + var ctx = ToJSContext; + + var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; + if (task == null) { + if (!isCurrentThreadOrParameter) + { + Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); + } slot.Type = MarshalerType.None; return; } - if (task.IsCompleted) + if (task.IsCompleted && isCurrentThreadOrParameter) { if (task.Exception != null) { @@ -172,7 +180,6 @@ internal void ToJSDynamic(Task? value) } } - var ctx = ToJSContext; if (slot.Type != MarshalerType.TaskPreCreated) { From 896c4aec8a352550a7bbf25bf0ee7c38ee7b6afc Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 15:04:18 +0100 Subject: [PATCH 3/9] JSAsyncTaskScheduler --- ....Runtime.InteropServices.JavaScript.csproj | 1 + .../JavaScript/JSAsyncTaskScheduler.cs | 43 +++++++++++++++++++ .../JavaScript/JSProxyContext.cs | 6 ++- .../JavaScript/JSSynchronizationContext.cs | 2 + .../Marshaling/JSMarshalerArgument.Task.cs | 12 ++++-- 5 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSAsyncTaskScheduler.cs diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index 9b20df8bd80e1..4b637cee5f174 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -68,6 +68,7 @@ + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSAsyncTaskScheduler.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSAsyncTaskScheduler.cs new file mode 100644 index 0000000000000..423843af3301f --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSAsyncTaskScheduler.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace System.Runtime.InteropServices.JavaScript +{ + // executes all tasks thru queue, never inline + internal sealed class JSAsyncTaskScheduler : TaskScheduler + { + private readonly JSSynchronizationContext m_synchronizationContext; + + internal JSAsyncTaskScheduler(JSSynchronizationContext synchronizationContext) + { + m_synchronizationContext = synchronizationContext; + } + + protected override void QueueTask(Task task) + { + m_synchronizationContext.Post((_) => + { + if (!TryExecuteTask(task)) + { + Environment.FailFast("Unexpected failure in JSAsyncTaskScheduler" + Environment.CurrentManagedThreadId); + } + }, null); + } + + // this is the main difference from the SynchronizationContextTaskScheduler + protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) + { + return false; + } + + protected override IEnumerable? GetScheduledTasks() + { + return null; + } + + public override int MaximumConcurrencyLevel => 1; + } +} 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 f8cc312f1c2f2..a612fbc1c7874 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 @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; +using System.Threading.Tasks; using static System.Runtime.InteropServices.JavaScript.JSHostImplementation; namespace System.Runtime.InteropServices.JavaScript @@ -40,6 +41,7 @@ private JSProxyContext() public int ManagedTID; // current managed thread id public bool IsMainThread; public JSSynchronizationContext SynchronizationContext; + public TaskScheduler? AsyncTaskScheduler; public static MainThreadingMode MainThreadingMode = MainThreadingMode.DeputyThread; public static JSThreadBlockingMode ThreadBlockingMode = JSThreadBlockingMode.NoBlockingWait; @@ -475,7 +477,7 @@ public static void ReleaseCSOwnedObject(JSObject jso, bool skipJS) { if (IsJSVHandle(jsHandle)) { - Environment.FailFast("TODO implement blocking ReleaseCSOwnedObjectSend to make sure the order of FreeJSVHandle is correct."); + Environment.FailFast($"TODO implement blocking ReleaseCSOwnedObjectSend to make sure the order of FreeJSVHandle is correct, ManagedThreadId: {Environment.CurrentManagedThreadId}. {Environment.NewLine} {Environment.StackTrace}"); } // this is async message, we need to call this as the last thing @@ -493,7 +495,7 @@ public static void ReleaseCSOwnedObject(JSObject jso, bool skipJS) } } -#endregion + #endregion #region Dispose diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs index ed7fffbae25de..e55276569e9bb 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs @@ -4,6 +4,7 @@ #if FEATURE_WASM_MANAGED_THREADS using System.Threading; +using System.Threading.Tasks; using System.Threading.Channels; using System.Runtime.CompilerServices; using WorkItemQueueType = System.Threading.Channels.Channel; @@ -56,6 +57,7 @@ public static unsafe JSSynchronizationContext InstallWebWorkerInterop(bool isMai } var proxyContext = ctx.ProxyContext; + proxyContext.AsyncTaskScheduler = new JSAsyncTaskScheduler(ctx); JSProxyContext.CurrentThreadContext = proxyContext; JSProxyContext.ExecutionContext = proxyContext; if (isMainThread) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index ecbb048c61399..b937dc577f325 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -196,7 +196,9 @@ internal void ToJSDynamic(Task? value) var taskHolder = ctx.CreateCSOwnedProxy(slot.JSHandle); #if FEATURE_WASM_MANAGED_THREADS - task.ContinueWith(Complete, taskHolder, CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.FromCurrentSynchronizationContext()); + // AsyncTaskScheduler will make sure that the resolve message is always sent after this call is completed + // that is: synchronous marshaling and eventually message to the target thread, which need to arrive before the resolve message + task.ContinueWith(Complete, taskHolder, ctx.AsyncTaskScheduler!); #else task.ContinueWith(Complete, taskHolder, TaskScheduler.Current); #endif @@ -280,7 +282,9 @@ public void ToJS(Task? value) var taskHolder = ctx.CreateCSOwnedProxy(slot.JSHandle); #if FEATURE_WASM_MANAGED_THREADS - task.ContinueWith(Complete, taskHolder, CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.FromCurrentSynchronizationContext()); + // AsyncTaskScheduler will make sure that the resolve message is always sent after this call is completed + // that is: synchronous marshaling and eventually message to the target thread, which need to arrive before the resolve message + task.ContinueWith(Complete, taskHolder, ctx.AsyncTaskScheduler!); #else task.ContinueWith(Complete, taskHolder, TaskScheduler.Current); #endif @@ -357,7 +361,9 @@ public void ToJS(Task? value, ArgumentToJSCallback marshaler) var taskHolder = ctx.CreateCSOwnedProxy(slot.JSHandle); #if FEATURE_WASM_MANAGED_THREADS - task.ContinueWith(Complete, new HolderAndMarshaler(taskHolder, marshaler), CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously, TaskScheduler.FromCurrentSynchronizationContext()); + // AsyncTaskScheduler will make sure that the resolve message is always sent after this call is completed + // that is: synchronous marshaling and eventually message to the target thread, which need to arrive before the resolve message + task.ContinueWith(Complete, new HolderAndMarshaler(taskHolder, marshaler), ctx.AsyncTaskScheduler!); #else task.ContinueWith(Complete, new HolderAndMarshaler(taskHolder, marshaler), TaskScheduler.Current); #endif From 55d97cdc0778600a8f6a4f8bb073c0f343142e38 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 6 Mar 2024 17:36:06 +0100 Subject: [PATCH 4/9] Update src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSProxyContext.cs Co-authored-by: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> --- .../System/Runtime/InteropServices/JavaScript/JSProxyContext.cs | 1 - 1 file changed, 1 deletion(-) 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 9c77af8e0f87e..0053db5318a79 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 @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; -using System.Threading.Tasks; using static System.Runtime.InteropServices.JavaScript.JSHostImplementation; namespace System.Runtime.InteropServices.JavaScript From 8d2fcdc8062e2d42245d0b9910f6a45e0bf8c327 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Wed, 6 Mar 2024 17:36:12 +0100 Subject: [PATCH 5/9] Update src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs Co-authored-by: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> --- .../JavaScript/Marshaling/JSMarshalerArgument.Task.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index b937dc577f325..0fc77a61a645c 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -142,6 +142,7 @@ internal void ToJSDynamic(Task? value) var ctx = ToJSContext; + // current thread or non-return parameter of JSImport var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; if (task == null) From 5f3d569c961785663dbca717aa73ff2d5c387841 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 18:10:50 +0100 Subject: [PATCH 6/9] explain it in comments --- .../JavaScript/JSProxyContext.cs | 2 +- .../Marshaling/JSMarshalerArgument.Task.cs | 53 +++++++++++++++---- 2 files changed, 43 insertions(+), 12 deletions(-) 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 0053db5318a79..2ef8eb48120c9 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 @@ -40,7 +40,7 @@ private JSProxyContext() public int ManagedTID; // current managed thread id public bool IsMainThread; public JSSynchronizationContext SynchronizationContext; - public TaskScheduler? AsyncTaskScheduler; + public JSAsyncTaskScheduler? AsyncTaskScheduler; public static MainThreadingMode MainThreadingMode = MainThreadingMode.DeputyThread; public static JSThreadBlockingMode ThreadBlockingMode = JSThreadBlockingMode.NoBlockingWait; diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index 0fc77a61a645c..f67caf6595e83 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -141,13 +141,11 @@ internal void ToJSDynamic(Task? value) Task? task = value; var ctx = ToJSContext; - - // current thread or non-return parameter of JSImport - var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; + var canMarshalTaskResultOnSameCall = CanMarshalTaskResultOnSameCall(ctx); if (task == null) { - if (!isCurrentThreadOrParameter) + if (!canMarshalTaskResultOnSameCall) { Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); } @@ -155,7 +153,7 @@ internal void ToJSDynamic(Task? value) return; } - if (task.IsCompleted && isCurrentThreadOrParameter) + if (canMarshalTaskResultOnSameCall && task.IsCompleted) { if (task.Exception != null) { @@ -239,18 +237,18 @@ public void ToJS(Task? value) { Task? task = value; var ctx = ToJSContext; - var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; + var canMarshalTaskResultOnSameCall = CanMarshalTaskResultOnSameCall(ctx); if (task == null) { - if (!isCurrentThreadOrParameter) + if (!canMarshalTaskResultOnSameCall) { Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); } slot.Type = MarshalerType.None; return; } - if (isCurrentThreadOrParameter && task.IsCompleted) + if (canMarshalTaskResultOnSameCall && task.IsCompleted) { if (task.Exception != null) { @@ -315,11 +313,11 @@ public void ToJS(Task? value, ArgumentToJSCallback marshaler) { Task? task = value; var ctx = ToJSContext; - var isCurrentThreadOrParameter = ctx.IsCurrentThread() || slot.Type != MarshalerType.TaskPreCreated; + var canMarshalTaskResultOnSameCall = CanMarshalTaskResultOnSameCall(ctx); if (task == null) { - if (!isCurrentThreadOrParameter) + if (!canMarshalTaskResultOnSameCall) { Environment.FailFast("Marshalling null return Task to JS is not supported in MT"); } @@ -327,7 +325,7 @@ public void ToJS(Task? value, ArgumentToJSCallback marshaler) return; } - if (isCurrentThreadOrParameter && task.IsCompleted) + if (canMarshalTaskResultOnSameCall && task.IsCompleted) { if (task.Exception != null) { @@ -384,6 +382,39 @@ static void Complete(Task task, object? thm) } } +#if FEATURE_WASM_MANAGED_THREADS + // We can't marshal resolved/rejected/null Task.Result directly into current argument when this is marshaling return of JSExport across threads + private bool CanMarshalTaskResultOnSameCall(JSProxyContext ctx) + { + if (slot.Type != MarshalerType.TaskPreCreated) + { + // this means that we are not in the return value of JSExport + // we are marshaling parameter of JSImport + return true; + } + + if (ctx.IsCurrentThread()) + { + // If the JS and Managed is running on the same thread we can use the args buffer, + // because the call is synchronous and the buffer will be processed. + // In that case the pre-allocated Promise would be discarded as necessary + // and the result will be marshaled by `try_marshal_sync_task_to_js` + return true; + } + + // Otherwise this is JSExport return value and we can't use the args buffer, because the args buffer arrived in async message and nobody is reading after this. + // In such case the JS side already pre-created the Promise and we have to use it, to resolve it in separate call via `mono_wasm_resolve_or_reject_promise_post` + // there is JSVHandle in this arg + return false; + } +#else + private bool CanMarshalTaskResultOnSameCall(JSProxyContext _) + { + // in ST build this is always synchronous and we can marshal the result directly + return true; + } +#endif + private sealed record HolderAndMarshaler(JSObject TaskHolder, ArgumentToJSCallback Marshaler); private static void RejectPromise(JSObject holder, Exception ex) From 7127520602bcd2922b6aa69561b802a778963263 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 18:14:17 +0100 Subject: [PATCH 7/9] more --- .../InteropServices/JavaScript/JSSynchronizationContext.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs index e55276569e9bb..8d9ea3283c8df 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSSynchronizationContext.cs @@ -4,7 +4,6 @@ #if FEATURE_WASM_MANAGED_THREADS using System.Threading; -using System.Threading.Tasks; using System.Threading.Channels; using System.Runtime.CompilerServices; using WorkItemQueueType = System.Threading.Channels.Channel; From 322b8d5619cdb795ea44afa265c39911c5651988 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 18:53:55 +0100 Subject: [PATCH 8/9] CA1822 --- .../JavaScript/Marshaling/JSMarshalerArgument.Task.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index f67caf6595e83..9ad38b4f7d2be 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -382,6 +382,9 @@ static void Complete(Task task, object? thm) } } +#if !DEBUG + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif #if FEATURE_WASM_MANAGED_THREADS // We can't marshal resolved/rejected/null Task.Result directly into current argument when this is marshaling return of JSExport across threads private bool CanMarshalTaskResultOnSameCall(JSProxyContext ctx) @@ -408,11 +411,13 @@ private bool CanMarshalTaskResultOnSameCall(JSProxyContext ctx) return false; } #else +#pragma warning disable CA1822 // Mark members as static private bool CanMarshalTaskResultOnSameCall(JSProxyContext _) { // in ST build this is always synchronous and we can marshal the result directly return true; } +#pragma warning restore CA1822 // Mark members as static #endif private sealed record HolderAndMarshaler(JSObject TaskHolder, ArgumentToJSCallback Marshaler); From cf375a4b041ae5a33d66ed7615262681caf32a69 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 6 Mar 2024 18:56:42 +0100 Subject: [PATCH 9/9] CompilerServices --- .../JavaScript/Marshaling/JSMarshalerArgument.Task.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs index 9ad38b4f7d2be..cb1e43a1a0096 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Threading; using static System.Runtime.InteropServices.JavaScript.JSHostImplementation; +using System.Runtime.CompilerServices; namespace System.Runtime.InteropServices.JavaScript {