Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
convert to indexes
  • Loading branch information
pavelsavara committed Aug 8, 2023
commit 5d4de3e0a93fdf29f45615aaad3c80ac00648b60
126 changes: 60 additions & 66 deletions src/mono/wasm/runtime/es6/dotnet.es6.lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,34 +73,63 @@ const postset = `

const DotnetSupportLib = {
$DOTNET: { setup },
$DOTNET__postset: postset
$DOTNET__postset: postset,
icudt68_dat: function () { throw new Error('dummy link symbol') },
};

// the methods would be visible to EMCC linker
// --- keep in sync with exports.ts ---
let linked_functions = [
// the JS methods would be visible to EMCC linker and become imports of the WASM module

#if USE_PTHREADS
// --- keep in sync with exports-linker.ts, order matters! ---
const mono_wasm_threads_imports = [
// mono-threads-wasm.c
"mono_wasm_pthread_on_pthread_attached",
"mono_wasm_pthread_on_pthread_detached",
// threads.c
"mono_wasm_eventloop_has_unsettled_interop_promises",
// diagnostics_server.c
"mono_wasm_diagnostic_server_on_server_thread_created",
"mono_wasm_diagnostic_server_on_runtime_server_init",
"mono_wasm_diagnostic_server_stream_signal_work_available",

// corebindings.c
"mono_wasm_install_js_worker_interop",
"mono_wasm_uninstall_js_worker_interop",
]
#else
const mono_wasm_threads_imports = [];
#endif

// --- keep in sync with exports-linker.ts, order matters! ---
const mono_wasm_legacy_interop_imports = DISABLE_LEGACY_JS_INTEROP ? [] : [
// corebindings.c
"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",
];

// --- keep in sync with exports-linker.ts, order matters! ---
const linked_functions = [
// mini-wasm.c
"mono_wasm_schedule_timer",

// mini-wasm-debugger.c
"mono_wasm_asm_loaded",
"mono_wasm_fire_debugger_agent_message_with_data",
"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",
// mono-threads-wasm.c
"schedule_background_exec",

// interp.c
"mono_wasm_profiler_enter",
"mono_wasm_profiler_leave",

// driver.c
"mono_wasm_trace_logger",
"mono_wasm_event_pipe_early_startup_callback",

// jiterpreter.c / interp.c / transform.c
// interp.c and jiterpreter.c
"mono_interp_tier_prepare_jiterpreter",
"mono_interp_record_interp_entry",
"mono_interp_jit_wasm_entry_trampoline",
Expand All @@ -109,6 +138,14 @@ let linked_functions = [
"mono_interp_flush_jitcall_queue",
"mono_jiterp_do_jit_call_indirect",

"mono_wasm_profiler_enter",
"mono_wasm_profiler_leave",

// driver.c
"mono_wasm_trace_logger",
"mono_wasm_set_entrypoint_breakpoint",
"mono_wasm_event_pipe_early_startup_callback",

// corebindings.c
"mono_wasm_release_cs_owned_object",
"mono_wasm_bind_js_function",
Expand All @@ -127,60 +164,17 @@ let linked_functions = [
"mono_wasm_get_first_day_of_week",
"mono_wasm_get_first_week_of_year",

"icudt68_dat",
...mono_wasm_threads_imports,
...mono_wasm_legacy_interop_imports,
];

#if USE_PTHREADS
linked_functions = [...linked_functions,
// mono-threads-wasm.c
"mono_wasm_pthread_on_pthread_attached",
"mono_wasm_pthread_on_pthread_detached",
// threads.c
"mono_wasm_eventloop_has_unsettled_interop_promises",
// diagnostics_server.c
"mono_wasm_diagnostic_server_on_server_thread_created",
"mono_wasm_diagnostic_server_on_runtime_server_init",
"mono_wasm_diagnostic_server_stream_signal_work_available",
// corebindings.c
"mono_wasm_install_js_worker_interop",
"mono_wasm_uninstall_js_worker_interop",
]
#endif

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",
]
}

if (!DISABLE_LEGACY_JS_INTEROP) {
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",
]
}

// -- this javascript file is evaluated by emcc during compilation! --
// we generate simple proxy for each exported function so that emcc will include them in the final output
// we generate simple stub for each exported function so that emcc will include them in the final output
// we will replace them with the real implementation in replace_linker_placeholders
let idx = 0;
for (let linked_function of linked_functions) {
DotnetSupportLib[linked_function] = new Function('throw new Error("unreachable");');
DotnetSupportLib[linked_function] = new Function(`return {runtime_idx:"${idx}"};//${linked_function}`);
idx++;
}

