Skip to content

Comments

testing#124819

Draft
pavelsavara wants to merge 4 commits intodotnet:mainfrom
pavelsavara:browser_mono_unify_prep
Draft

testing#124819
pavelsavara wants to merge 4 commits intodotnet:mainfrom
pavelsavara:browser_mono_unify_prep

Conversation

@pavelsavara
Copy link
Member

@pavelsavara pavelsavara commented Feb 24, 2026

Unify Mono and CoreCLR JS interop code paths for single-threaded Browser WASM

This PR eliminates the separate Mono-specific code paths in the Browser WASM JS interop layer, aligning Mono with the pattern already used by CoreCLR. This is a step toward running CoreCLR on WASM with a shared managed/JS codebase.

Key changes

Replace Mono internal calls with [LibraryImport] P/Invokes

  • Timer scheduling (TimerQueue.Browser.cs) and thread pool (ThreadPool.Browser.cs) now use [LibraryImport] for both Mono and CoreCLR instead of Mono-only [MethodImpl(MethodImplOptions.InternalCall)].
  • AsyncHelpers.Browser.cs conditionally targets libSystem.Native.Browser (Mono) or QCall (CoreCLR).

Replace mono_wasm_invoke_jsexport with [UnmanagedCallersOnly] entry points

  • Managed exports (CallDelegate, CompleteTask, ReleaseJSOwnedObjectByGCHandle, GetManagedStackTrace, LoadLazyAssembly, LoadSatelliteAssembly, InstallMainSynchronizationContext, BindAssemblyExports) are now called directly as C-exported functions via [UnmanagedCallersOnly(EntryPoint = "...")] rather than looked up by name and dispatched through mono_runtime_invoke.
  • The TypeScript side calls them directly through cwraps instead of via the ManagedExports object + mono_wasm_invoke_jsexport.
  • JavaScriptExports.CoreCLR.cs is renamed to JavaScriptExports.cs (shared) and gains the thread-blocking-mode logic previously only in JavaScriptExports.Mono.cs.

New BrowserHost_ExecuteAssembly for entry point execution

  • Replaces the JS→C#→Mono roundtrip (CallEntrypoint managed export → AssemblyGetEntryPoint icall) with a direct C function BrowserHost_ExecuteAssembly that calls mono_runtime_run_main.
  • Main promise resolution/rejection is handled via SystemJS_ResolveMainPromise / SystemJS_RejectMainPromise exported from managed code.

Separate scheduling concerns

  • The monolithic SystemJS_ScheduleBackgroundJob(cb) / mono_background_exec which multiplexed timer, thread pool, finalization, and diagnostics callbacks is split into four dedicated pairs:
    • SystemJS_ScheduleTimer / SystemJS_ExecuteTimerCallback
    • SystemJS_ScheduleBackgroundJob / SystemJS_ExecuteBackgroundJobCallback
    • SystemJS_ScheduleFinalization / SystemJS_ExecuteFinalizationCallback
    • SystemJS_ScheduleDiagnosticServerJob / SystemJS_ExecuteDiagnosticServerCallback

P/Invoke module registration for Mono

  • WasmApp.Common.targets adds libSystem.Native.Browser and libSystem.Runtime.InteropServices.JavaScript.Native to _WasmPInvokeModules for browser projects.

Deleted code

  • Interop.Runtime.Mono.cs — Mono-specific internal call declarations
  • JSHostImplementation.Mono.cs — Mono-specific BindAssemblyExports / BindManagedFunction via icalls
  • corebindings.cbindings_initialize_internals, SystemInteropJS_AssemblyGetEntryPoint, SystemInteropJS_BindAssemblyExports, SystemInteropJS_GetAssemblyExport
  • driver.cmono_wasm_invoke_jsexport, async/sync JSExport dispatch
  • mono-threads-wasm.cSystemJS_ScheduleBackgroundJob(cb), mono_background_exec, mono_wasm_ds_exec
  • mini-wasm.cSystemJS_ScheduleTimer, mono_wasm_execute_timer, internal call registrations
  • sgen-mono.csgen_client_schedule_background_job

Other improvements

  • mono_wasm_get_method_matching now null-checks the result of mono_get_method before dereferencing.
  • JSHostImplementation.CoreCLR.cs unwraps TargetInvocationException using ExceptionDispatchInfo to preserve original stack traces.
  • Changed ArithmeticException to ArgumentException for assembly binding errors.

Scope

Single-threaded browser only (DISABLE_THREADS). Multi-threaded paths have TODO-WASM: unification markers.

@pavelsavara pavelsavara added this to the 11.0.0 milestone Feb 24, 2026
@pavelsavara pavelsavara self-assigned this Feb 24, 2026
Copilot AI review requested due to automatic review settings February 24, 2026 20:24
@pavelsavara pavelsavara added NO-REVIEW Experimental/testing PR, do NOT review it arch-wasm WebAssembly architecture area-System.Runtime.InteropServices.JavaScript os-browser Browser variant of arch-wasm labels Feb 24, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors Browser/WASM scheduling and JS interop entrypoints, moving away from legacy mono internal-call/reflection-based paths toward LibraryImport/UnmanagedCallersOnly-style exports, and introduces new scheduling hooks for finalization and diagnostic server work.

Changes:

  • Update Browser/WASM scheduling to use idempotent scheduling (SystemJS_Schedule*) and a unified runBackgroundTimers() runner.
  • Restructure JS interop exports/binding to use handle-based JSExport invocation (SystemInteropJS_CallJSExport) and add new native entrypoints (e.g., BrowserHost_ExecuteAssembly).
  • Adjust build/pinvoke module lists and remove older mono-only glue code and declarations.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/native/libs/System.Native.Browser/native/scheduling.ts Makes background/finalization scheduling idempotent (no reschedule/cancel).
src/mono/wasm/build/WasmApp.Common.targets Adds browser-only native modules to the pinvoke module list.
src/mono/mono/utils/mono-threads.h Removes DISABLE_THREADS declarations for background/ds job scheduling.
src/mono/mono/utils/mono-threads-wasm.h Removes DISABLE_THREADS declarations for background/ds exec entrypoints.
src/mono/mono/utils/mono-threads-wasm.c Removes legacy DISABLE_THREADS background/ds job queue/executors.
src/mono/mono/sgen/sgen-client.h Removes sgen_client_schedule_background_job API declaration.
src/mono/mono/mini/mini-wasm.h Removes DISABLE_THREADS JS-import declarations for timers/background jobs.
src/mono/mono/mini/mini-wasm.c Removes legacy DISABLE_THREADS timer/background job wiring and internal calls.
src/mono/mono/metadata/sgen-mono.c Removes HOST_WASM/DISABLE_THREADS background job scheduling shim.
src/mono/mono/metadata/gc.c Switches DISABLE_THREADS wasm finalization notification to SystemJS_ScheduleFinalization.
src/mono/mono/eventpipe/ep-rt-mono.h Adds browser-only ds job scheduling/execute callback declarations for single-threaded queueing.
src/mono/mono/eventpipe/ep-rt-mono.c Implements browser-only ds job scheduling queue and execute callback.
src/mono/browser/runtime/types/internal.ts Adds JSExportHandle and replaces background/ds helpers with runBackgroundTimers.
src/mono/browser/runtime/scheduling.ts Reworks scheduling: unified runBackgroundTimers + new SystemJS_Schedule* APIs.
src/mono/browser/runtime/runtime.h Removes mono_wasm_assembly_find_method export declaration.
src/mono/browser/runtime/runtime.c Removes mono_wasm_assembly_find_method; hardens token-based lookup with null check.
src/mono/browser/runtime/run.ts Changes main execution to call native BrowserHost_ExecuteAssembly and resolve/reject a JS promise via new callbacks.
src/mono/browser/runtime/marshal-to-js.ts Updates comments to remove call_entry_point reference.
src/mono/browser/runtime/managed-exports.ts Removes legacy managed-exports method lookup/async invoke paths; introduces UCO/handle invoke helpers.
src/mono/browser/runtime/loader/exit.ts Formatting + avoids attempting node stream flush outside Node.
src/mono/browser/runtime/invoke-cs.ts Switches bindings to invoke JSExports via JSExportHandle + handle-based call helper.
src/mono/browser/runtime/exports.ts Exposes runBackgroundTimers instead of legacy background/ds exec helpers.
src/mono/browser/runtime/exports-binding.ts Updates the wasm import list to new scheduling + main-promise resolution hooks.
src/mono/browser/runtime/driver.c Removes legacy invoke_jsexport plumbing; adds BrowserHost_ExecuteAssembly.
src/mono/browser/runtime/diagnostics/common.ts Uses runBackgroundTimers during diagnostic server event loop.
src/mono/browser/runtime/cwraps.ts Updates cwrap signatures to new entrypoints and removes old ones.
src/mono/browser/runtime/corebindings.c Removes legacy internal-call registration and export lookup/bind helpers.
src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs Removes legacy managed entrypoint invocation (CallEntrypoint).
src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.Mono.cs Deletes mono-specific BindManagedFunction/BindAssemblyExports implementation.
src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.CoreCLR.cs Improves exception typing + unwraps TargetInvocationException preserving stack.
src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs Adds/extends UnmanagedCallersOnly exports and managed-threads handling in exports.
src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.Mono.cs Adds EntryPoint names for select exports; trims legacy entrypoint/bind exports code.
src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj Switches to unified Interop.Runtime + adjusts included interop/export files.
src/libraries/System.Private.CoreLib/src/System/Threading/TimerQueue.Browser.cs Switches to LibraryImport-based SystemJS_ScheduleTimer for MONO/browser.
src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Browser.cs Switches to LibraryImport-based SystemJS_ScheduleBackgroundJob for MONO/browser.
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.Browser.cs Adds MONO/browser LibraryImport for main-promise resolve/reject hooks.
src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs Removes unused browser interop entrypoint APIs (BindAssemblyExports/GetAssemblyExport/AssemblyGetEntryPoint).
src/libraries/Common/src/Interop/Browser/Interop.Runtime.Mono.cs Deletes mono-specific internal-call declarations for runtime interop.
Comments suppressed due to low confidence (2)

src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs:55

  • In the FEATURE_WASM_MANAGED_THREADS branch, this uses arg_exc but the variable declared in this method is argException. As written this won’t compile; update the reference to use the correct variable when calling AssertCurrentThreadContext().
    src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs:139
  • ctx.ReleasePromiseHolder(arg_1.slot.GCHandle) references arg_1, but this method defines arg1 (and not arg_1). This is a compile-time error; use the correct argument variable when releasing the holder.

pavelsavara and others added 2 commits February 24, 2026 21:33
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 24, 2026 20:35
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-System.Runtime.InteropServices.JavaScript NO-REVIEW Experimental/testing PR, do NOT review it os-browser Browser variant of arch-wasm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant