Skip to content

[browser][nodeJS] JSImport is causing a deadlock in .net10 #123186

@Problemkurs

Description

@Problemkurs

Description

When using the WebAssembly browser/node.js stack in .net10, asynchronous interop calls ( [JSImport] specifically) freeze indefinitely after reaching 1000 calls. This appears to be a regression, as the exact same code runs to completion and executes noticeably faster .net9.

Reproduction Steps

  1. Create a new “WebAssembly Console App” (dotnet new wasmconsole).
  2. Update the .csproj to target <TargetFramework>net10.0</TargetFramework>.
  3. make both JSImport/JSExport example calls async as shown below
  4. add a loop calling a JSImport at least 1000 times as shown below
  5. Build the project: dotnet build -c Release.
  6. Run the output in Node.js: node .\bin\Release\net10.0\browser-wasm\AppBundle\main.mjs.

Program.cs

using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;

public partial class MyClass
{
    [JSExport]
    internal static async Task<string> Greeting()
    {
        var text = $"Hello! Node version: {await GetNodeVersion()}";
        return text;
    }

[JSImport("node.process.version", "main.mjs")]
    internal static partial Task<string> GetNodeVersion();
}
  

main.mjs

import { dotnet } from './_framework/dotnet.js'

const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
    .withDiagnosticTracing(false)
    .create();

setModuleImports('main.mjs', {
    node: {
        process: {
            version: async () => globalThis.process.version
        }
    }
});

const config = getConfig();
const exports = await getAssemblyExports(config.mainAssemblyName);

// This loop hangs at i=1000 in .NET 10
for (let i = 1; i <= 3000; i++) {
    await exports.MyClass.Greeting();
    console.log(`Iteration: ${i}`);
}

console.log("Completed successfully!");
await dotnet.run();
  

Expected behavior

The node application should run to completion

Actual behavior

The execution freezes at exactly i == 1000 and the process appears to hang inside a tight webassembly loop.

Regression?

Changing the TF of the project to net9 fixes the issue.
The example loop also runs noticeably faster in net9

Known Workarounds

await dotnet
    .withEnvironmentVariable('MONO_INTERPRETER_OPTIONS', '-ssa')
    .create();

Configuration

dotnet-sdk-10.0.102-win-x64
Node.js v22.11.0.
Windows 11 x64

Other information

No response

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions