diff --git a/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj b/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj index cb112b3b3fa..bf56a93391a 100644 --- a/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj +++ b/src/mono/sample/wasm/browser-eventpipe/Wasm.Browser.EventPipe.Sample.csproj @@ -14,6 +14,7 @@ + + + diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 0bdfe5f0268..1e6dcf1daa5 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -1,17 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import MonoWasmThreads from "consts:monoWasmThreads"; +import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; + import type { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments } from "./types/internal"; import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; -import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; -import { disableLegacyJsInterop, Module } from "./globals"; +import { linkerDisableLegacyJsInterop, linkerEnableAotProfiler, linkerEnableBrowserProfiler, Module } from "./globals"; import { mono_log_error } from "./logging"; -type SigLine = [lazy: boolean, name: string, returnType: string | null, argTypes?: string[], opts?: any]; +type SigLine = [lazyOrSkip: boolean | (() => boolean), name: string, returnType: string | null, argTypes?: string[], opts?: any]; const legacy_interop_cwraps: SigLine[] = WasmEnableLegacyJsInterop ? [ [true, "mono_wasm_array_get_ref", "void", ["number", "number", "number"]], @@ -29,6 +31,17 @@ const legacy_interop_cwraps: SigLine[] = WasmEnableLegacyJsInterop ? [ [true, "mono_wasm_array_length_ref", "number", ["number"]], ] : []; +const diagnostics_cwraps: SigLine[] = MonoWasmThreads ? [ + // MONO.diagnostics + [true, "mono_wasm_event_pipe_enable", "bool", ["string", "number", "number", "string", "bool", "number"]], + [true, "mono_wasm_event_pipe_session_start_streaming", "bool", ["number"]], + [true, "mono_wasm_event_pipe_session_disable", "bool", ["number"]], + [true, "mono_wasm_diagnostic_server_create_thread", "bool", ["string", "number"]], + [true, "mono_wasm_diagnostic_server_thread_attach_to_runtime", "void", []], + [true, "mono_wasm_diagnostic_server_post_resume_runtime", "void", []], + [true, "mono_wasm_diagnostic_server_create_stream", "number", []], +] : []; + // when the method is assigned/cached at usage, instead of being invoked directly from cwraps, it can't be marked lazy, because it would be re-bound on each call const fn_signatures: SigLine[] = [ // MONO @@ -61,22 +74,14 @@ const fn_signatures: SigLine[] = [ [true, "mono_wasm_assembly_get_entry_point", "number", ["number", "number"]], [true, "mono_wasm_class_get_type", "number", ["number"]], - // MONO.diagnostics - [true, "mono_wasm_event_pipe_enable", "bool", ["string", "number", "number", "string", "bool", "number"]], - [true, "mono_wasm_event_pipe_session_start_streaming", "bool", ["number"]], - [true, "mono_wasm_event_pipe_session_disable", "bool", ["number"]], - [true, "mono_wasm_diagnostic_server_create_thread", "bool", ["string", "number"]], - [true, "mono_wasm_diagnostic_server_thread_attach_to_runtime", "void", []], - [true, "mono_wasm_diagnostic_server_post_resume_runtime", "void", []], - [true, "mono_wasm_diagnostic_server_create_stream", "number", []], - //INTERNAL [false, "mono_wasm_exit", "void", ["number"]], [true, "mono_wasm_getenv", "number", ["string"]], [true, "mono_wasm_set_main_args", "void", ["number", "number"]], [false, "mono_wasm_enable_on_demand_gc", "void", ["number"]], // These two need to be lazy because they may be missing - [true, "mono_wasm_profiler_init_aot", "void", ["string"]], + [() => !linkerEnableAotProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]], + [() => !linkerEnableBrowserProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]], [true, "mono_wasm_profiler_init_browser", "void", ["number"]], [false, "mono_wasm_exec_regression", "number", ["number", "string"]], [false, "mono_wasm_invoke_method_bound", "number", ["number", "number", "number"]], @@ -132,6 +137,7 @@ const fn_signatures: SigLine[] = [ [true, "mono_jiterp_get_opcode_info", "number", ["number", "number"]], [true, "mono_wasm_is_zero_page_reserved", "number", []], [true, "mono_jiterp_is_special_interface", "number", ["number"]], + ...diagnostics_cwraps, ...legacy_interop_cwraps ]; @@ -152,6 +158,22 @@ export interface t_LegacyCwraps { mono_wasm_array_length_ref(array: MonoObjectRef): number; } +export interface t_DiagnosticsCwraps { + // MONO.diagnostics + mono_wasm_event_pipe_enable(outputPath: string | null, stream: VoidPtr, bufferSizeInMB: number, providers: string, rundownRequested: boolean, outSessionId: VoidPtr): boolean; + mono_wasm_event_pipe_session_start_streaming(sessionId: number): boolean; + mono_wasm_event_pipe_session_disable(sessionId: number): boolean; + mono_wasm_diagnostic_server_create_thread(websocketURL: string, threadIdOutPtr: VoidPtr): boolean; + mono_wasm_diagnostic_server_thread_attach_to_runtime(): void; + mono_wasm_diagnostic_server_post_resume_runtime(): void; + mono_wasm_diagnostic_server_create_stream(): VoidPtr; +} + +export interface t_ProfilerCwraps { + mono_wasm_profiler_init_aot(desc: string): void; + mono_wasm_profiler_init_browser(desc: string): void; +} + export interface t_Cwraps { // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; @@ -182,23 +204,11 @@ export interface t_Cwraps { mono_wasm_assembly_get_entry_point(assembly: MonoAssembly, idx: number): MonoMethod; mono_wasm_intern_string_ref(strRef: MonoStringRef): void; - - // MONO.diagnostics - mono_wasm_event_pipe_enable(outputPath: string | null, stream: VoidPtr, bufferSizeInMB: number, providers: string, rundownRequested: boolean, outSessionId: VoidPtr): boolean; - mono_wasm_event_pipe_session_start_streaming(sessionId: number): boolean; - mono_wasm_event_pipe_session_disable(sessionId: number): boolean; - mono_wasm_diagnostic_server_create_thread(websocketURL: string, threadIdOutPtr: VoidPtr): boolean; - mono_wasm_diagnostic_server_thread_attach_to_runtime(): void; - mono_wasm_diagnostic_server_post_resume_runtime(): void; - mono_wasm_diagnostic_server_create_stream(): VoidPtr; - //INTERNAL mono_wasm_exit(exit_code: number): number; mono_wasm_getenv(name: string): CharPtr; mono_wasm_enable_on_demand_gc(enable: number): void; mono_wasm_set_main_args(argc: number, argv: VoidPtr): void; - mono_wasm_profiler_init_aot(desc: string): void; - mono_wasm_profiler_init_browser(desc: string): void; mono_wasm_exec_regression(verbose_level: number, image: string): number; mono_wasm_invoke_method_bound(method: MonoMethod, args: JSMarshalerArguments, fail: MonoStringRef): number; mono_wasm_write_managed_pointer_unsafe(destination: VoidPtr | MonoObjectRef, pointer: ManagedPointer): void; @@ -265,6 +275,8 @@ const wrapped_c_functions: t_Cwraps = {}; export default wrapped_c_functions; export const legacy_c_functions: t_LegacyCwraps & t_Cwraps = wrapped_c_functions as any; +export const diagnostics_c_functions: t_DiagnosticsCwraps & t_Cwraps = wrapped_c_functions as any; +export const profiler_c_functions: t_ProfilerCwraps & t_Cwraps = wrapped_c_functions as any; // see src/mono/wasm/driver.c I52_ERROR_xxx export const enum I52Error { @@ -275,7 +287,7 @@ export const enum I52Error { const fastCwrapTypes = ["void", "number", null]; -function cwrap(name: string, returnType: string | null, argTypes: string[] | undefined, opts: any, throwOnError: boolean): Function { +function cwrap(name: string, returnType: string | null, argTypes: string[] | undefined, opts: any): Function { // Attempt to bypass emscripten's generated wrapper if it is safe to do so let fce = // Special cwrap options disable the fast path @@ -301,29 +313,29 @@ function cwrap(name: string, returnType: string | null, argTypes: string[] | und if (typeof (fce) !== "function") { const msg = `cwrap ${name} not found or not a function`; - if (throwOnError) - throw new Error(msg); - else - mono_log_error("" + msg); + throw new Error(msg); } return fce; } export function init_c_exports(): void { - const lfns = WasmEnableLegacyJsInterop && !disableLegacyJsInterop ? legacy_interop_cwraps : []; + const lfns = WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop ? legacy_interop_cwraps : []; const fns = [...fn_signatures, ...lfns]; for (const sig of fns) { const wf: any = wrapped_c_functions; - const [lazy, name, returnType, argTypes, opts] = sig; - if (lazy) { + const [lazyOrSkip, name, returnType, argTypes, opts] = sig; + const maybeSkip = typeof lazyOrSkip === "function"; + if (lazyOrSkip === true || maybeSkip) { // lazy init on first run wf[name] = function (...args: any[]) { - const fce = cwrap(name, returnType, argTypes, opts, true); + const isNotSkipped = !maybeSkip || !lazyOrSkip(); + mono_assert(isNotSkipped, () => `cwrap ${name} should not be called when binding was skipped`); + const fce = cwrap(name, returnType, argTypes, opts); wf[name] = fce; return fce(...args); }; } else { - const fce = cwrap(name, returnType, argTypes, opts, false); + const fce = cwrap(name, returnType, argTypes, opts); wf[name] = fce; } } diff --git a/src/mono/wasm/runtime/diagnostics/browser/controller.ts b/src/mono/wasm/runtime/diagnostics/browser/controller.ts index 3f3c9213c83..91ea014ff89 100644 --- a/src/mono/wasm/runtime/diagnostics/browser/controller.ts +++ b/src/mono/wasm/runtime/diagnostics/browser/controller.ts @@ -1,7 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import cwraps from "../../cwraps"; +import MonoWasmThreads from "consts:monoWasmThreads"; + +import { diagnostics_c_functions as cwraps } from "../../cwraps"; import { INTERNAL } from "../../globals"; import { mono_log_info, mono_log_debug, mono_log_warn } from "../../logging"; import { withStackAlloc, getI32 } from "../../memory"; @@ -52,6 +54,7 @@ export function getController(): ServerController { } export async function startDiagnosticServer(websocket_url: string): Promise { + mono_assert(MonoWasmThreads, "The diagnostic server requires threads to be enabled during build time."); const sizeOfPthreadT = 4; mono_log_info(`starting the diagnostic server url: ${websocket_url}`); const result: number | undefined = withStackAlloc(sizeOfPthreadT, (pthreadIdPtr) => { diff --git a/src/mono/wasm/runtime/diagnostics/index.ts b/src/mono/wasm/runtime/diagnostics/index.ts index 0db99e66fee..ee92751818b 100644 --- a/src/mono/wasm/runtime/diagnostics/index.ts +++ b/src/mono/wasm/runtime/diagnostics/index.ts @@ -41,23 +41,22 @@ export async function mono_wasm_init_diagnostics(): Promise { if (!MonoWasmThreads) { mono_log_warn("ignoring diagnostics options because this runtime does not support diagnostics"); return; - } else { - const options = diagnostic_options_from_environment(); - if (!options) - return; - diagnosticsInitialized = true; - if (!is_nullish(options?.server)) { - if (options.server.connectUrl === undefined || typeof (options.server.connectUrl) !== "string") { - throw new Error("server.connectUrl must be a string"); - } - const url = options.server.connectUrl; - const suspend = boolsyOption(options.server.suspend); - const controller = await startDiagnosticServer(url); - if (controller) { - diagnosticsServerEnabled = true; - if (suspend) { - suspendOnStartup = true; - } + } + const options = diagnostic_options_from_environment(); + if (!options) + return; + diagnosticsInitialized = true; + if (!is_nullish(options?.server)) { + if (options.server.connectUrl === undefined || typeof (options.server.connectUrl) !== "string") { + throw new Error("server.connectUrl must be a string"); + } + const url = options.server.connectUrl; + const suspend = boolsyOption(options.server.suspend); + const controller = await startDiagnosticServer(url); + if (controller) { + diagnosticsServerEnabled = true; + if (suspend) { + suspendOnStartup = true; } } } @@ -144,6 +143,7 @@ function diagnostic_options_from_ports_spec(val: string): DiagnosticOptions | nu } export function mono_wasm_diagnostic_server_on_runtime_server_init(out_options: VoidPtr): void { + mono_assert(MonoWasmThreads, "The diagnostic server requires threads to be enabled during build time."); if (diagnosticsServerEnabled) { /* called on the main thread when the runtime is sufficiently initialized */ const controller = getController(); diff --git a/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts b/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts index df5c92e8431..8bc87ea3763 100644 --- a/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts +++ b/src/mono/wasm/runtime/diagnostics/server_pthread/index.ts @@ -2,12 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. /// - +import MonoWasmThreads from "consts:monoWasmThreads"; import monoDiagnosticsMock from "consts:monoDiagnosticsMock"; + import { PromiseAndController, assertNever } from "../../types/internal"; import { pthread_self } from "../../pthreads/worker"; import { createPromiseController } from "../../globals"; -import cwraps from "../../cwraps"; +import { diagnostics_c_functions as cwraps } from "../../cwraps"; import { EventPipeSessionIDImpl } from "../shared/types"; import { CharPtr } from "../../types/emscripten"; import { @@ -284,6 +285,7 @@ function parseProtocolCommand(data: ArrayBuffer | BinaryProtocolCommand): ParseC /// Called by the runtime to initialize the diagnostic server workers export function mono_wasm_diagnostic_server_on_server_thread_created(websocketUrlPtr: CharPtr): void { + mono_assert(MonoWasmThreads, "The diagnostic server requires threads to be enabled during build time."); const websocketUrl = utf8ToString(websocketUrlPtr); mono_log_debug(`mono_wasm_diagnostic_server_on_server_thread_created, url ${websocketUrl}`); let mock: PromiseAndController | undefined = undefined; diff --git a/src/mono/wasm/runtime/diagnostics/server_pthread/streaming-session.ts b/src/mono/wasm/runtime/diagnostics/server_pthread/streaming-session.ts index 8d7209a9848..88fbc7d3913 100644 --- a/src/mono/wasm/runtime/diagnostics/server_pthread/streaming-session.ts +++ b/src/mono/wasm/runtime/diagnostics/server_pthread/streaming-session.ts @@ -1,13 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { - EventPipeSessionIDImpl -} from "../shared/types"; +import MonoWasmThreads from "consts:monoWasmThreads"; + +import { EventPipeSessionIDImpl } from "../shared/types"; import { EventPipeSocketConnection, takeOverSocket } from "./socket-connection"; import { StreamQueue, allocateQueue } from "./stream-queue"; import type { MockRemoteSocket } from "../mock"; import type { VoidPtr } from "../../types/emscripten"; -import cwraps from "../../cwraps"; +import { diagnostics_c_functions as cwraps } from "../../cwraps"; import { EventPipeCommandCollectTracing2, EventPipeCollectTracingCommandProvider, @@ -24,6 +24,7 @@ export class EventPipeStreamingSession { } export async function makeEventPipeStreamingSession(ws: WebSocket | MockRemoteSocket, cmd: EventPipeCommandCollectTracing2): Promise { + mono_assert(MonoWasmThreads, "The diagnostic server requires threads to be enabled during build time."); // First, create the native IPC stream and get its queue. const ipcStreamAddr = cwraps.mono_wasm_diagnostic_server_create_stream(); // FIXME: this should be a wrapped in a JS object so we can free it when we're done. const queueAddr = getQueueAddrFromStreamAddr(ipcStreamAddr); diff --git a/src/mono/wasm/runtime/diagnostics/shared/create-session.ts b/src/mono/wasm/runtime/diagnostics/shared/create-session.ts index 820a094174e..e6d80d2cb3a 100644 --- a/src/mono/wasm/runtime/diagnostics/shared/create-session.ts +++ b/src/mono/wasm/runtime/diagnostics/shared/create-session.ts @@ -3,7 +3,7 @@ import * as memory from "../../memory"; import { VoidPtr } from "../../types/emscripten"; -import cwraps from "../../cwraps"; +import { diagnostics_c_functions as cwraps } from "../../cwraps"; import type { EventPipeSessionIDImpl } from "./types"; const sizeOfInt32 = 4; diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 66477cc88d8..cea78ac9382 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -7,8 +7,10 @@ // because we can't pass custom define symbols to acorn optimizer, we use environment variables to pass other build options const DISABLE_LEGACY_JS_INTEROP = process.env.DISABLE_LEGACY_JS_INTEROP === "1"; +const ENABLE_BROWSER_PROFILER = process.env.ENABLE_BROWSER_PROFILER === "1"; +const ENABLE_AOT_PROFILER = process.env.ENABLE_AOT_PROFILER === "1"; -function setup(disableLegacyJsInterop) { +function setup(linkerSetup) { const pthreadReplacements = {}; const dotnet_replacements = { fetch: globalThis.fetch, @@ -29,8 +31,8 @@ function setup(disableLegacyJsInterop) { Module.__dotnet_runtime.passEmscriptenInternals({ isPThread: ENVIRONMENT_IS_PTHREAD, - disableLegacyJsInterop, - quit_, ExitStatus + quit_, ExitStatus, + ...linkerSetup }); Module.__dotnet_runtime.initializeReplacements(dotnet_replacements); @@ -58,7 +60,11 @@ function setup(disableLegacyJsInterop) { } const postset = ` - DOTNET.setup(${DISABLE_LEGACY_JS_INTEROP ? "true" : "false"}); + DOTNET.setup({ `+ + `linkerDisableLegacyJsInterop: ${DISABLE_LEGACY_JS_INTEROP ? "true" : "false"},` + + `linkerEnableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` + + `linkerEnableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}` + + `}); `; const DotnetSupportLib = { @@ -131,6 +137,22 @@ linked_functions = [...linked_functions, "mono_wasm_install_js_worker_interop", "mono_wasm_uninstall_js_worker_interop", ] + +if (ENABLE_AOT_PROFILER) { + linked_functions = [...linked_functions, + "mono_wasm_invoke_js_with_args_ref", + "mono_wasm_get_object_property_ref", + "mono_wasm_set_object_property_ref", + "mono_wasm_get_by_index_ref", + "mono_wasm_set_by_index_ref", + "mono_wasm_get_global_object_ref", + "mono_wasm_create_cs_owned_object_ref", + "mono_wasm_typed_array_to_array_ref", + "mono_wasm_typed_array_from_ref", + "mono_wasm_invoke_js_blazor", + ] +} + #endif if (!DISABLE_LEGACY_JS_INTEROP) { linked_functions = [...linked_functions, diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index 66540624866..5653bec9bd6 100644 --- a/src/mono/wasm/runtime/exports-internal.ts +++ b/src/mono/wasm/runtime/exports-internal.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { mono_wasm_cancel_promise } from "./cancelable-promise"; -import cwraps from "./cwraps"; +import cwraps, { profiler_c_functions } from "./cwraps"; import { mono_wasm_send_dbg_command_with_parms, mono_wasm_send_dbg_command, mono_wasm_get_dbg_command_info, mono_wasm_get_details, mono_wasm_release_object, mono_wasm_call_function_on, mono_wasm_debugger_resume, mono_wasm_detach_debugger, mono_wasm_raise_debug_event, mono_wasm_change_debugger_log_level, mono_wasm_debugger_attached } from "./debug"; import { http_wasm_supports_streaming_response, http_wasm_create_abort_controler, http_wasm_abort_request, http_wasm_abort_response, http_wasm_fetch, http_wasm_fetch_bytes, http_wasm_get_response_header_names, http_wasm_get_response_header_values, http_wasm_get_response_bytes, http_wasm_get_response_length, http_wasm_get_streamed_response_bytes } from "./http"; import { exportedRuntimeAPI, Module, runtimeHelpers } from "./globals"; @@ -18,10 +18,6 @@ export function export_internal(): any { return { // tests mono_wasm_exit: (exit_code: number) => { Module.err("early exit " + exit_code); }, - mono_wasm_enable_on_demand_gc: cwraps.mono_wasm_enable_on_demand_gc, - mono_wasm_profiler_init_aot: cwraps.mono_wasm_profiler_init_aot, - mono_wasm_profiler_init_browser: cwraps.mono_wasm_profiler_init_browser, - mono_wasm_exec_regression: cwraps.mono_wasm_exec_regression, // with mono_wasm_debugger_log and mono_wasm_trace_logger logging: undefined, @@ -89,8 +85,8 @@ export function cwraps_internal(internal: any): void { Object.assign(internal, { mono_wasm_exit: cwraps.mono_wasm_exit, mono_wasm_enable_on_demand_gc: cwraps.mono_wasm_enable_on_demand_gc, - mono_wasm_profiler_init_aot: cwraps.mono_wasm_profiler_init_aot, - mono_wasm_profiler_init_browser: cwraps.mono_wasm_profiler_init_browser, + mono_wasm_profiler_init_aot: profiler_c_functions.mono_wasm_profiler_init_aot, + mono_wasm_profiler_init_browser: profiler_c_functions.mono_wasm_profiler_init_browser, mono_wasm_exec_regression: cwraps.mono_wasm_exec_regression, }); } diff --git a/src/mono/wasm/runtime/exports-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index 857c62026ad..440fdda419f 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; +import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; + import { mono_wasm_debugger_log, mono_wasm_add_dbg_command_received, mono_wasm_set_entrypoint_breakpoint, mono_wasm_fire_debugger_agent_message_with_data, mono_wasm_fire_debugger_agent_message_with_data_to_pause } from "./debug"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; import { mono_wasm_bind_cs_function } from "./invoke-cs"; diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 903f835a97a..e3d1bdc5444 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -4,10 +4,10 @@ import ProductVersion from "consts:productVersion"; import GitHash from "consts:gitHash"; import BuildConfiguration from "consts:configuration"; -import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; +import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import type { RuntimeAPI } from "./types"; -import { Module, disableLegacyJsInterop, exportedRuntimeAPI, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; +import { Module, linkerDisableLegacyJsInterop, exportedRuntimeAPI, passEmscriptenInternals, runtimeHelpers, setRuntimeGlobals, } from "./globals"; import { GlobalObjects, is_nullish } from "./types/internal"; import { configureEmscriptenStartup, configureWorkerStartup } from "./startup"; @@ -29,12 +29,12 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { const globals = globalObjects; const globalThisAny = globalThis as any; - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { initializeLegacyExports(globals); } // here we merge methods from the local objects into exported objects - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { Object.assign(globals.mono, export_mono_api()); Object.assign(globals.binding, export_binding_api()); Object.assign(globals.internal, export_internal_api()); @@ -58,7 +58,7 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { }, ...API, }); - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { Object.assign(exportedRuntimeAPI, { MONO: globals.mono, BINDING: globals.binding, @@ -72,7 +72,7 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { if (!module.disableDotnet6Compatibility) { Object.assign(module, exportedRuntimeAPI); - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { // backward compatibility // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/src/mono/wasm/runtime/globals.ts b/src/mono/wasm/runtime/globals.ts index 91b4248b7ca..22fef7474b2 100644 --- a/src/mono/wasm/runtime/globals.ts +++ b/src/mono/wasm/runtime/globals.ts @@ -21,13 +21,17 @@ export let ENVIRONMENT_IS_PTHREAD: boolean; export let exportedRuntimeAPI: RuntimeAPI = null as any; export let runtimeHelpers: RuntimeHelpers = null as any; export let loaderHelpers: LoaderHelpers = null as any; -// this is when we link with workload tools. The consts:WasmEnableLegacyJsInterop is when we compile with rollup. -export let disableLegacyJsInterop = false; +// this is when we link with workload tools. The consts:wasmEnableLegacyJsInterop is when we compile with rollup. +export let linkerDisableLegacyJsInterop = false; +export let linkerEnableAotProfiler = false; +export let linkerEnableBrowserProfiler = false; export let _runtimeModuleLoaded = false; // please keep it in place also as rollup guard export function passEmscriptenInternals(internals: EmscriptenInternals): void { ENVIRONMENT_IS_PTHREAD = internals.isPThread; - disableLegacyJsInterop = internals.disableLegacyJsInterop; + linkerDisableLegacyJsInterop = internals.linkerDisableLegacyJsInterop; + linkerEnableAotProfiler = internals.linkerEnableAotProfiler; + linkerEnableBrowserProfiler = internals.linkerEnableBrowserProfiler; runtimeHelpers.quit = internals.quit_; runtimeHelpers.ExitStatus = internals.ExitStatus; } diff --git a/src/mono/wasm/runtime/profiler.ts b/src/mono/wasm/runtime/profiler.ts index da627b50ec4..a62d0c82792 100644 --- a/src/mono/wasm/runtime/profiler.ts +++ b/src/mono/wasm/runtime/profiler.ts @@ -1,9 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { ENVIRONMENT_IS_WEB, runtimeHelpers } from "./globals"; +import { ENVIRONMENT_IS_WEB, linkerEnableAotProfiler, linkerEnableBrowserProfiler, runtimeHelpers } from "./globals"; import { MonoMethod, AOTProfilerOptions, BrowserProfilerOptions } from "./types/internal"; -import cwraps from "./cwraps"; +import { profiler_c_functions as cwraps } from "./cwraps"; import { utf8ToString } from "./strings"; // Initialize the AOT profiler with OPTIONS. @@ -15,6 +15,7 @@ import { utf8ToString } from "./strings"; // DumpAotProfileData stores the data into INTERNAL.aotProfileData. // export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions): void { + mono_assert(linkerEnableAotProfiler, "AOT profiler is not enabled, please use aot; in your project file."); if (options == null) options = {}; if (!("writeAt" in options)) @@ -26,6 +27,7 @@ export function mono_wasm_init_aot_profiler(options: AOTProfilerOptions): void { } export function mono_wasm_init_browser_profiler(options: BrowserProfilerOptions): void { + mono_assert(linkerEnableBrowserProfiler, "Browser profiler is not enabled, please use browser; in your project file."); if (options == null) options = {}; const arg = "browser:"; @@ -56,8 +58,6 @@ export type TimeStamp = { __brand: "TimeStamp" } - - export function startMeasure(): TimeStamp { if (runtimeHelpers.enablePerfMeasure) { return globalThis.performance.now() as any; diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js index b7181da2180..9d1074488e1 100644 --- a/src/mono/wasm/runtime/rollup.config.js +++ b/src/mono/wasm/runtime/rollup.config.js @@ -16,7 +16,7 @@ const isDebug = configuration !== "Release"; const productVersion = process.env.ProductVersion || "8.0.0-dev"; const nativeBinDir = process.env.NativeBinDir ? process.env.NativeBinDir.replace(/"/g, "") : "bin"; const monoWasmThreads = process.env.MonoWasmThreads === "true" ? true : false; -const WasmEnableLegacyJsInterop = process.env.DISABLE_LEGACY_JS_INTEROP !== "1" ? true : false; +const wasmEnableLegacyJsInterop = process.env.DISABLE_LEGACY_JS_INTEROP !== "1" ? true : false; const monoDiagnosticsMock = process.env.MonoDiagnosticsMock === "true" ? true : false; const terserConfig = { compress: { @@ -71,6 +71,14 @@ try { } catch (e) { gitHash = "unknown"; } +const envConstants = { + productVersion, + configuration, + monoWasmThreads, + monoDiagnosticsMock, + gitHash, + wasmEnableLegacyJsInterop, +}; function consts(dict) { // implement rollup-plugin-const in terms of @rollup/plugin-virtual @@ -94,7 +102,7 @@ const typescriptConfigOptions = { include: ["**/*.ts", "../../../../artifacts/bin/native/generated/**/*.ts"] }; -const outputCodePlugins = [consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock, gitHash, WasmEnableLegacyJsInterop }), typescript(typescriptConfigOptions)]; +const outputCodePlugins = [consts(envConstants), typescript(typescriptConfigOptions)]; const externalDependencies = ["module"]; const loaderConfig = { diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index e9eee44f0de..978bbb55025 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -2,10 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; +import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop"; import { DotnetModuleInternal, CharPtrNull } from "./types/internal"; -import { disableLegacyJsInterop, ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers } from "./globals"; +import { linkerDisableLegacyJsInterop, ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers } from "./globals"; import cwraps, { init_c_exports } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; @@ -327,7 +327,7 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { init_c_exports(); cwraps_internal(INTERNAL); - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { cwraps_mono_api(MONO); cwraps_binding_api(BINDING); } @@ -581,7 +581,7 @@ export function bindings_init(): void { const mark = startMeasure(); strings_init(); init_managed_exports(); - if (WasmEnableLegacyJsInterop && !disableLegacyJsInterop && !ENVIRONMENT_IS_PTHREAD) { + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop && !ENVIRONMENT_IS_PTHREAD) { init_legacy_exports(); } initialize_marshalers_to_js(); diff --git a/src/mono/wasm/runtime/types/internal.ts b/src/mono/wasm/runtime/types/internal.ts index f2dba23fe73..992fea25a25 100644 --- a/src/mono/wasm/runtime/types/internal.ts +++ b/src/mono/wasm/runtime/types/internal.ts @@ -245,7 +245,9 @@ export function is_nullish(value: T | null | undefined): value is null | unde export type EmscriptenInternals = { isPThread: boolean, - disableLegacyJsInterop: boolean, + linkerDisableLegacyJsInterop: boolean, + linkerEnableAotProfiler: boolean, + linkerEnableBrowserProfiler: boolean, quit_: Function, ExitStatus: ExitStatusError, };