dotnet / runtimelab

This repo is for experimentation and exploring new ideas that may or may not make it into the main dotnet/runtime repo.
MIT License
1.41k stars 197 forks source link

[NativeAOT-LLVM] DotnetJS Minor incompatibilities with WASM SDK on Mono runtime #2627

Open maxkatz6 opened 3 months ago

maxkatz6 commented 3 months ago

These problems are less important, as can be easily worked around in user code, but still wanted to mention them somewhere (unless it was mentioned before).

Null or empty config.mainAssemblyName

Typical "net9 browser" template would look like this, where mainAssemblyName is read from the config.

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

const dotnetRuntime = await dotnet
    .withApplicationArgumentsFromQuery()
    .create();

const config = dotnetRuntime.getConfig();

await dotnetRuntime.runMain(config.mainAssemblyName, [globalThis.location.href]);

It fails in runtime with:

MONO_WASM: Assert failed: Null or empty config.mainAssemblyName Error: Assert failed: Null or empty config.mainAssemblyName
ve @ dotnet.runtime.js:3

Workaround: Provide hardcoded assembly name:

const dotnetRuntime = await dotnet
     .withMainAssembly("hardcoded-assembly-name")
     .create();

WasmRuntimeAssetsLocation seems to be ignored

WasmRuntimeAssetsLocation is used to redefine in which folder runtime wasm/js files should be output relatively to the entry point index.html.

It's not well supported across the .NET SDKs though:

  1. Mono WASM supports WasmRuntimeAssetsLocation properly.
  2. NativeAOT-LLVM ignores it and assumes "./" as output folder for the framework files.
  3. Microsoft.NET.Sdk.WebAssembly SDK ignores it and assumes "./framework" as output folder for the framework files. AFAIK it's also the case with Blazor. Although I haven't checked it with latest previews.

It mostly affects JSHost.ImportAsync with custom js files, like we have avalonia.js, as ImportAsync is always relative to dotnet.js file. To make it work with either SDK, we always put it near dotnet.js. So that's a workaround I guess.

"net9.0-browser" TFM is not supported

error NETSDK1208: The target platform identifier browser was not recognized. This is because MSBuildEnableWorkloadResolver is set to false which disables .NET SDK Workloads which is required for this identifer.

But MSBuildEnableWorkloadResolver = false is required to run NativeAOT-LLVM, so it's blocked here.

Workaround: just use "net9.0".

JSExport/JSImport-callback exceptions are not marshalled to JS

https://github.com/maraf/runtimelab/blob/edc82cb72ed417d48e7d11ce042aebe2addca94e/src/mono/wasm/runtime/marshal-to-js.ts#L329