1+ // Licensed to the .NET Foundation under one or more agreements.
2+ // The .NET Foundation licenses this file to you under the MIT license.
3+
4+ import MonoWasmThreads from "consts:monoWasmThreads" ;
5+ import WasmEnableLegacyJsInterop from "consts:wasmEnableLegacyJsInterop" ;
6+
7+ 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" ;
8+ import { mono_wasm_release_cs_owned_object } from "./gc-handles" ;
9+ import { mono_wasm_bind_cs_function } from "./invoke-cs" ;
10+ import { mono_wasm_bind_js_function , mono_wasm_invoke_bound_function , mono_wasm_invoke_import } from "./invoke-js" ;
11+ import { mono_interp_tier_prepare_jiterpreter } from "./jiterpreter" ;
12+ import { mono_interp_jit_wasm_entry_trampoline , mono_interp_record_interp_entry } from "./jiterpreter-interp-entry" ;
13+ import { mono_interp_jit_wasm_jit_call_trampoline , mono_interp_invoke_wasm_jit_call_trampoline , mono_interp_flush_jitcall_queue , mono_jiterp_do_jit_call_indirect } from "./jiterpreter-jit-call" ;
14+ import { mono_wasm_marshal_promise } from "./marshal-to-js" ;
15+ import { mono_wasm_eventloop_has_unsettled_interop_promises } from "./pthreads/shared/eventloop" ;
16+ import { mono_wasm_pthread_on_pthread_attached , mono_wasm_pthread_on_pthread_detached } from "./pthreads/worker" ;
17+ import { mono_wasm_schedule_timer , schedule_background_exec } from "./scheduling" ;
18+ import { mono_wasm_asm_loaded } from "./startup" ;
19+ import { mono_wasm_diagnostic_server_on_server_thread_created } from "./diagnostics/server_pthread" ;
20+ import { mono_wasm_diagnostic_server_on_runtime_server_init , mono_wasm_event_pipe_early_startup_callback } from "./diagnostics" ;
21+ import { mono_wasm_diagnostic_server_stream_signal_work_available } from "./diagnostics/server_pthread/stream-queue" ;
22+ import { mono_log_debug , mono_log_warn , mono_wasm_trace_logger } from "./logging" ;
23+ import { mono_wasm_profiler_leave , mono_wasm_profiler_enter } from "./profiler" ;
24+ import { mono_wasm_change_case , mono_wasm_change_case_invariant } from "./hybrid-globalization/change-case" ;
25+ import { mono_wasm_compare_string , mono_wasm_ends_with , mono_wasm_starts_with , mono_wasm_index_of } from "./hybrid-globalization/collations" ;
26+ import { mono_wasm_get_calendar_info } from "./hybrid-globalization/calendar" ;
27+ import { mono_wasm_install_js_worker_interop , mono_wasm_uninstall_js_worker_interop } from "./pthreads/shared" ;
28+
29+ import {
30+ mono_wasm_invoke_js_blazor , mono_wasm_invoke_js_with_args_ref , mono_wasm_get_object_property_ref , mono_wasm_set_object_property_ref ,
31+ mono_wasm_get_by_index_ref , mono_wasm_set_by_index_ref , mono_wasm_get_global_object_ref
32+ } from "./net6-legacy/method-calls" ;
33+ import { mono_wasm_create_cs_owned_object_ref } from "./net6-legacy/cs-to-js" ;
34+ import { mono_wasm_typed_array_to_array_ref } from "./net6-legacy/js-to-cs" ;
35+ import { mono_wasm_typed_array_from_ref } from "./net6-legacy/buffers" ;
36+ import { mono_wasm_get_culture_info } from "./hybrid-globalization/culture-info" ;
37+ import { mono_wasm_get_first_day_of_week , mono_wasm_get_first_week_of_year } from "./hybrid-globalization/locales" ;
38+
39+ // the JS methods would be visible to EMCC linker and become imports of the WASM module
40+
41+ export const mono_wasm_threads_imports = ! MonoWasmThreads ? [ ] : [
42+ // mono-threads-wasm.c
43+ mono_wasm_pthread_on_pthread_attached ,
44+ mono_wasm_pthread_on_pthread_detached ,
45+ // threads.c
46+ mono_wasm_eventloop_has_unsettled_interop_promises ,
47+ // diagnostics_server.c
48+ mono_wasm_diagnostic_server_on_server_thread_created ,
49+ mono_wasm_diagnostic_server_on_runtime_server_init ,
50+ mono_wasm_diagnostic_server_stream_signal_work_available ,
51+
52+ // corebindings.c
53+ mono_wasm_install_js_worker_interop ,
54+ mono_wasm_uninstall_js_worker_interop ,
55+ ] ;
56+
57+ export const mono_wasm_legacy_interop_imports = ! WasmEnableLegacyJsInterop ? [ ] : [
58+ // corebindings.c
59+ mono_wasm_invoke_js_with_args_ref ,
60+ mono_wasm_get_object_property_ref ,
61+ mono_wasm_set_object_property_ref ,
62+ mono_wasm_get_by_index_ref ,
63+ mono_wasm_set_by_index_ref ,
64+ mono_wasm_get_global_object_ref ,
65+ mono_wasm_create_cs_owned_object_ref ,
66+ mono_wasm_typed_array_to_array_ref ,
67+ mono_wasm_typed_array_from_ref ,
68+ mono_wasm_invoke_js_blazor ,
69+ ] ;
70+
71+ export const mono_wasm_imports = [
72+ // mini-wasm.c
73+ mono_wasm_schedule_timer ,
74+
75+ // mini-wasm-debugger.c
76+ mono_wasm_asm_loaded ,
77+ mono_wasm_debugger_log ,
78+ mono_wasm_add_dbg_command_received ,
79+ mono_wasm_fire_debugger_agent_message_with_data ,
80+ mono_wasm_fire_debugger_agent_message_with_data_to_pause ,
81+ // mono-threads-wasm.c
82+ schedule_background_exec ,
83+
84+ // interp.c and jiterpreter.c
85+ mono_interp_tier_prepare_jiterpreter ,
86+ mono_interp_record_interp_entry ,
87+ mono_interp_jit_wasm_entry_trampoline ,
88+ mono_interp_jit_wasm_jit_call_trampoline ,
89+ mono_interp_invoke_wasm_jit_call_trampoline ,
90+ mono_interp_flush_jitcall_queue ,
91+ mono_jiterp_do_jit_call_indirect ,
92+
93+ mono_wasm_profiler_enter ,
94+ mono_wasm_profiler_leave ,
95+
96+ // driver.c
97+ mono_wasm_trace_logger ,
98+ mono_wasm_set_entrypoint_breakpoint ,
99+ mono_wasm_event_pipe_early_startup_callback ,
100+
101+ // corebindings.c
102+ mono_wasm_release_cs_owned_object ,
103+ mono_wasm_bind_js_function ,
104+ mono_wasm_invoke_bound_function ,
105+ mono_wasm_invoke_import ,
106+ mono_wasm_bind_cs_function ,
107+ mono_wasm_marshal_promise ,
108+ mono_wasm_change_case_invariant ,
109+ mono_wasm_change_case ,
110+ mono_wasm_compare_string ,
111+ mono_wasm_starts_with ,
112+ mono_wasm_ends_with ,
113+ mono_wasm_index_of ,
114+ mono_wasm_get_calendar_info ,
115+ mono_wasm_get_culture_info ,
116+ mono_wasm_get_first_day_of_week ,
117+ mono_wasm_get_first_week_of_year ,
118+ ] ;
119+
120+ const wasmImports : Function [ ] = [
121+ ...mono_wasm_imports ,
122+ // threading exports, if threading is enabled
123+ ...mono_wasm_threads_imports ,
124+ // legacy interop exports, if enabled
125+ ...mono_wasm_legacy_interop_imports
126+ ] ;
127+
128+ export function replace_linker_placeholders ( imports : WebAssembly . Imports ) {
129+ // the output from emcc contains wrappers for these linker imports which add overhead,
130+ // but now we have what we need to replace them with the actual functions
131+ // By default the imports all live inside of 'env', but emscripten minification could rename it to 'a'.
132+ // See https://github.com/emscripten-core/emscripten/blob/c5d1a856592b788619be11bbdc1dd119dec4e24c/src/preamble.js#L933-L936
133+ const env = imports . env || imports . a ;
134+ if ( ! env ) {
135+ mono_log_warn ( "WARNING: Neither imports.env or imports.a were present when instantiating the wasm module. This likely indicates an emscripten configuration issue." ) ;
136+ return ;
137+ }
138+
139+ // the import names could be minified by applyImportAndExportNameChanges in emcc
140+ // we call each stub function to get the runtime_idx, which is the index into the wasmImports array
141+ const indexToNameMap : string [ ] = new Array ( wasmImports . length ) ;
142+ for ( const shortName in env ) {
143+ const stub_fn = env [ shortName ] as Function ;
144+ if ( typeof stub_fn === "function" && stub_fn . toString ( ) . indexOf ( "runtime_idx" ) !== - 1 ) {
145+ try {
146+ const { runtime_idx } = stub_fn ( ) ;
147+ if ( indexToNameMap [ runtime_idx ] !== undefined ) throw new Error ( `Duplicate runtime_idx ${ runtime_idx } ` ) ;
148+ indexToNameMap [ runtime_idx ] = shortName ;
149+ } catch {
150+ // no-action
151+ }
152+ }
153+ }
154+
155+ for ( const [ idx , realFn ] of wasmImports . entries ( ) ) {
156+ const shortName = indexToNameMap [ idx ] ;
157+ // if it's not found it means the emcc linker didn't include it, which is fine
158+ if ( shortName !== undefined ) {
159+ const stubFn = env [ shortName ] ;
160+ if ( typeof stubFn !== "function" ) throw new Error ( `Expected ${ shortName } to be a function` ) ;
161+ env [ shortName ] = realFn ;
162+ mono_log_debug ( `Replaced WASM import ${ shortName } stub ${ stubFn . name } with ${ realFn . name || "minified implementation" } ` ) ;
163+ }
164+ }
165+
166+ }
0 commit comments