autoAddDeps(DotnetSupportLib, "$DOTNET");
Expand Down
64 changes: 35 additions & 29 deletions src/mono/wasm/runtime/exports-linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { mono_wasm_asm_loaded } from "./startup";
import { mono_wasm_diagnostic_server_on_server_thread_created } from "./diagnostics/server_pthread";
import { mono_wasm_diagnostic_server_on_runtime_server_init, mono_wasm_event_pipe_early_startup_callback } from "./diagnostics";
import { mono_wasm_diagnostic_server_stream_signal_work_available } from "./diagnostics/server_pthread/stream-queue";
import { mono_log_warn, mono_wasm_trace_logger } from "./logging";
import { mono_log_debug, mono_log_warn, mono_wasm_trace_logger } from "./logging";
import { mono_wasm_profiler_leave, mono_wasm_profiler_enter } from "./profiler";
import { mono_wasm_change_case, mono_wasm_change_case_invariant } from "./hybrid-globalization/change-case";
import { mono_wasm_compare_string, mono_wasm_ends_with, mono_wasm_starts_with, mono_wasm_index_of } from "./hybrid-globalization/collations";
Expand All @@ -35,11 +35,11 @@ import { mono_wasm_typed_array_to_array_ref } from "./net6-legacy/js-to-cs";
import { mono_wasm_typed_array_from_ref } from "./net6-legacy/buffers";
import { mono_wasm_get_culture_info } from "./hybrid-globalization/culture-info";
import { mono_wasm_get_first_day_of_week, mono_wasm_get_first_week_of_year } from "./hybrid-globalization/locales";
import { mono_assert } from "./globals";

// the methods would be visible to EMCC linker
// --- keep in sync with dotnet.cjs.lib.js ---
const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : {
// the JS methods would be visible to EMCC linker and become imports of the WASM module

// --- keep in sync with dotnet.es6.lib.js, order matters! ---
const mono_wasm_threads_imports = !MonoWasmThreads ? [] : [
// mono-threads-wasm.c
mono_wasm_pthread_on_pthread_attached,
mono_wasm_pthread_on_pthread_detached,
Expand All @@ -53,9 +53,10 @@ const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : {
// corebindings.c
mono_wasm_install_js_worker_interop,
mono_wasm_uninstall_js_worker_interop,
};
];

const mono_wasm_legacy_interop_exports = !WasmEnableLegacyJsInterop ? undefined : {
// --- keep in sync with dotnet.es6.lib.js, order matters! ---
const mono_wasm_legacy_interop_imports = !WasmEnableLegacyJsInterop ? [] : [
// corebindings.c
mono_wasm_invoke_js_with_args_ref,
mono_wasm_get_object_property_ref,
Expand All @@ -67,13 +68,11 @@ const mono_wasm_legacy_interop_exports = !WasmEnableLegacyJsInterop ? undefined
mono_wasm_typed_array_to_array_ref,
mono_wasm_typed_array_from_ref,
mono_wasm_invoke_js_blazor,
};
];

// the methods would be visible to EMCC linker
// --- keep in sync with dotnet.cjs.lib.js ---
// --- keep in sync with dotnet.es6.lib.js ---
export function export_linker(): { [key: string]: Function } {
return {
// --- keep in sync with dotnet.es6.lib.js, order matters! ---
export function export_linker(): Function[] {
return [
// mini-wasm.c
mono_wasm_schedule_timer,

Expand Down Expand Up @@ -122,15 +121,15 @@ export function export_linker(): { [key: string]: Function } {
mono_wasm_get_first_week_of_year,

// threading exports, if threading is enabled
...mono_wasm_threads_exports,
...mono_wasm_threads_imports,
// legacy interop exports, if enabled
...mono_wasm_legacy_interop_exports
};
...mono_wasm_legacy_interop_imports
];
}

export function replace_linker_placeholders(
imports: WebAssembly.Imports,
realFunctions: { [key: string]: Function }
realFunctions: Function[],
) {
// the output from emcc contains wrappers for these linker imports which add overhead,
// but now we have what we need to replace them with the actual functions
Expand All @@ -144,20 +143,27 @@ export function replace_linker_placeholders(

// the import names could be minified by applyImportAndExportNameChanges in emcc
// but the stubs are not, so we can use the stub names to find the short names
const nameMap: { [k: string]: string } = {};
const indexToNameMap: string[] = new Array(realFunctions.length);
for (const shortName in env) {
const fn = env[shortName] as Function;
const realName = fn.name;
nameMap[realName] = shortName;
}
if (typeof fn === "function" && fn.toString().indexOf("runtime_idx") !== -1) {
try {
const { runtime_idx } = fn();
indexToNameMap[runtime_idx] = shortName;
} catch {
// no-action
}
}

for (const realName in realFunctions) {
const fn = realFunctions[realName];
mono_assert(typeof (fn) === "function", `Expected ${realName} to be a function`);
const shortName = nameMap["_" + realName];
// if it's not found it means the emcc linker didn't include it, which is fine
if (shortName) {
env[shortName] = fn;
let idx = 0;
for (const fn of realFunctions) {
const shortName = indexToNameMap[idx];
// if it's not found it means the emcc linker didn't include it, which is fine
if (shortName) {
env[shortName] = fn;
mono_log_debug(`Replaced WASM import ${shortName} with ${fn.name}`);
}
idx++;
}
}
}
}