From 43be3a11a0041f050fb42159d9d3b498d1e5f606 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Fri, 6 Jan 2023 21:43:02 +0100 Subject: [PATCH] manual backport of https://github.com/dotnet/runtime/pull/80257 --- .../JavaScript/JSImportExportTest.cs | 14 +++++++++++++ src/mono/wasm/runtime/invoke-js.ts | 20 +++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs index 9fbac261b76ebf..81341d23ebaba5 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs @@ -5,6 +5,7 @@ using System.IO; using System.Runtime.CompilerServices; using System.Threading.Tasks; +using System.Threading; using Xunit; #pragma warning disable xUnit1026 // Theory methods should use all of their parameters @@ -18,6 +19,19 @@ public unsafe void StructSize() Assert.Equal(16, sizeof(JSMarshalerArgument)); } + [Fact] + public async Task CancelableImportAsync() + { + var cts = new CancellationTokenSource(); + var exTask = Assert.ThrowsAsync(async () => await JSHost.ImportAsync("JavaScriptTestHelper", "./JavaScriptTestHelper.mjs", cts.Token)); + cts.Cancel(); + var actualEx2 = await exTask; + Assert.Equal("OperationCanceledException", actualEx2.Message); + + var actualEx = await Assert.ThrowsAsync(async () => await JSHost.ImportAsync("JavaScriptTestHelper", "./JavaScriptTestHelper.mjs", new CancellationToken(true))); + Assert.Equal("OperationCanceledException", actualEx.Message); + } + [Fact] public unsafe void GlobalThis() { diff --git a/src/mono/wasm/runtime/invoke-js.ts b/src/mono/wasm/runtime/invoke-js.ts index 7e31a296fdb987..0f6fd9f55361d7 100644 --- a/src/mono/wasm/runtime/invoke-js.ts +++ b/src/mono/wasm/runtime/invoke-js.ts @@ -12,6 +12,7 @@ import { IMPORTS, INTERNAL, Module, runtimeHelpers } from "./imports"; import { generate_arg_marshal_to_js } from "./marshal-to-js"; import { mono_wasm_new_external_root } from "./roots"; import { mono_wasm_symbolicate_string } from "./logging"; +import { wrap_as_cancelable_promise } from "./cancelable-promise"; export function mono_wasm_bind_js_function(function_name: MonoStringRef, module_name: MonoStringRef, signature: JSFunctionSignature, function_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const function_name_root = mono_wasm_new_external_root(function_name), @@ -174,7 +175,7 @@ export function get_global_this(): any { export const importedModulesPromises: Map> = new Map(); export const importedModules: Map> = new Map(); -export async function dynamic_import(module_name: string, module_url: string): Promise { +export function dynamic_import(module_name: string, module_url: string): Promise { mono_assert(module_name, "Invalid module_name"); mono_assert(module_url, "Invalid module_name"); let promise = importedModulesPromises.get(module_name); @@ -185,13 +186,16 @@ export async function dynamic_import(module_name: string, module_url: string): P promise = import(/* webpackIgnore: true */module_url); importedModulesPromises.set(module_name, promise); } - const module = await promise; - if (newPromise) { - importedModules.set(module_name, module); - if (runtimeHelpers.diagnosticTracing) - console.debug(`MONO_WASM: imported ES6 module '${module_name}' from '${module_url}'`); - } - return module; + + return wrap_as_cancelable_promise(async () => { + const module = await promise; + if (newPromise) { + importedModules.set(module_name, module); + if (runtimeHelpers.diagnosticTracing) + console.debug(`MONO_WASM: imported ES6 module '${module_name}' from '${module_url}'`); + } + return module; + }); }