diff --git a/src/mono/wasi/build/WasiApp.Native.targets b/src/mono/wasi/build/WasiApp.Native.targets index c4b290bb3d327..95cd07c61d04f 100644 --- a/src/mono/wasi/build/WasiApp.Native.targets +++ b/src/mono/wasi/build/WasiApp.Native.targets @@ -182,7 +182,6 @@ - diff --git a/src/mono/wasi/runtime/CMakeLists.txt b/src/mono/wasi/runtime/CMakeLists.txt index 58d5ecaf0b15d..8f1bc6679c47c 100644 --- a/src/mono/wasi/runtime/CMakeLists.txt +++ b/src/mono/wasi/runtime/CMakeLists.txt @@ -9,7 +9,7 @@ set(CMAKE_EXECUTABLE_SUFFIX ".wasm") add_executable(dotnet driver.c pinvoke.c stubs.c synthetic-pthread.c) target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/include/wasm) -target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/wasi-default.rsp @${NATIVE_BIN_DIR}/src/wasi-compile.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) +target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/wasi-default.rsp @${NATIVE_BIN_DIR}/src/wasi-compile.rsp -DGEN_PINVOKE=1) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_WASICC_FLAGS}) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index ce4c063a5806a..f0f20741ae15c 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -218,7 +218,6 @@ <_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" /> <_EmccCFlags Include="-DENABLE_AOT_PROFILER=1" Condition="$(WasmProfilers.Contains('aot'))" /> <_EmccCFlags Include="-DENABLE_BROWSER_PROFILER=1" Condition="$(WasmProfilers.Contains('browser'))" /> - <_EmccCFlags Include="-DCORE_BINDINGS" /> <_EmccCFlags Include="-DGEN_PINVOKE=1" /> <_EmccCFlags Include="-emit-llvm" /> @@ -258,6 +257,8 @@ + + diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index aa38682595789..8eaecaf217364 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -63,6 +63,7 @@ - $(RunAOTCompilationAfterBuild) - Run AOT compilation even after Build. By default, it is run only for publish. Defaults to false. - $(WasmAotProfilePath) - Path to an AOT profile file. + - $(WasmEnableLegacyJsInterop) - Include support for legacy JS interop. Defaults to true. - $(WasmEnableExceptionHandling) - Enable support for the WASM Exception Handling feature. - $(WasmEnableSIMD) - Enable support for the WASM SIMD feature. - $(WasmEnableWebcil) - Enable conversion of assembly .dlls to .webcil @@ -94,6 +95,7 @@ true false true + true diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 98ed82a16229c..47bda408d7534 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -4,12 +4,13 @@ project(mono-wasm-runtime C) option(DISABLE_THREADS "defined if the build does NOT support multithreading" ON) option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threads to be created in a multithreaded build" OFF) +option(ENABLE_LEGACY_JS_INTEROP "defined if the build supports legacy JavaScript interop" ON) set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(dotnet corebindings.c driver.c pinvoke.c) target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/include/wasm) -target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-compile.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) +target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-compile.rsp -DGEN_PINVOKE=1) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_EMCC_FLAGS}) diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index 38544d0d94894..2428c31962fa3 100644 --- a/src/mono/wasm/runtime/assets.ts +++ b/src/mono/wasm/runtime/assets.ts @@ -5,7 +5,6 @@ import cwraps from "./cwraps"; import { mono_wasm_load_icu_data } from "./icu"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, Module, runtimeHelpers } from "./imports"; import { mono_wasm_load_bytes_into_heap } from "./memory"; -import { MONO } from "./net6-legacy/imports"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; import { createPromiseController, PromiseAndController } from "./promise-controller"; import { delay } from "./promise-utils"; @@ -74,7 +73,7 @@ export function get_preferred_icu_asset(): string | null { return OTHERS; } -export function shouldLoadIcuAsset(asset : AssetEntryInternal, preferredIcuAsset: string | null) : boolean{ +export function shouldLoadIcuAsset(asset: AssetEntryInternal, preferredIcuAsset: string | null): boolean { return !(asset.behavior == "icu" && asset.name != preferredIcuAsset); } @@ -540,12 +539,12 @@ export async function wait_for_all_assets() { if (runtimeHelpers.config.assets) { mono_assert(actual_downloaded_assets_count == expected_downloaded_assets_count, () => `Expected ${expected_downloaded_assets_count} assets to be downloaded, but only finished ${actual_downloaded_assets_count}`); mono_assert(actual_instantiated_assets_count == expected_instantiated_assets_count, () => `Expected ${expected_instantiated_assets_count} assets to be in memory, but only instantiated ${actual_instantiated_assets_count}`); - loaded_files.forEach(value => MONO.loaded_files.push(value.url)); + loaded_files.forEach(value => runtimeHelpers.loadedFiles.push(value.url)); if (runtimeHelpers.diagnosticTracing) console.debug("MONO_WASM: all assets are loaded in wasm memory"); } } // Used by the debugger to enumerate loaded dlls and pdbs export function mono_wasm_get_loaded_files(): string[] { - return MONO.loaded_files; + return runtimeHelpers.loadedFiles; } diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 3eb6016a41089..cb5a57b33ace8 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -17,26 +17,35 @@ #include "gc-common.h" //JS funcs +extern void mono_wasm_release_cs_owned_object (int js_handle); +extern void mono_wasm_bind_js_function(MonoString **function_name, MonoString **module_name, void *signature, int* function_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_invoke_bound_function(int function_js_handle, void *data); +extern void mono_wasm_invoke_import(int fn_handle, void *data); +extern void mono_wasm_bind_cs_function(MonoString **fully_qualified_name, int signature_hash, void* signatures, int *is_exception, MonoObject **result); +extern void mono_wasm_marshal_promise(void *data); + +typedef void (*background_job_cb)(void); +void mono_threads_schedule_background_job (background_job_cb cb); + +#ifdef ENABLE_LEGACY_JS_INTEROP extern void mono_wasm_invoke_js_with_args_ref (int js_handle, MonoString **method, MonoArray **args, int *is_exception, MonoObject **result); extern void mono_wasm_get_object_property_ref (int js_handle, MonoString **propertyName, int *is_exception, MonoObject **result); -extern void mono_wasm_get_by_index_ref (int js_handle, int property_index, int *is_exception, MonoObject **result); extern void mono_wasm_set_object_property_ref (int js_handle, MonoString **propertyName, MonoObject **value, int createIfNotExist, int hasOwnProperty, int *is_exception, MonoObject **result); +extern void mono_wasm_get_by_index_ref (int js_handle, int property_index, int *is_exception, MonoObject **result); extern void mono_wasm_set_by_index_ref (int js_handle, int property_index, MonoObject **value, int *is_exception, MonoObject **result); extern void mono_wasm_get_global_object_ref (MonoString **global_name, int *is_exception, MonoObject **result); -extern void mono_wasm_release_cs_owned_object (int js_handle); -extern void mono_wasm_create_cs_owned_object_ref (MonoString **core_name, MonoArray **args, int *is_exception, MonoObject** result); extern void mono_wasm_typed_array_to_array_ref (int js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_create_cs_owned_object_ref (MonoString **core_name, MonoArray **args, int *is_exception, MonoObject** result); extern void mono_wasm_typed_array_from_ref (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception, MonoObject** result); -extern void mono_wasm_bind_js_function(MonoString **function_name, MonoString **module_name, void *signature, int* function_js_handle, int *is_exception, MonoObject **result); -extern void mono_wasm_invoke_bound_function(int function_js_handle, void *data); -extern void mono_wasm_invoke_import(int fn_handle, void *data); -extern void mono_wasm_bind_cs_function(MonoString **fully_qualified_name, int signature_hash, void* signatures, int *is_exception, MonoObject **result); -extern void mono_wasm_marshal_promise(void *data); +// Blazor specific custom routines - see dotnet_support.js for backing code +extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *callInfo, void* arg0, void* arg1, void* arg2); +#endif /* ENABLE_LEGACY_JS_INTEROP */ - -void core_initialize_internals (void) +void bindings_initialize_internals (void) { + mono_add_internal_call ("System.Runtime.InteropServices.JavaScript.JSSynchronizationContext::ScheduleBackgroundJob", mono_threads_schedule_background_job); + mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); mono_add_internal_call ("Interop/Runtime::BindJSFunction", mono_wasm_bind_js_function); mono_add_internal_call ("Interop/Runtime::InvokeJSFunction", mono_wasm_invoke_bound_function); @@ -45,7 +54,7 @@ void core_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::MarshalPromise", mono_wasm_marshal_promise); mono_add_internal_call ("Interop/Runtime::RegisterGCRoot", mono_wasm_register_root); mono_add_internal_call ("Interop/Runtime::DeregisterGCRoot", mono_wasm_deregister_root); - +#ifdef ENABLE_LEGACY_JS_INTEROP // legacy mono_add_internal_call ("Interop/Runtime::InvokeJSWithArgsRef", mono_wasm_invoke_js_with_args_ref); mono_add_internal_call ("Interop/Runtime::GetObjectPropertyRef", mono_wasm_get_object_property_ref); @@ -56,70 +65,8 @@ void core_initialize_internals (void) mono_add_internal_call ("Interop/Runtime::TypedArrayToArrayRef", mono_wasm_typed_array_to_array_ref); mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); -} - -// Int8Array | int8_t | byte or SByte (signed byte) -// Uint8Array | uint8_t | byte or Byte (unsigned byte) -// Uint8ClampedArray| uint8_t | byte or Byte (unsigned byte) -// Int16Array | int16_t | short (signed short) -// Uint16Array | uint16_t | ushort (unsigned short) -// Int32Array | int32_t | int (signed integer) -// Uint32Array | uint32_t | uint (unsigned integer) -// Float32Array | float | float -// Float64Array | double | double -// typed array marshalling -// Keep in sync with driver.c -#define MARSHAL_ARRAY_BYTE 10 -#define MARSHAL_ARRAY_UBYTE 11 -#define MARSHAL_ARRAY_UBYTE_C 12 // alias of MARSHAL_ARRAY_UBYTE -#define MARSHAL_ARRAY_SHORT 13 -#define MARSHAL_ARRAY_USHORT 14 -#define MARSHAL_ARRAY_INT 15 -#define MARSHAL_ARRAY_UINT 16 -#define MARSHAL_ARRAY_FLOAT 17 -#define MARSHAL_ARRAY_DOUBLE 18 - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, PPVOLATILE(MonoArray) result) -{ - MONO_ENTER_GC_UNSAFE; - MonoClass * typeClass = mono_get_byte_class(); // default is Byte - switch (type) { - case MARSHAL_ARRAY_BYTE: - typeClass = mono_get_sbyte_class(); - break; - case MARSHAL_ARRAY_SHORT: - typeClass = mono_get_int16_class(); - break; - case MARSHAL_ARRAY_USHORT: - typeClass = mono_get_uint16_class(); - break; - case MARSHAL_ARRAY_INT: - typeClass = mono_get_int32_class(); - break; - case MARSHAL_ARRAY_UINT: - typeClass = mono_get_uint32_class(); - break; - case MARSHAL_ARRAY_FLOAT: - typeClass = mono_get_single_class(); - break; - case MARSHAL_ARRAY_DOUBLE: - typeClass = mono_get_double_class(); - break; - case MARSHAL_ARRAY_UBYTE: - case MARSHAL_ARRAY_UBYTE_C: - typeClass = mono_get_byte_class(); - break; - default: - printf ("Invalid marshal type %d in mono_wasm_typed_array_new", type); - abort(); - } - - PVOLATILE(MonoArray) buffer; - - buffer = mono_array_new (mono_get_root_domain(), typeClass, length); - memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); - store_volatile((PPVOLATILE(MonoObject))result, (MonoObject *)buffer); - MONO_EXIT_GC_UNSAFE; + // Blazor specific custom routines - see dotnet_support.js for backing code + mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJS", mono_wasm_invoke_js_blazor); +#endif /* ENABLE_LEGACY_JS_INTEROP */ } diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index f11017b21ef0c..98a073b872608 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; import { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, @@ -11,6 +12,22 @@ import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/ type SigLine = [lazy: 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"]], + [true, "mono_wasm_obj_array_new_ref", "void", ["number", "number"]], + [true, "mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], + [true, "mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], + [true, "mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]], + [true, "mono_wasm_string_array_new_ref", "void", ["number", "number"]], + [true, "mono_wasm_typed_array_new_ref", "void", ["number", "number", "number", "number", "number"]], + [true, "mono_wasm_get_delegate_invoke_ref", "number", ["number"]], + [true, "mono_wasm_get_type_name", "string", ["number"]], + [true, "mono_wasm_get_type_aqn", "string", ["number"]], + [true, "mono_wasm_obj_array_new", "number", ["number"]], + [true, "mono_wasm_obj_array_set", "void", ["number", "number", "number"]], + [true, "mono_wasm_array_length_ref", "number", ["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 @@ -34,31 +51,14 @@ const fn_signatures: SigLine[] = [ // BINDING [true, "mono_wasm_get_corlib", "number", []], [true, "mono_wasm_assembly_load", "number", ["string"]], - [true, "mono_wasm_find_corlib_class", "number", ["string", "string"]], [true, "mono_wasm_assembly_find_class", "number", ["number", "string", "string"]], [true, "mono_wasm_runtime_run_module_cctor", "void", ["number"]], - [true, "mono_wasm_find_corlib_type", "number", ["string", "string"]], - [true, "mono_wasm_assembly_find_type", "number", ["number", "string", "string"]], [true, "mono_wasm_assembly_find_method", "number", ["number", "string", "number"]], [false, "mono_wasm_invoke_method_ref", "void", ["number", "number", "number", "number", "number"]], [true, "mono_wasm_string_from_utf16_ref", "void", ["number", "number", "number"]], - [true, "mono_wasm_array_length_ref", "number", ["number"]], - [true, "mono_wasm_array_get_ref", "void", ["number", "number", "number"]], - [false, "mono_wasm_obj_array_new", "number", ["number"]], - [false, "mono_wasm_obj_array_new_ref", "void", ["number", "number"]], - [false, "mono_wasm_obj_array_set", "void", ["number", "number", "number"]], - [false, "mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], - [true, "mono_wasm_register_bundled_satellite_assemblies", "void", []], - [false, "mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], - [true, "mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]], [true, "mono_wasm_intern_string_ref", "void", ["number"]], [true, "mono_wasm_assembly_get_entry_point", "number", ["number"]], - [true, "mono_wasm_get_delegate_invoke_ref", "number", ["number"]], - [true, "mono_wasm_string_array_new_ref", "void", ["number", "number"]], - [true, "mono_wasm_typed_array_new_ref", "void", ["number", "number", "number", "number", "number"]], [true, "mono_wasm_class_get_type", "number", ["number"]], - [true, "mono_wasm_get_type_name", "string", ["number"]], - [true, "mono_wasm_get_type_aqn", "string", ["number"]], // MONO.diagnostics [true, "mono_wasm_event_pipe_enable", "bool", ["string", "number", "number", "string", "bool", "number"]], @@ -116,8 +116,26 @@ const fn_signatures: SigLine[] = [ [true, "mono_jiterp_debug_count", "number", []], [true, "mono_jiterp_get_trace_hit_count", "number", ["number"]], [true, "mono_jiterp_get_polling_required_address", "number", []], + ...legacy_interop_cwraps ]; +export interface t_LegacyCwraps { + // legacy interop + mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; + mono_wasm_obj_array_new_ref(size: number, result: MonoObjectRef): void; + mono_wasm_obj_array_set_ref(array: MonoObjectRef, idx: number, obj: MonoObjectRef): void; + mono_wasm_try_unbox_primitive_and_get_type_ref(obj: MonoObjectRef, buffer: VoidPtr, buffer_size: number): number; + mono_wasm_box_primitive_ref(klass: MonoClass, value: VoidPtr, value_size: number, result: MonoObjectRef): void; + mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; + mono_wasm_typed_array_new_ref(arr: VoidPtr, length: number, size: number, type: number, result: MonoObjectRef): void; + mono_wasm_get_delegate_invoke_ref(delegate: MonoObjectRef): MonoMethod; + mono_wasm_get_type_name(ty: MonoType): string; + mono_wasm_get_type_aqn(ty: MonoType): string; + mono_wasm_obj_array_new(size: number): MonoArray; + mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; + mono_wasm_array_length_ref(array: MonoObjectRef): number; +} + export interface t_Cwraps { // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; @@ -140,38 +158,14 @@ export interface t_Cwraps { // BINDING mono_wasm_get_corlib(): MonoAssembly; mono_wasm_assembly_load(name: string): MonoAssembly; - mono_wasm_find_corlib_class(namespace: string, name: string): MonoClass; mono_wasm_assembly_find_class(assembly: MonoAssembly, namespace: string, name: string): MonoClass; - mono_wasm_find_corlib_type(namespace: string, name: string): MonoType; - mono_wasm_assembly_find_type(assembly: MonoAssembly, namespace: string, name: string): MonoType; mono_wasm_assembly_find_method(klass: MonoClass, name: string, args: number): MonoMethod; mono_wasm_invoke_method_ref(method: MonoMethod, this_arg: MonoObjectRef, params: VoidPtr, out_exc: MonoObjectRef, out_result: MonoObjectRef): void; mono_wasm_string_from_utf16_ref(str: CharPtr, len: number, result: MonoObjectRef): void; - - mono_wasm_array_length_ref(array: MonoObjectRef): number; - mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; - mono_wasm_obj_array_new_ref(size: number, result: MonoObjectRef): void; - mono_wasm_obj_array_set_ref(array: MonoObjectRef, idx: number, obj: MonoObjectRef): void; - mono_wasm_register_bundled_satellite_assemblies(): void; - mono_wasm_try_unbox_primitive_and_get_type_ref(obj: MonoObjectRef, buffer: VoidPtr, buffer_size: number): number; - mono_wasm_box_primitive_ref(klass: MonoClass, value: VoidPtr, value_size: number, result: MonoObjectRef): void; - mono_wasm_intern_string_ref(strRef: MonoStringRef): void; - mono_wasm_assembly_get_entry_point(assembly: MonoAssembly, idx: number): MonoMethod; - mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; - mono_wasm_typed_array_new_ref(arr: VoidPtr, length: number, size: number, type: number, result: MonoObjectRef): void; mono_wasm_class_get_type(klass: MonoClass): MonoType; - mono_wasm_get_delegate_invoke_ref(delegate: MonoObjectRef): MonoMethod; - mono_wasm_get_type_name(ty: MonoType): string; - mono_wasm_get_type_aqn(ty: MonoType): string; + mono_wasm_assembly_get_entry_point(assembly: MonoAssembly, idx: number): MonoMethod; + mono_wasm_intern_string_ref(strRef: MonoStringRef): void; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_obj_array_new(size: number): MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; // MONO.diagnostics mono_wasm_event_pipe_enable(outputPath: string | null, stream: VoidPtr, bufferSizeInMB: number, providers: string, rundownRequested: boolean, outSessionId: VoidPtr): boolean; @@ -239,6 +233,7 @@ export interface t_Cwraps { 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; // see src/mono/wasm/driver.c I52_ERROR_xxx export const enum I52Error { diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 5c5c8a0ae84f5..f1c4daa9a9ce4 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -39,39 +39,26 @@ #endif #include "gc-common.h" -#ifdef CORE_BINDINGS -void core_initialize_internals (); -#endif - -extern void mono_wasm_set_entrypoint_breakpoint (const char* assembly_name, int method_token); +void bindings_initialize_internals (); -// Blazor specific custom routines - see dotnet_support.js for backing code -extern void* mono_wasm_invoke_js_blazor (MonoString **exceptionMessage, void *callInfo, void* arg0, void* arg1, void* arg2); void mono_wasm_enable_debugging (int); - -static int _marshal_type_from_mono_type (int mono_type, MonoClass *klass, MonoType *type); - -int mono_wasm_register_root (char *start, size_t size, const char *name); -void mono_wasm_deregister_root (char *addr); - void mono_ee_interp_init (const char *opts); void mono_marshal_ilgen_init (void); void mono_method_builder_ilgen_init (void); void mono_sgen_mono_ilgen_init (void); void mono_icall_table_init (void); -void mono_aot_register_module (void **aot_info); char *monoeg_g_getenv(const char *variable); int monoeg_g_setenv(const char *variable, const char *value, int overwrite); -int32_t monoeg_g_hasenv(const char *variable); -void mono_free (void*); int32_t mini_parse_debug_option (const char *option); char *mono_method_get_full_name (MonoMethod *method); -char *mono_method_full_name (MonoMethod *method, int signature); -extern void mono_wasm_register_timezones_bundle(); +extern void mono_wasm_register_timezones_bundle(); +extern void mono_wasm_set_entrypoint_breakpoint (const char* assembly_name, int method_token); static void mono_wasm_init_finalizer_thread (void); +#ifdef ENABLE_LEGACY_JS_INTEROP + #define MARSHAL_TYPE_NULL 0 #define MARSHAL_TYPE_INT 1 #define MARSHAL_TYPE_FP64 2 @@ -126,6 +113,8 @@ static int resolved_datetime_class = 0, resolved_safehandle_class = 0, resolved_voidtaskresult_class = 0; +#endif /* ENABLE_LEGACY_JS_INTEROP */ + int mono_wasm_enable_gc = 1; /* Not part of public headers */ @@ -442,22 +431,7 @@ get_native_to_interp (MonoMethod *method, void *extra_arg) return addr; } -typedef void (*background_job_cb)(void); -void mono_threads_schedule_background_job (background_job_cb cb); - -void mono_initialize_internals (void) -{ - // Blazor specific custom routines - see dotnet_support.js for backing code - mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJS", mono_wasm_invoke_js_blazor); - -#ifdef CORE_BINDINGS - core_initialize_internals(); -#endif - - mono_add_internal_call ("System.Runtime.InteropServices.JavaScript.JSSynchronizationContext::ScheduleBackgroundJob", mono_threads_schedule_background_job); -} - -EMSCRIPTEN_KEEPALIVE void +void mono_wasm_register_bundled_satellite_assemblies (void) { /* In legacy satellite_assembly_count is always false */ @@ -612,7 +586,7 @@ mono_wasm_load_runtime (const char *unused, int debug_level) mono_trace_set_log_handler (wasm_trace_logger, NULL); root_domain = mono_jit_init_version ("mono", NULL); - mono_initialize_internals(); + bindings_initialize_internals(); mono_thread_set_main (mono_thread_current ()); @@ -682,32 +656,6 @@ mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int argument return result; } -EMSCRIPTEN_KEEPALIVE MonoMethod* -mono_wasm_get_delegate_invoke_ref (MonoObject **delegate) -{ - MonoMethod * result; - MONO_ENTER_GC_UNSAFE; - result = mono_get_delegate_invoke(mono_object_get_class (*delegate)); - MONO_EXIT_GC_UNSAFE; - return result; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_box_primitive_ref (MonoClass *klass, void *value, int value_size, PPVOLATILE(MonoObject) result) -{ - assert (klass); - - MONO_ENTER_GC_UNSAFE; - MonoType *type = mono_class_get_type (klass); - int alignment; - - if (mono_type_size (type, &alignment) <= value_size) - // TODO: use mono_value_box_checked and propagate error out - store_volatile(result, mono_value_box (root_domain, klass, value)); - - MONO_EXIT_GC_UNSAFE; -} - EMSCRIPTEN_KEEPALIVE void mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **_out_exc, MonoObject **out_result) { @@ -833,6 +781,8 @@ mono_wasm_string_from_utf16_ref (const mono_unichar2 * chars, int length, MonoSt MONO_EXIT_GC_UNSAFE; } +#ifdef ENABLE_LEGACY_JS_INTEROP + static int class_is_task (MonoClass *klass) { @@ -981,6 +931,87 @@ _marshal_type_from_mono_type (int mono_type, MonoClass *klass, MonoType *type) } } +EMSCRIPTEN_KEEPALIVE void +mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, PPVOLATILE(MonoArray) result) +{ + MONO_ENTER_GC_UNSAFE; + MonoClass * typeClass = mono_get_byte_class(); // default is Byte + switch (type) { + case MARSHAL_ARRAY_BYTE: + typeClass = mono_get_sbyte_class(); + break; + case MARSHAL_ARRAY_SHORT: + typeClass = mono_get_int16_class(); + break; + case MARSHAL_ARRAY_USHORT: + typeClass = mono_get_uint16_class(); + break; + case MARSHAL_ARRAY_INT: + typeClass = mono_get_int32_class(); + break; + case MARSHAL_ARRAY_UINT: + typeClass = mono_get_uint32_class(); + break; + case MARSHAL_ARRAY_FLOAT: + typeClass = mono_get_single_class(); + break; + case MARSHAL_ARRAY_DOUBLE: + typeClass = mono_get_double_class(); + break; + case MARSHAL_ARRAY_UBYTE: + case MARSHAL_ARRAY_UBYTE_C: + typeClass = mono_get_byte_class(); + break; + default: + printf ("Invalid marshal type %d in mono_wasm_typed_array_new", type); + abort(); + } + + PVOLATILE(MonoArray) buffer; + + buffer = mono_array_new (mono_get_root_domain(), typeClass, length); + memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); + + store_volatile((PPVOLATILE(MonoObject))result, (MonoObject *)buffer); + MONO_EXIT_GC_UNSAFE; +} + +EMSCRIPTEN_KEEPALIVE MonoMethod* +mono_wasm_get_delegate_invoke_ref (MonoObject **delegate) +{ + MonoMethod * result; + MONO_ENTER_GC_UNSAFE; + result = mono_get_delegate_invoke(mono_object_get_class (*delegate)); + MONO_EXIT_GC_UNSAFE; + return result; +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_box_primitive_ref (MonoClass *klass, void *value, int value_size, PPVOLATILE(MonoObject) result) +{ + assert (klass); + + MONO_ENTER_GC_UNSAFE; + MonoType *type = mono_class_get_type (klass); + int alignment; + + if (mono_type_size (type, &alignment) <= value_size) + // TODO: use mono_value_box_checked and propagate error out + store_volatile(result, mono_value_box (root_domain, klass, value)); + + MONO_EXIT_GC_UNSAFE; +} + +EMSCRIPTEN_KEEPALIVE char * +mono_wasm_get_type_name (MonoType * typePtr) { + return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_REFLECTION); +} + +EMSCRIPTEN_KEEPALIVE char * +mono_wasm_get_type_aqn (MonoType * typePtr) { + return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED); +} + // This code runs inside a gc unsafe region static int _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (PVOLATILE(MonoObject) obj, void *result, int result_capacity) { @@ -1184,6 +1215,8 @@ mono_wasm_string_array_new_ref (int size, MonoArray **result) MONO_EXIT_GC_UNSAFE; } +#endif /* ENABLE_LEGACY_JS_INTEROP */ + EMSCRIPTEN_KEEPALIVE int mono_wasm_exec_regression (int verbose_level, char *image) { @@ -1264,16 +1297,6 @@ mono_wasm_class_get_type (MonoClass *klass) return result; } -EMSCRIPTEN_KEEPALIVE char * -mono_wasm_get_type_name (MonoType * typePtr) { - return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_REFLECTION); -} - -EMSCRIPTEN_KEEPALIVE char * -mono_wasm_get_type_aqn (MonoType * typePtr) { - return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED); -} - EMSCRIPTEN_KEEPALIVE void mono_wasm_write_managed_pointer_unsafe (PPVOLATILE(MonoObject) destination, PVOLATILE(MonoObject) source) { store_volatile(destination, source); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 281cc1c5a77e0..3669e0349d2d8 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -4,13 +4,9 @@ "use strict"; -#if USE_PTHREADS -const usePThreads = true; -const isPThread = `ENVIRONMENT_IS_PTHREAD`; -#else -const usePThreads = false; -const isPThread = `false`; -#endif +const monoWasmThreads = process.env.MonoWasmThreads == "true"; +const WasmEnableLegacyJsInterop = process.env.WasmEnableLegacyJsInterop === "true"; +const isPThread = monoWasmThreads ? "ENVIRONMENT_IS_PTHREAD" : "false"; const DotnetSupportLib = { $DOTNET: {}, @@ -22,8 +18,8 @@ const DotnetSupportLib = { // Emscripten's getBinaryPromise is not async for NodeJs, but we would like to have it async, so we replace it. // We also replace implementation of fetch $DOTNET__postset: ` -let __dotnet_replacement_PThread = ${usePThreads} ? {} : undefined; -${usePThreads ? ` +let __dotnet_replacement_PThread = ${monoWasmThreads} ? {} : undefined; +${monoWasmThreads ? ` __dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker; __dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS; __dotnet_replacement_PThread.allocateUnusedWorker = PThread.allocateUnusedWorker; @@ -45,7 +41,7 @@ if (ENVIRONMENT_IS_NODE) { }); } var noExitRuntime = __dotnet_replacements.noExitRuntime; -${usePThreads ? ` +${monoWasmThreads ? ` PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker; PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTLS; PThread.allocateUnusedWorker = __dotnet_replacements.pthreadReplacements.allocateUnusedWorker; @@ -55,7 +51,7 @@ PThread.allocateUnusedWorker = __dotnet_replacements.pthreadReplacements.allocat // the methods would be visible to EMCC linker // --- keep in sync with exports.ts --- -const linked_functions = [ +let linked_functions = [ // mini-wasm.c "mono_set_timeout", @@ -74,7 +70,6 @@ const linked_functions = [ "mono_wasm_profiler_leave", // driver.c - "mono_wasm_invoke_js_blazor", "mono_wasm_trace_logger", "mono_wasm_event_pipe_early_startup_callback", @@ -88,16 +83,7 @@ const linked_functions = [ "mono_jiterp_do_jit_call_indirect", // 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_release_cs_owned_object", - "mono_wasm_typed_array_to_array_ref", - "mono_wasm_typed_array_from_ref", "mono_wasm_bind_js_function", "mono_wasm_invoke_bound_function", "mono_wasm_invoke_import", @@ -106,17 +92,33 @@ const linked_functions = [ // pal_icushim_static.c "mono_wasm_load_icu_data", - - #if USE_PTHREADS - /// mono-threads-wasm.c - "mono_wasm_pthread_on_pthread_attached", - // 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", - #endif ]; +if (monoWasmThreads) { + linked_functions = [...linked_functions, + /// mono-threads-wasm.c + "mono_wasm_pthread_on_pthread_attached", + // 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", + ] +} +if (WasmEnableLegacyJsInterop) { + 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 for (let linked_function of linked_functions) { diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index 74285acc2dfce..519d0917c5260 100644 --- a/src/mono/wasm/runtime/exports-internal.ts +++ b/src/mono/wasm/runtime/exports-internal.ts @@ -7,7 +7,6 @@ import { mono_wasm_send_dbg_command_with_parms, mono_wasm_send_dbg_command, mono 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 "./imports"; import { get_property, set_property, has_property, get_typeof_property, get_global_this, dynamic_import } from "./invoke-js"; -import { mono_method_resolve } from "./net6-legacy/method-binding"; import { mono_intern_string } from "./strings"; import { mono_wasm_stringify_as_error_with_stack } from "./logging"; import { ws_wasm_create, ws_wasm_open, ws_wasm_send, ws_wasm_receive, ws_wasm_close, ws_wasm_abort } from "./web-socket"; @@ -24,7 +23,6 @@ export function export_internal(): any { 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, - mono_method_resolve,//MarshalTests.cs mono_intern_string,// MarshalTests.cs // with mono_wasm_debugger_log and mono_wasm_trace_logger diff --git a/src/mono/wasm/runtime/exports-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index 6c1c0c844b183..dbfa140f47c3b 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import { mono_wasm_fire_debugger_agent_message_with_data, mono_wasm_fire_debugger_agent_message_with_data_to_pause, mono_wasm_debugger_log, mono_wasm_add_dbg_command_received, mono_wasm_set_entrypoint_breakpoint } from "./debug"; - +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_load_icu_data } from "./icu"; import { mono_wasm_bind_cs_function } from "./invoke-cs"; @@ -11,11 +11,6 @@ import { mono_wasm_bind_js_function, mono_wasm_invoke_bound_function, mono_wasm_ import { mono_interp_tier_prepare_jiterpreter } from "./jiterpreter"; import { mono_interp_jit_wasm_entry_trampoline, mono_interp_record_interp_entry } from "./jiterpreter-interp-entry"; 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"; -import { mono_wasm_typed_array_from_ref } from "./net6-legacy/buffers"; -import { - mono_wasm_invoke_js_blazor, 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 -} from "./net6-legacy/method-calls"; import { mono_wasm_marshal_promise } from "./marshal-to-js"; import { mono_wasm_pthread_on_pthread_attached } from "./pthreads/worker"; import { mono_set_timeout, schedule_background_exec } from "./scheduling"; @@ -23,10 +18,15 @@ 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_wasm_create_cs_owned_object_ref } from "./net6-legacy/cs-to-js"; -import { mono_wasm_typed_array_to_array_ref } from "./net6-legacy/js-to-cs"; import { mono_wasm_trace_logger } from "./logging"; import { mono_wasm_profiler_leave, mono_wasm_profiler_enter } from "./profiler"; +import { mono_wasm_create_cs_owned_object_ref } from "./net6-legacy/cs-to-js"; +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_invoke_js_blazor, 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 +} from "./net6-legacy/method-calls"; // the methods would be visible to EMCC linker // --- keep in sync with dotnet.cjs.lib.js --- @@ -39,6 +39,20 @@ const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : { mono_wasm_diagnostic_server_stream_signal_work_available, }; +const mono_wasm_legacy_interop_exports = !WasmEnableLegacyJsInterop ? undefined : { + // 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, +}; + // the methods would be visible to EMCC linker // --- keep in sync with dotnet.cjs.lib.js --- // --- keep in sync with dotnet.es6.lib.js --- @@ -69,22 +83,12 @@ export function export_linker(): any { mono_wasm_profiler_leave, // driver.c - mono_wasm_invoke_js_blazor, mono_wasm_trace_logger, mono_wasm_set_entrypoint_breakpoint, mono_wasm_event_pipe_early_startup_callback, // 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_release_cs_owned_object, - mono_wasm_typed_array_to_array_ref, - mono_wasm_typed_array_from_ref, mono_wasm_bind_js_function, mono_wasm_invoke_bound_function, mono_wasm_invoke_import, @@ -96,5 +100,7 @@ export function export_linker(): any { // threading exports, if threading is enabled ...mono_wasm_threads_exports, + // legacy interop exports, if enabled + ...mono_wasm_legacy_interop_exports }; } diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 692c800035bc0..9a6e2ec5e5294 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -5,18 +5,21 @@ import ProductVersion from "consts:productVersion"; import GitHash from "consts:gitHash"; import MonoWasmThreads from "consts:monoWasmThreads"; import BuildConfiguration from "consts:configuration"; +import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; import { ENVIRONMENT_IS_PTHREAD, exportedRuntimeAPI, moduleExports, set_emscripten_entrypoint, set_imports_exports } from "./imports"; import { DotnetModule, is_nullish, EarlyImports, EarlyExports, EarlyReplacements, RuntimeAPI, CreateDotnetRuntimeType } from "./types"; import { configure_emscripten_startup, mono_wasm_pthread_worker_init } from "./startup"; -import { mono_bind_static_method } from "./net6-legacy/method-calls"; import { create_weak_ref } from "./weak-ref"; -import { export_binding_api, export_mono_api } from "./net6-legacy/exports-legacy"; import { export_internal } from "./exports-internal"; import { export_linker } from "./exports-linker"; import { init_polyfills } from "./polyfills"; import { export_api, export_module } from "./export-api"; + +// legacy +import { mono_bind_static_method } from "./net6-legacy/method-calls"; +import { export_binding_api, export_internal_api, export_mono_api } from "./net6-legacy/exports-legacy"; import { set_legacy_exports } from "./net6-legacy/imports"; const __initializeImportsAndExports: any = initializeImportsAndExports; // don't want to export the type @@ -39,18 +42,21 @@ function initializeImportsAndExports( // we want to have same instance of MONO, BINDING and Module in dotnet iife set_imports_exports(imports, exports); - set_legacy_exports(exports); + if (WasmEnableLegacyJsInterop) { + set_legacy_exports(exports); + } init_polyfills(replacements); // here we merge methods from the local objects into exported objects - Object.assign(exports.mono, export_mono_api()); - Object.assign(exports.binding, export_binding_api()); + if (WasmEnableLegacyJsInterop) { + Object.assign(exports.mono, export_mono_api()); + Object.assign(exports.binding, export_binding_api()); + Object.assign(exports.internal, export_internal_api()); + } Object.assign(exports.internal, export_internal()); const API = export_api(); __linker_exports = export_linker(); Object.assign(exportedRuntimeAPI, { - MONO: exports.mono, - BINDING: exports.binding, INTERNAL: exports.internal, IMPORTS: exports.marshaled_imports, Module: module, @@ -61,6 +67,13 @@ function initializeImportsAndExports( }, ...API, }); + if (WasmEnableLegacyJsInterop) { + Object.assign(exportedRuntimeAPI, { + MONO: exports.mono, + BINDING: exports.binding, + }); + } + Object.assign(callbackAPI, API); if (exports.module.__undefinedConfig) { module.disableDotnet6Compatibility = true; @@ -81,13 +94,15 @@ function initializeImportsAndExports( if (imports.isGlobal || !module.disableDotnet6Compatibility) { Object.assign(module, exportedRuntimeAPI); - // backward compatibility - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - module.mono_bind_static_method = (fqn: string, signature: string/*ArgsMarshalString*/): Function => { - console.warn("MONO_WASM: Module.mono_bind_static_method is obsolete, please use [JSExportAttribute] interop instead"); - return mono_bind_static_method(fqn, signature); - }; + if (WasmEnableLegacyJsInterop) { + // backward compatibility + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + module.mono_bind_static_method = (fqn: string, signature: string/*ArgsMarshalString*/): Function => { + console.warn("MONO_WASM: Module.mono_bind_static_method is obsolete, please use [JSExportAttribute] interop instead"); + return mono_bind_static_method(fqn, signature); + }; + } const warnWrap = (name: string, provider: () => any) => { if (typeof globalThisAny[name] !== "undefined") { diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts index 1a7af3d7a7c9b..d341f36818600 100644 --- a/src/mono/wasm/runtime/imports.ts +++ b/src/mono/wasm/runtime/imports.ts @@ -5,8 +5,8 @@ /// /// -import { CreateDotnetRuntimeType, DotnetModule, RuntimeAPI, EarlyExports, EarlyImports, ModuleAPI, RuntimeHelpers } from "./types"; -import { EmscriptenModule } from "./types/emscripten"; +import type { CreateDotnetRuntimeType, DotnetModule, RuntimeAPI, EarlyExports, EarlyImports, ModuleAPI, RuntimeHelpers } from "./types"; +import type { EmscriptenModule } from "./types/emscripten"; // these are our public API (except internal) export let Module: EmscriptenModule & DotnetModule; @@ -60,5 +60,6 @@ const initialRuntimeHelpers: Partial = }, diagnosticTracing: false, enablePerfMeasure: true, + loadedFiles: [] }; export const runtimeHelpers: RuntimeHelpers = initialRuntimeHelpers as any; diff --git a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts index 515c261445cd6..c19744f11c350 100644 --- a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts +++ b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { _are_promises_supported } from "../cancelable-promise"; -import cwraps from "../cwraps"; +import { legacy_c_functions as cwraps } from "../cwraps"; import { mono_wasm_get_jsobj_from_js_handle, _lookup_js_owned_object, setup_managed_proxy, mono_wasm_get_js_handle, teardown_managed_proxy, assert_not_disposed } from "../gc-handles"; import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; import { ManagedObject } from "../marshal"; diff --git a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts index 725d0c5eeee56..3e93287282e8a 100644 --- a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts +++ b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts @@ -1,7 +1,7 @@ // 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 { legacy_c_functions as cwraps } from "../cwraps"; import { mono_wasm_runtime_ready } from "../debug"; import { mono_wasm_load_icu_data } from "../icu"; import { runtimeHelpers } from "../imports"; @@ -16,6 +16,7 @@ import { mono_bind_static_method, mono_call_assembly_entry_point } from "./metho import { mono_wasm_load_runtime } from "../startup"; import { BINDINGType, MONOType } from "./export-types"; import { mono_wasm_load_data_archive } from "../assets"; +import { mono_method_resolve } from "./method-binding"; export function export_mono_api(): MONOType { return { @@ -74,6 +75,12 @@ export function cwraps_mono_api(mono: MONOType): void { }); } +export function export_internal_api(): any { + return { + mono_method_resolve,//MarshalTests.cs + }; +} + export function export_binding_api(): BINDINGType { return { // legacy BINDING API diff --git a/src/mono/wasm/runtime/net6-legacy/imports.ts b/src/mono/wasm/runtime/net6-legacy/imports.ts index 3cbd03463ecf0..d62ebf7806e7d 100644 --- a/src/mono/wasm/runtime/net6-legacy/imports.ts +++ b/src/mono/wasm/runtime/net6-legacy/imports.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 { EarlyExports, MonoClass } from "../types"; -import { VoidPtr } from "../types/emscripten"; -import { BINDINGType, MONOType } from "./export-types"; +import type { EarlyExports, MonoClass } from "../types"; +import type { VoidPtr } from "../types/emscripten"; +import type { BINDINGType, MONOType } from "./export-types"; export let MONO: MONOType; export let BINDING: BINDINGType; diff --git a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts index 48b9125eb1bf6..2ccf51d09759b 100644 --- a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts +++ b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { isThenable } from "../cancelable-promise"; -import cwraps from "../cwraps"; +import { legacy_c_functions as cwraps } from "../cwraps"; import { js_owned_gc_handle_symbol, assert_not_disposed, cs_owned_js_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, mono_wasm_release_cs_owned_object, teardown_managed_proxy, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles"; import { Module } from "../imports"; import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; diff --git a/src/mono/wasm/runtime/net6-legacy/method-binding.ts b/src/mono/wasm/runtime/net6-legacy/method-binding.ts index b1e7ed491d72a..2eefa077fa2c5 100644 --- a/src/mono/wasm/runtime/net6-legacy/method-binding.ts +++ b/src/mono/wasm/runtime/net6-legacy/method-binding.ts @@ -1,7 +1,7 @@ // 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 { legacy_c_functions as cwraps } from "../cwraps"; import { Module } from "../imports"; import { parseFQN } from "../invoke-cs"; import { setI32, setU32, setF32, setF64, setU52, setI52, setB32, setI32_unchecked, setU32_unchecked, _zero_region, _create_temp_frame, getB32, getI32, getU32, getF32, getF64 } from "../memory"; diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js index d9b5269977274..6d7b77906f17c 100644 --- a/src/mono/wasm/runtime/rollup.config.js +++ b/src/mono/wasm/runtime/rollup.config.js @@ -16,6 +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.WasmEnableLegacyJsInterop !== "false" ? true : false; const monoDiagnosticsMock = process.env.MonoDiagnosticsMock === "true" ? true : false; const terserConfig = { compress: { @@ -84,7 +85,7 @@ const typescriptConfigOptions = { include: ["**/*.ts", "../../../../artifacts/bin/native/generated/**/*.ts"] }; -const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock, gitHash }), typescript(typescriptConfigOptions)]; +const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock, gitHash, WasmEnableLegacyJsInterop }), typescript(typescriptConfigOptions)]; const externalDependencies = [ ]; diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 8f5f30a4b1f2e..d554fae7c6388 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -3,6 +3,7 @@ import BuildConfiguration from "consts:configuration"; import MonoWasmThreads from "consts:monoWasmThreads"; +import WasmEnableLegacyJsInterop from "consts:WasmEnableLegacyJsInterop"; import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigInternal } from "./types"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, Module, runtimeHelpers } from "./imports"; import cwraps, { init_c_exports } from "./cwraps"; @@ -18,18 +19,20 @@ import * as pthreads_worker from "./pthreads/worker"; import { createPromiseController } from "./promise-controller"; import { string_decoder } from "./strings"; import { init_managed_exports } from "./managed-exports"; -import { init_legacy_exports } from "./net6-legacy/corebindings"; import { cwraps_internal } from "./exports-internal"; -import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy"; import { CharPtr, InstantiateWasmCallBack, InstantiateWasmSuccessCallback } from "./types/emscripten"; import { instantiate_wasm_asset, mono_download_assets, resolve_asset_path, start_asset_download, wait_for_all_assets } from "./assets"; -import { BINDING, MONO } from "./net6-legacy/imports"; import { readSymbolMapFile } from "./logging"; import { mono_wasm_init_diagnostics } from "./diagnostics"; import { preAllocatePThreadWorkerPool, instantiateWasmPThreadWorkerPool } from "./pthreads/browser"; import { export_linker } from "./exports-linker"; import { endMeasure, MeasuredBlock, startMeasure } from "./profiler"; +// legacy +import { init_legacy_exports } from "./net6-legacy/corebindings"; +import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy"; +import { BINDING, MONO } from "./net6-legacy/imports"; + let config: MonoConfigInternal = undefined as any; let configLoaded = false; export const dotnetReady = createPromiseController(); @@ -302,9 +305,10 @@ function mono_wasm_pre_init_essential(isWorker: boolean): void { // init_polyfills() is already called from export.ts init_c_exports(); cwraps_internal(INTERNAL); - cwraps_mono_api(MONO); - cwraps_binding_api(BINDING); - + if (WasmEnableLegacyJsInterop) { + cwraps_mono_api(MONO); + cwraps_binding_api(BINDING); + } // removeRunDependency triggers the dependenciesFulfilled callback (runCaller) in // emscripten - on a worker since we don't have any other dependencies that causes run() to get // called too soon; and then it will get called a second time when dotnet.js calls it directly. @@ -556,7 +560,9 @@ export function bindings_init(): void { try { const mark = startMeasure(); init_managed_exports(); - init_legacy_exports(); + if (WasmEnableLegacyJsInterop) { + init_legacy_exports(); + } initialize_marshalers_to_js(); initialize_marshalers_to_cs(); runtimeHelpers._i52_error_scratch_buffer = Module._malloc(4); diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index 1de2fc6998912..7a1b333e2bc75 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -224,6 +224,7 @@ export type RuntimeHelpers = { quit: Function, locateFile: (path: string, prefix?: string) => string, javaScriptExports: JavaScriptExports, + loadedFiles: string[], } export type GlobalizationMode = diff --git a/src/mono/wasm/runtime/wasm-config.h.in b/src/mono/wasm/runtime/wasm-config.h.in index c5650ed200b45..7ca162a30ce83 100644 --- a/src/mono/wasm/runtime/wasm-config.h.in +++ b/src/mono/wasm/runtime/wasm-config.h.in @@ -10,4 +10,7 @@ /* Support for starting user threads is disabled */ #cmakedefine DISABLE_WASM_USER_THREADS +/* Support legacy JavaScript interop */ +#cmakedefine ENABLE_LEGACY_JS_INTEROP + #endif/*__MONO_WASM_CONFIG_H__*/ diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 3f4d2d2e2e03e..06f877690ff76 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -20,6 +20,7 @@ true false true + true @@ -353,6 +354,7 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASM_OPT_ADDITIONAL_FLAGS="--enable-simd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 + $(CMakeBuildRuntimeConfigureCmd) -DENABLE_LEGACY_JS_INTEROP=0 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) @@ -397,7 +399,8 @@ SkipUnchangedFiles="true" /> - + @@ -473,7 +476,7 @@ - Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),MonoDiagnosticsMock:$(MonoDiagnosticsMock) + Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),WasmEnableLegacyJsInterop:$(WasmEnableLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock)