From d411d71e31c8d076c8af3252f75bcdff8e6f3504 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 13 Dec 2022 19:17:15 +0100 Subject: [PATCH 01/10] wip --- ...ervices.JavaScript.Legacy.UnitTests.csproj | 8 +- src/mono/wasi/mono-wasi-driver/driver.c | 19 --- src/mono/wasi/mono-wasi-driver/driver.h | 1 - src/mono/wasm/build/WasmApp.Native.targets | 2 + src/mono/wasm/runtime/CMakeLists.txt | 2 +- src/mono/wasm/runtime/corebindings.c | 11 +- src/mono/wasm/runtime/cwraps.ts | 121 ++++++------------ src/mono/wasm/runtime/driver.c | 108 +--------------- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 79 ++++++------ src/mono/wasm/runtime/exports-linker.ts | 35 +++-- src/mono/wasm/runtime/icu.ts | 8 -- src/mono/wasm/runtime/net6-legacy/cs-to-js.ts | 2 +- .../runtime/net6-legacy/exports-legacy.ts | 2 +- src/mono/wasm/runtime/net6-legacy/js-to-cs.ts | 2 +- .../runtime/net6-legacy/method-binding.ts | 2 +- src/mono/wasm/runtime/rollup.config.js | 3 +- src/mono/wasm/wasm.proj | 8 +- .../pal_icushim_static.c | 7 - 18 files changed, 131 insertions(+), 289 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj index e7643c86db59b..bb2a067dc1dff 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj @@ -7,6 +7,11 @@ 0612 + + + + + @@ -15,9 +20,6 @@ - - - diff --git a/src/mono/wasi/mono-wasi-driver/driver.c b/src/mono/wasi/mono-wasi-driver/driver.c index df4ef9911429b..91d49a9f07e6c 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.c +++ b/src/mono/wasi/mono-wasi-driver/driver.c @@ -518,12 +518,6 @@ mono_wasm_assembly_load (const char *name) return res; } -MonoClass* -mono_wasm_find_corlib_class (const char *namespace, const char *name) -{ - return mono_class_from_name (mono_get_corlib (), namespace, name); -} - MonoClass* mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name) { @@ -700,12 +694,6 @@ mono_unbox_int (MonoObject *obj) } } -int -mono_wasm_array_length (MonoArray *array) -{ - return mono_array_length (array); -} - MonoObject* mono_wasm_array_get (MonoArray *array, int idx) { @@ -753,13 +741,6 @@ mono_wasm_string_get_data_ref ( return; } -void -mono_wasm_string_get_data ( - MonoString *string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned -) { - mono_wasm_string_get_data_ref(&string, outChars, outLengthBytes, outIsInterned); -} - void add_assembly(const char* base_dir, const char *name) { FILE *fileptr; unsigned char *buffer; diff --git a/src/mono/wasi/mono-wasi-driver/driver.h b/src/mono/wasi/mono-wasi-driver/driver.h index a27f2b8480614..0f76d9faa5fe2 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.h +++ b/src/mono/wasi/mono-wasi-driver/driver.h @@ -20,7 +20,6 @@ MonoArray* mono_wasm_obj_array_new (int size); void mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj); MonoArray* mono_wasm_string_array_new (int size); MonoString *mono_wasm_string_from_js (const char *str); -int mono_wasm_array_length(MonoArray* array); char *mono_wasm_string_get_utf8 (MonoString *str); MonoMethod* lookup_dotnet_method(const char* assembly_name, const char* namespace, const char* type_name, const char* method_name, int num_params); diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index fc637efdd64fa..87a78a556b08d 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -264,6 +264,8 @@ + + diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index dab32f84e060c..5c648525488ee 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -9,7 +9,7 @@ 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/corebindings.c b/src/mono/wasm/runtime/corebindings.c index ffbb52020432e..a30030f27298e 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -34,9 +34,14 @@ 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); + void core_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 +50,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 USE_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,6 +61,10 @@ 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); + + // 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 /* USE_LEGACY_JS_INTEROP */ } // Int8Array | int8_t | byte or SByte (signed byte) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index f1279cd9bf870..6fd4c01be9a70 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 MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; import { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, @@ -11,12 +12,27 @@ 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[] = !MonoWasmLegacyJsInterop ? [] : [ + [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"]], +]; + + // 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 [true, "mono_wasm_register_root", "number", ["number", "number", "string"]], [true, "mono_wasm_deregister_root", null, ["number"]], - [true, "mono_wasm_string_get_data", null, ["number", "number", "number", "number"]], [true, "mono_wasm_string_get_data_ref", null, ["number", "number", "number", "number"]], [true, "mono_wasm_set_is_debugger_attached", "void", ["bool"]], [true, "mono_wasm_send_dbg_command", "bool", ["number", "number", "number", "number", "number"]], @@ -27,7 +43,6 @@ const fn_signatures: SigLine[] = [ [true, "mono_background_exec", null, []], [true, "mono_set_timeout_exec", null, []], [true, "mono_wasm_load_icu_data", "number", ["number"]], - [true, "mono_wasm_get_icudt_name", "string", ["string"]], [false, "mono_wasm_add_assembly", "number", ["string", "number", "number"]], [true, "mono_wasm_add_satellite_assembly", "void", ["string", "string", "number", "number"]], [false, "mono_wasm_load_runtime", null, ["string", "number"]], @@ -36,37 +51,15 @@ 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"]], - [true, "mono_wasm_invoke_method", "number", ["number", "number", "number", "number"]], [false, "mono_wasm_invoke_method_ref", "void", ["number", "number", "number", "number", "number"]], - [true, "mono_wasm_string_get_utf8", "number", ["number"]], [true, "mono_wasm_string_from_utf16_ref", "void", ["number", "number", "number"]], - [true, "mono_wasm_get_obj_type", "number", ["number"]], - [true, "mono_wasm_array_length", "number", ["number"]], [true, "mono_wasm_array_length_ref", "number", ["number"]], - [true, "mono_wasm_array_get", "number", ["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_type_get_class", "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"]], @@ -77,15 +70,12 @@ const fn_signatures: SigLine[] = [ [true, "mono_wasm_diagnostic_server_post_resume_runtime", "void", []], [true, "mono_wasm_diagnostic_server_create_stream", "number", []], - //DOTNET - [true, "mono_wasm_string_from_js", "number", ["string"]], - //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 + // These need to be lazy because they may be missing [true, "mono_wasm_profiler_init_aot", "void", ["number"]], [true, "mono_wasm_profiler_init_browser", "void", ["number"]], [false, "mono_wasm_exec_regression", "number", ["number", "string"]], @@ -115,8 +105,25 @@ const fn_signatures: SigLine[] = [ [true, "mono_jiterp_register_jit_call_thunk", "void", ["number", "number"]], [true, "mono_jiterp_type_get_raw_value_size", "number", ["number"]], [true, "mono_jiterp_update_jit_call_dispatcher", "void", ["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; +} + export interface t_Cwraps { // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; @@ -131,70 +138,23 @@ export interface t_Cwraps { mono_background_exec(): void; mono_set_timeout_exec(): void; mono_wasm_load_icu_data(offset: VoidPtr): number; - mono_wasm_get_icudt_name(name: string): string; mono_wasm_add_assembly(name: string, data: VoidPtr, size: number): number; mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void; mono_wasm_load_runtime(unused: string, debugLevel: number): void; mono_wasm_change_debugger_log_level(value: number): void; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_string_get_data(string: MonoString, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; - // 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; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_string_get_utf8(str: MonoString): CharPtr; mono_wasm_string_from_utf16_ref(str: CharPtr, len: number, result: MonoObjectRef): void; - mono_wasm_array_length(array: MonoArray): number; - + mono_wasm_class_get_type(klass: MonoClass): MonoType; + mono_wasm_assembly_get_entry_point(assembly: MonoAssembly, idx: number): MonoMethod; 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_type_get_class(ty: MonoType): MonoClass; - 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; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_get_obj_type(str: MonoObject): number; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_obj_array_new(size: number): MonoArray; - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; - /** - * @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; @@ -205,12 +165,6 @@ export interface t_Cwraps { mono_wasm_diagnostic_server_post_resume_runtime(): void; mono_wasm_diagnostic_server_create_stream(): VoidPtr; - //DOTNET - /** - * @deprecated Not GC or thread safe - */ - mono_wasm_string_from_js(str: string): MonoString; - //INTERNAL mono_wasm_exit(exit_code: number): number; mono_wasm_getenv(name: string): CharPtr; @@ -253,6 +207,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 9b145963b0d4c..5a00f53ecaa5c 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -39,9 +39,7 @@ #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); @@ -441,22 +439,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 */ @@ -610,7 +593,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(); + core_initialize_internals(); mono_thread_set_main (mono_thread_current ()); @@ -734,28 +717,6 @@ mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void MONO_EXIT_GC_UNSAFE; } -// deprecated -MonoObject* -mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) -{ - PVOLATILE(MonoObject) result = NULL; - mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, (MonoObject **)&result); - - if (result) { - MONO_ENTER_GC_UNSAFE; - MonoMethodSignature *sig = mono_method_signature (method); - MonoType *type = mono_signature_get_return_type (sig); - // If the method return type is void return null - // This gets around a memory access crash when the result return a value when - // a void method is invoked. - if (mono_type_get_type (type) == MONO_TYPE_VOID) - result = NULL; - MONO_EXIT_GC_UNSAFE; - } - - return result; -} - EMSCRIPTEN_KEEPALIVE MonoObject* mono_wasm_invoke_method_bound (MonoMethod *method, void* args)// JSMarshalerArguments { @@ -839,28 +800,6 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly, int auto_insert_brea return method; } -// TODO: ref -EMSCRIPTEN_KEEPALIVE char * -mono_wasm_string_get_utf8 (MonoString *str) -{ - char * result; - MONO_ENTER_GC_UNSAFE; - result = mono_string_to_utf8 (str); //XXX JS is responsible for freeing this - MONO_EXIT_GC_UNSAFE; - return result; -} - -EMSCRIPTEN_KEEPALIVE MonoString * -mono_wasm_string_from_js (const char *str) -{ - PVOLATILE(MonoString) result = NULL; - MONO_ENTER_GC_UNSAFE; - if (str) - result = mono_string_new (root_domain, str); - MONO_EXIT_GC_UNSAFE; - return result; -} - EMSCRIPTEN_KEEPALIVE void mono_wasm_string_from_utf16_ref (const mono_unichar2 * chars, int length, MonoString **result) { @@ -1057,17 +996,6 @@ _wasm_get_obj_type_ref_impl (PPVOLATILE(MonoObject) obj) return _marshal_type_from_mono_type (mono_type, klass, type); } -// FIXME: Ref -EMSCRIPTEN_KEEPALIVE int -mono_wasm_get_obj_type (MonoObject *obj) -{ - int result; - MONO_ENTER_GC_UNSAFE; - result = _wasm_get_obj_type_ref_impl(&obj); - MONO_EXIT_GC_UNSAFE; - return result; -} - // 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) { @@ -1218,25 +1146,12 @@ mono_wasm_try_unbox_primitive_and_get_type_ref (MonoObject **objRef, void *resul return retval; } -// FIXME: Ref -EMSCRIPTEN_KEEPALIVE int -mono_wasm_array_length (MonoArray *array) -{ - return mono_array_length (array); -} - EMSCRIPTEN_KEEPALIVE int mono_wasm_array_length_ref (MonoArray **array) { return mono_array_length (*array); } -EMSCRIPTEN_KEEPALIVE MonoObject* -mono_wasm_array_get (MonoArray *array, int idx) -{ - return mono_array_get (array, MonoObject*, idx); -} - EMSCRIPTEN_KEEPALIVE void mono_wasm_array_get_ref (PPVOLATILE(MonoArray) array, int idx, PPVOLATILE(MonoObject) result) { @@ -1352,13 +1267,6 @@ mono_wasm_string_get_data_ref ( MONO_EXIT_GC_UNSAFE; } -EMSCRIPTEN_KEEPALIVE void -mono_wasm_string_get_data ( - MonoString *string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned -) { - mono_wasm_string_get_data_ref(&string, outChars, outLengthBytes, outIsInterned); -} - EMSCRIPTEN_KEEPALIVE MonoType * mono_wasm_class_get_type (MonoClass *klass) { @@ -1371,18 +1279,6 @@ mono_wasm_class_get_type (MonoClass *klass) return result; } -EMSCRIPTEN_KEEPALIVE MonoClass * -mono_wasm_type_get_class (MonoType *type) -{ - if (!type) - return NULL; - MonoClass *result; - MONO_ENTER_GC_UNSAFE; - result = mono_type_get_class (type); - MONO_EXIT_GC_UNSAFE; - return result; -} - EMSCRIPTEN_KEEPALIVE char * mono_wasm_get_type_name (MonoType * typePtr) { return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_REFLECTION); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 929887d1b0686..ab13f6e167d3b 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -4,13 +4,8 @@ "use strict"; -#if USE_PTHREADS -const usePThreads = `true`; -const isPThread = `ENVIRONMENT_IS_PTHREAD`; -#else -const usePThreads = `false`; -const isPThread = `false`; -#endif +const usePThreads = process.env.MonoWasmThreads == "true"; +const isPThread = usePThreads ? "ENVIRONMENT_IS_PTHREAD" : "false"; const DotnetSupportLib = { $DOTNET: {}, @@ -22,12 +17,15 @@ 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; -if (${usePThreads}) { - __dotnet_replacement_PThread.loadWasmModuleToWorker = PThread.loadWasmModuleToWorker; - __dotnet_replacement_PThread.threadInitTLS = PThread.threadInitTLS; - __dotnet_replacement_PThread.allocateUnusedWorker = PThread.allocateUnusedWorker; +${usePThreads ? ` +let __dotnet_replacement_PThread = { + loadWasmModuleToWorker: PThread.loadWasmModuleToWorker, + threadInitTLS: PThread.threadInitTLS, + allocateUnusedWorker: PThread.allocateUnusedWorker, } +`: ` +let __dotnet_replacement_PThread = undefined; +`} let __dotnet_replacements = {scriptUrl: import.meta.url, fetch: globalThis.fetch, require, updateGlobalBufferAndViews, pthreadReplacements: __dotnet_replacement_PThread}; if (ENVIRONMENT_IS_NODE) { __dotnet_replacements.requirePromise = import(/* webpackIgnore: true */'module').then(mod => mod.createRequire(import.meta.url)); @@ -45,17 +43,17 @@ if (ENVIRONMENT_IS_NODE) { }); } var noExitRuntime = __dotnet_replacements.noExitRuntime; -if (${usePThreads}) { - PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker; - PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTLS; - PThread.allocateUnusedWorker = __dotnet_replacements.pthreadReplacements.allocateUnusedWorker; -} +${usePThreads ? ` +PThread.loadWasmModuleToWorker = __dotnet_replacements.pthreadReplacements.loadWasmModuleToWorker; +PThread.threadInitTLS = __dotnet_replacements.pthreadReplacements.threadInitTLS; +PThread.allocateUnusedWorker = __dotnet_replacements.pthreadReplacements.allocateUnusedWorker; +`: ""} `, }; // 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 +72,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", @@ -87,16 +84,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", @@ -105,18 +93,33 @@ const linked_functions = [ // pal_icushim_static.c "mono_wasm_load_icu_data", - "mono_wasm_get_icudt_name", - - #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 (process.env.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 (process.env.MonoWasmLegacyJsInterop) { + 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-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index 4f3b2ce45f6e1..b54a3b24c8ac6 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -2,14 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; +import MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; import { mono_wasm_fire_debugger_agent_message, mono_wasm_debugger_log, mono_wasm_add_dbg_command_received, mono_wasm_set_entrypoint_breakpoint } from "./debug"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; -import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu"; +import { mono_wasm_load_icu_data } from "./icu"; import { mono_wasm_bind_cs_function } from "./invoke-cs"; import { mono_wasm_bind_js_function, mono_wasm_invoke_bound_function, mono_wasm_invoke_import } from "./invoke-js"; import { mono_interp_tier_prepare_jiterpreter } from "./jiterpreter"; import { mono_interp_jit_wasm_entry_trampoline } 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_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, @@ -22,8 +25,6 @@ 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"; @@ -38,6 +39,21 @@ const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : { mono_wasm_diagnostic_server_stream_signal_work_available, }; +const mono_wasm_legacy_interop_exports = !MonoWasmLegacyJsInterop ? 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 --- @@ -67,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, @@ -91,9 +97,10 @@ export function export_linker(): any { // pal_icushim_static.c mono_wasm_load_icu_data, - mono_wasm_get_icudt_name, // 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/icu.ts b/src/mono/wasm/runtime/icu.ts index 3e6e7105335c4..966fb8f01accf 100644 --- a/src/mono/wasm/runtime/icu.ts +++ b/src/mono/wasm/runtime/icu.ts @@ -16,14 +16,6 @@ export function mono_wasm_load_icu_data(offset: VoidPtr): boolean { return ok; } -// Get icudt.dat exact filename that matches given culture, examples: -// "ja" -> "icudt_CJK.dat" -// "en_US" (or "en-US" or just "en") -> "icudt_EFIGS.dat" -// etc, see "mono_wasm_get_icudt_name" implementation in pal_icushim_static.c -export function mono_wasm_get_icudt_name(culture: string): string { - return cwraps.mono_wasm_get_icudt_name(culture); -} - // Performs setup for globalization. // @globalizationMode is one of "icu", "invariant", or "auto". // "auto" will use "icu" if any ICU data archives have been loaded, 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 2758977f1d771..f63fbdce64f1a 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"; 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 37f6dd6b9c4f8..e54f7dbcdff41 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 monoWasmLegacyJsInterop = process.env.MonoWasmLegacyJsInterop === "true" ? 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, monoWasmLegacyJsInterop }), typescript(typescriptConfigOptions)]; const externalDependencies = [ ]; diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 5069285979c98..564a9c05a47a9 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -17,9 +17,11 @@ true + false true false true + false @@ -319,8 +321,8 @@ DestinationFolder="$(NativeBinDir)" SkipUnchangedFiles="true" /> - - + + @@ -397,7 +399,7 @@ - Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),MonoDiagnosticsMock:$(MonoDiagnosticsMock) + Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),MonoWasmLegacyJsInterop:$(MonoWasmLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock) diff --git a/src/native/libs/System.Globalization.Native/pal_icushim_static.c b/src/native/libs/System.Globalization.Native/pal_icushim_static.c index cd57172b52329..2a1e2b71a696f 100644 --- a/src/native/libs/System.Globalization.Native/pal_icushim_static.c +++ b/src/native/libs/System.Globalization.Native/pal_icushim_static.c @@ -50,13 +50,6 @@ static void U_CALLCONV icu_trace_data(const void* context, int32_t fnNumber, int static int32_t load_icu_data(const void* pData); -EMSCRIPTEN_KEEPALIVE const char* mono_wasm_get_icudt_name(const char* culture); - -EMSCRIPTEN_KEEPALIVE const char* mono_wasm_get_icudt_name(const char* culture) -{ - return GlobalizationNative_GetICUDTName(culture); -} - EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(const void* pData); EMSCRIPTEN_KEEPALIVE int32_t mono_wasm_load_icu_data(const void* pData) From aba32b9a931caa5337908823c576a95a600db7f5 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 13 Dec 2022 20:49:04 +0100 Subject: [PATCH 02/10] wip --- ....Runtime.InteropServices.JavaScript.csproj | 21 +- .../JavaScript/JSFunctionBinding.cs | 3 +- ...ervices.JavaScript.Legacy.UnitTests.csproj | 2 +- ...me.InteropServices.JavaScript.Tests.csproj | 1 + .../JavaScript/JSImportExportTest.cs | 2 + src/mono/wasm/runtime/assets.ts | 5 +- src/mono/wasm/runtime/corebindings.c | 45 +- src/mono/wasm/runtime/driver.c | 471 +++++++++--------- src/mono/wasm/runtime/exports-internal.ts | 2 - src/mono/wasm/runtime/exports-linker.ts | 14 +- src/mono/wasm/runtime/exports.ts | 44 +- src/mono/wasm/runtime/imports.ts | 5 +- .../runtime/net6-legacy/exports-legacy.ts | 9 +- src/mono/wasm/runtime/net6-legacy/imports.ts | 6 +- src/mono/wasm/runtime/startup.ts | 21 +- src/mono/wasm/runtime/types.ts | 1 + src/mono/wasm/wasm.proj | 1 + 17 files changed, 328 insertions(+), 325 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index f67b0cd3b0346..d5ec09d0af13f 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -3,7 +3,9 @@ $(NetCoreAppCurrent)-Browser;$(NetCoreAppCurrent) true true + true $(DefineConstants);FEATURE_WASM_THREADS + $(DefineConstants);FEATURE_LEGACY_JS_INTEROP @@ -21,15 +23,6 @@ - - - - - - - - - @@ -67,6 +60,16 @@ + + + + + + + + + + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs index a4a07ab5139ba..35b6d31c45e02 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSFunctionBinding.cs @@ -142,8 +142,9 @@ public static void InvokeJS(JSFunctionBinding signature, SpanThe method is executed on an architecture other than WebAssembly. // JavaScriptExports need to be protected from trimming because they are used from C/JS code which IL linker can't see [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "System.Runtime.InteropServices.JavaScript.JavaScriptExports", "System.Runtime.InteropServices.JavaScript")] - // TODO make this DynamicDependency conditional +#if FEATURE_LEGACY_JS_INTEROP [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, "System.Runtime.InteropServices.JavaScript.LegacyExports", "System.Runtime.InteropServices.JavaScript")] +#endif public static JSFunctionBinding BindJSFunction(string functionName, string moduleName, ReadOnlySpan signatures) { if (RuntimeInformation.OSArchitecture != Architecture.Wasm) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj index bb2a067dc1dff..64512922a9b1d 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj @@ -7,11 +7,11 @@ 0612 - + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj index e6e1d2adcf81e..364ff9c17321b 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj @@ -6,6 +6,7 @@ $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop true + $(DefineConstants);FEATURE_LEGACY_JS_INTEROP diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs index 48f39d3254bc8..2d1e2c4aace5c 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System/Runtime/InteropServices/JavaScript/JSImportExportTest.cs @@ -44,8 +44,10 @@ public unsafe void GlobalThis() [Fact] public unsafe void DotnetInstance() { +#if FEATURE_LEGACY_JS_INTEROP Assert.True(JSHost.DotnetInstance.HasProperty("MONO")); Assert.Equal("object", JSHost.DotnetInstance.GetTypeOfProperty("MONO")); +#endif JSHost.DotnetInstance.SetProperty("testBool", true); Assert.Equal("boolean", JSHost.DotnetInstance.GetTypeOfProperty("testBool")); diff --git a/src/mono/wasm/runtime/assets.ts b/src/mono/wasm/runtime/assets.ts index 2f6ab851f1bb1..1fbabe7654df9 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"; @@ -516,12 +515,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 a30030f27298e..34134cf1b8761 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -50,7 +50,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 USE_LEGACY_JS_INTEROP +#ifdef FEATURE_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); @@ -64,9 +64,10 @@ void core_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); -#endif /* USE_LEGACY_JS_INTEROP */ +#endif /* FEATURE_LEGACY_JS_INTEROP */ } +#ifdef FEATURE_LEGACY_JS_INTEROP // Int8Array | int8_t | byte or SByte (signed byte) // Uint8Array | uint8_t | byte or Byte (unsigned byte) // Uint8ClampedArray| uint8_t | byte or Byte (unsigned byte) @@ -133,44 +134,6 @@ mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, PPVOLA MONO_EXIT_GC_UNSAFE; } -// TODO: Remove - no longer used? If not, convert to ref -EMSCRIPTEN_KEEPALIVE int -mono_wasm_unbox_enum (PVOLATILE(MonoObject) obj) -{ - if (!obj) - return 0; - - int result = 0; - MONO_ENTER_GC_UNSAFE; - PVOLATILE(MonoType) type = mono_class_get_type (mono_object_get_class(obj)); - - PVOLATILE(void) ptr = mono_object_unbox (obj); - switch (mono_type_get_type(mono_type_get_underlying_type (type))) { - case MONO_TYPE_I1: - case MONO_TYPE_U1: - result = *(unsigned char*)ptr; - break; - case MONO_TYPE_I2: - result = *(short*)ptr; - break; - case MONO_TYPE_U2: - result = *(unsigned short*)ptr; - break; - case MONO_TYPE_I4: - result = *(int*)ptr; - break; - case MONO_TYPE_U4: - result = *(unsigned int*)ptr; - break; - // WASM doesn't support returning longs to JS - // case MONO_TYPE_I8: - // case MONO_TYPE_U8: - default: - printf ("Invalid type %d to mono_unbox_enum\n", mono_type_get_type(mono_type_get_underlying_type (type))); - break; - } - MONO_EXIT_GC_UNSAFE; - return result; -} +#endif /* FEATURE_LEGACY_JS_INTEROP */ diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 5a00f53ecaa5c..1f4a9637926d1 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -663,32 +663,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) { @@ -996,209 +970,12 @@ _wasm_get_obj_type_ref_impl (PPVOLATILE(MonoObject) obj) return _marshal_type_from_mono_type (mono_type, klass, type); } -// 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) { - void **resultP = result; - int *resultI = result; - uint32_t *resultU = result; - int64_t *resultL = result; - float *resultF = result; - double *resultD = result; - - /* Process obj before calling into the runtime, class_from_name () can invoke managed code */ - MonoClass *klass = mono_object_get_class (obj); - if (!klass) - return MARSHAL_ERROR_NULL_CLASS_POINTER; - - MonoType *type = mono_class_get_type (klass), *original_type = type; - if (!type) - return MARSHAL_ERROR_NULL_TYPE_POINTER; - - if ((klass == mono_get_string_class ()) && - mono_string_instance_is_interned ((MonoString *)obj)) { - *resultL = 0; - *resultP = type; - return MARSHAL_TYPE_STRING_INTERNED; - } - - if (mono_class_is_enum (klass)) - type = mono_type_get_underlying_type (type); - - if (!type) - return MARSHAL_ERROR_NULL_TYPE_POINTER; - - int mono_type = mono_type_get_type (type); - - if (mono_type == MONO_TYPE_GENERICINST) { - // HACK: While the 'any other type' fallback is valid for classes, it will do the - // wrong thing for structs, so we need to make sure the valuetype handler is used - if (mono_type_generic_inst_is_valuetype (type)) - mono_type = MONO_TYPE_VALUETYPE; - } - - // FIXME: We would prefer to unbox once here but it will fail if the value isn't unboxable - - switch (mono_type) { - case MONO_TYPE_I1: - case MONO_TYPE_BOOLEAN: - *resultI = *(signed char*)mono_object_unbox (obj); - break; - case MONO_TYPE_U1: - *resultU = *(unsigned char*)mono_object_unbox (obj); - break; - case MONO_TYPE_I2: - case MONO_TYPE_CHAR: - *resultI = *(short*)mono_object_unbox (obj); - break; - case MONO_TYPE_U2: - *resultU = *(unsigned short*)mono_object_unbox (obj); - break; - case MONO_TYPE_I4: - case MONO_TYPE_I: - *resultI = *(int*)mono_object_unbox (obj); - break; - case MONO_TYPE_U4: - *resultU = *(uint32_t*)mono_object_unbox (obj); - break; - case MONO_TYPE_R4: - *resultF = *(float*)mono_object_unbox (obj); - break; - case MONO_TYPE_R8: - *resultD = *(double*)mono_object_unbox (obj); - break; - case MONO_TYPE_PTR: - *resultU = (uint32_t)(*(void**)mono_object_unbox (obj)); - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - // FIXME: At present the javascript side of things can't handle this, - // but there's no reason not to future-proof this API - *resultL = *(int64_t*)mono_object_unbox (obj); - break; - case MONO_TYPE_VALUETYPE: - { - int obj_size = mono_object_get_size (obj), - required_size = (sizeof (int)) + (sizeof (MonoType *)) + obj_size; - - // Check whether this struct has special-case marshaling - // FIXME: Do we need to null out obj before this? - int marshal_type = _marshal_type_from_mono_type (mono_type, klass, original_type); - if (marshal_type != MARSHAL_TYPE_VT) - return marshal_type; - - // Check whether the result buffer is big enough for the struct and padding - if (result_capacity < required_size) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - // Store a header before the struct data with the size of the data and its MonoType - *resultP = type; - int * resultSize = (int *)(resultP + 1); - *resultSize = obj_size; - void * resultVoid = (resultP + 2); - void * unboxed = mono_object_unbox (obj); - memcpy (resultVoid, unboxed, obj_size); - return MARSHAL_TYPE_VT; - } - break; - default: - // If we failed to do a fast unboxing, return the original type information so - // that the caller can do a proper, slow unboxing later - // HACK: Store the class pointer into the result buffer so our caller doesn't - // have to call back into the native runtime later to get it - *resultP = type; - int fallbackResultType = _marshal_type_from_mono_type (mono_type, klass, original_type); - assert (fallbackResultType != MARSHAL_TYPE_VT); - return fallbackResultType; - } - - // We successfully performed a fast unboxing here so use the type information - // matching what we unboxed (i.e. an enum's underlying type instead of its type) - int resultType = _marshal_type_from_mono_type (mono_type, klass, type); - assert (resultType != MARSHAL_TYPE_VT); - return resultType; -} - -EMSCRIPTEN_KEEPALIVE int -mono_wasm_try_unbox_primitive_and_get_type_ref (MonoObject **objRef, void *result, int result_capacity) -{ - if (!result) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - int retval; - int *resultI = result; - int64_t *resultL = result; - - if (result_capacity >= sizeof (int64_t)) - *resultL = 0; - else if (result_capacity >= sizeof (int)) - *resultI = 0; - - if (result_capacity < 16) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - if (!objRef || !(*objRef)) - return MARSHAL_TYPE_NULL; - - MONO_ENTER_GC_UNSAFE; - retval = _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (*objRef, result, result_capacity); - MONO_EXIT_GC_UNSAFE; - return retval; -} - EMSCRIPTEN_KEEPALIVE int mono_wasm_array_length_ref (MonoArray **array) { return mono_array_length (*array); } -EMSCRIPTEN_KEEPALIVE void -mono_wasm_array_get_ref (PPVOLATILE(MonoArray) array, int idx, PPVOLATILE(MonoObject) result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic((void*)result, mono_array_get ((MonoArray*)*array, MonoObject*, idx)); - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_new_ref (int size, MonoArray **result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_object_class (), size)); - MONO_EXIT_GC_UNSAFE; -} - -// Deprecated -EMSCRIPTEN_KEEPALIVE MonoArray* -mono_wasm_obj_array_new (int size) -{ - PVOLATILE(MonoArray) result = NULL; - mono_wasm_obj_array_new_ref(size, (MonoArray **)&result); - return result; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj) -{ - mono_array_setref (array, idx, obj); -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_obj_array_set_ref (MonoArray **array, int idx, MonoObject **obj) -{ - MONO_ENTER_GC_UNSAFE; - mono_array_setref (*array, idx, *obj); - MONO_EXIT_GC_UNSAFE; -} - -EMSCRIPTEN_KEEPALIVE void -mono_wasm_string_array_new_ref (int size, MonoArray **result) -{ - MONO_ENTER_GC_UNSAFE; - mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_string_class (), size)); - MONO_EXIT_GC_UNSAFE; -} - EMSCRIPTEN_KEEPALIVE int mono_wasm_exec_regression (int verbose_level, char *image) { @@ -1279,16 +1056,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); @@ -1393,3 +1160,241 @@ EMSCRIPTEN_KEEPALIVE const char * mono_wasm_method_get_full_name (MonoMethod *me EMSCRIPTEN_KEEPALIVE const char * mono_wasm_method_get_name (MonoMethod *method) { return mono_method_get_name(method); } + +#ifdef FEATURE_LEGACY_JS_INTEROP + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_array_get_ref (PPVOLATILE(MonoArray) array, int idx, PPVOLATILE(MonoObject) result) +{ + MONO_ENTER_GC_UNSAFE; + mono_gc_wbarrier_generic_store_atomic((void*)result, mono_array_get ((MonoArray*)*array, MonoObject*, idx)); + MONO_EXIT_GC_UNSAFE; +} + + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_obj_array_new_ref (int size, MonoArray **result) +{ + MONO_ENTER_GC_UNSAFE; + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_object_class (), size)); + MONO_EXIT_GC_UNSAFE; +} + +// Deprecated +EMSCRIPTEN_KEEPALIVE MonoArray* +mono_wasm_obj_array_new (int size) +{ + PVOLATILE(MonoArray) result = NULL; + mono_wasm_obj_array_new_ref(size, (MonoArray **)&result); + return result; +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj) +{ + mono_array_setref (array, idx, obj); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_obj_array_set_ref (MonoArray **array, int idx, MonoObject **obj) +{ + MONO_ENTER_GC_UNSAFE; + mono_array_setref (*array, idx, *obj); + MONO_EXIT_GC_UNSAFE; +} + +// 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) { + void **resultP = result; + int *resultI = result; + uint32_t *resultU = result; + int64_t *resultL = result; + float *resultF = result; + double *resultD = result; + + /* Process obj before calling into the runtime, class_from_name () can invoke managed code */ + MonoClass *klass = mono_object_get_class (obj); + if (!klass) + return MARSHAL_ERROR_NULL_CLASS_POINTER; + + MonoType *type = mono_class_get_type (klass), *original_type = type; + if (!type) + return MARSHAL_ERROR_NULL_TYPE_POINTER; + + if ((klass == mono_get_string_class ()) && + mono_string_instance_is_interned ((MonoString *)obj)) { + *resultL = 0; + *resultP = type; + return MARSHAL_TYPE_STRING_INTERNED; + } + + if (mono_class_is_enum (klass)) + type = mono_type_get_underlying_type (type); + + if (!type) + return MARSHAL_ERROR_NULL_TYPE_POINTER; + + int mono_type = mono_type_get_type (type); + + if (mono_type == MONO_TYPE_GENERICINST) { + // HACK: While the 'any other type' fallback is valid for classes, it will do the + // wrong thing for structs, so we need to make sure the valuetype handler is used + if (mono_type_generic_inst_is_valuetype (type)) + mono_type = MONO_TYPE_VALUETYPE; + } + + // FIXME: We would prefer to unbox once here but it will fail if the value isn't unboxable + + switch (mono_type) { + case MONO_TYPE_I1: + case MONO_TYPE_BOOLEAN: + *resultI = *(signed char*)mono_object_unbox (obj); + break; + case MONO_TYPE_U1: + *resultU = *(unsigned char*)mono_object_unbox (obj); + break; + case MONO_TYPE_I2: + case MONO_TYPE_CHAR: + *resultI = *(short*)mono_object_unbox (obj); + break; + case MONO_TYPE_U2: + *resultU = *(unsigned short*)mono_object_unbox (obj); + break; + case MONO_TYPE_I4: + case MONO_TYPE_I: + *resultI = *(int*)mono_object_unbox (obj); + break; + case MONO_TYPE_U4: + *resultU = *(uint32_t*)mono_object_unbox (obj); + break; + case MONO_TYPE_R4: + *resultF = *(float*)mono_object_unbox (obj); + break; + case MONO_TYPE_R8: + *resultD = *(double*)mono_object_unbox (obj); + break; + case MONO_TYPE_PTR: + *resultU = (uint32_t)(*(void**)mono_object_unbox (obj)); + break; + case MONO_TYPE_I8: + case MONO_TYPE_U8: + // FIXME: At present the javascript side of things can't handle this, + // but there's no reason not to future-proof this API + *resultL = *(int64_t*)mono_object_unbox (obj); + break; + case MONO_TYPE_VALUETYPE: + { + int obj_size = mono_object_get_size (obj), + required_size = (sizeof (int)) + (sizeof (MonoType *)) + obj_size; + + // Check whether this struct has special-case marshaling + // FIXME: Do we need to null out obj before this? + int marshal_type = _marshal_type_from_mono_type (mono_type, klass, original_type); + if (marshal_type != MARSHAL_TYPE_VT) + return marshal_type; + + // Check whether the result buffer is big enough for the struct and padding + if (result_capacity < required_size) + return MARSHAL_ERROR_BUFFER_TOO_SMALL; + + // Store a header before the struct data with the size of the data and its MonoType + *resultP = type; + int * resultSize = (int *)(resultP + 1); + *resultSize = obj_size; + void * resultVoid = (resultP + 2); + void * unboxed = mono_object_unbox (obj); + memcpy (resultVoid, unboxed, obj_size); + return MARSHAL_TYPE_VT; + } + break; + default: + // If we failed to do a fast unboxing, return the original type information so + // that the caller can do a proper, slow unboxing later + // HACK: Store the class pointer into the result buffer so our caller doesn't + // have to call back into the native runtime later to get it + *resultP = type; + int fallbackResultType = _marshal_type_from_mono_type (mono_type, klass, original_type); + assert (fallbackResultType != MARSHAL_TYPE_VT); + return fallbackResultType; + } + + // We successfully performed a fast unboxing here so use the type information + // matching what we unboxed (i.e. an enum's underlying type instead of its type) + int resultType = _marshal_type_from_mono_type (mono_type, klass, type); + assert (resultType != MARSHAL_TYPE_VT); + return resultType; +} + +EMSCRIPTEN_KEEPALIVE int +mono_wasm_try_unbox_primitive_and_get_type_ref (MonoObject **objRef, void *result, int result_capacity) +{ + if (!result) + return MARSHAL_ERROR_BUFFER_TOO_SMALL; + + int retval; + int *resultI = result; + int64_t *resultL = result; + + if (result_capacity >= sizeof (int64_t)) + *resultL = 0; + else if (result_capacity >= sizeof (int)) + *resultI = 0; + + if (result_capacity < 16) + return MARSHAL_ERROR_BUFFER_TOO_SMALL; + + if (!objRef || !(*objRef)) + return MARSHAL_TYPE_NULL; + + MONO_ENTER_GC_UNSAFE; + retval = _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (*objRef, result, result_capacity); + MONO_EXIT_GC_UNSAFE; + return retval; +} + +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_string_array_new_ref (int size, MonoArray **result) +{ + MONO_ENTER_GC_UNSAFE; + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_string_class (), size)); + 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 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); +} + +#endif /* FEATURE_LEGACY_JS_INTEROP */ \ No newline at end of file diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index c3ff6a75d3bbe..ca339a0f79262 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"; @@ -23,7 +22,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 b54a3b24c8ac6..ab4e0f0e895f0 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -11,13 +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 } 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_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"; 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"; @@ -27,6 +20,13 @@ import { mono_wasm_diagnostic_server_on_runtime_server_init, mono_wasm_event_pip import { mono_wasm_diagnostic_server_stream_signal_work_available } from "./diagnostics/server_pthread/stream-queue"; 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 --- diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 1950eb7ae692b..734cc409b4cd4 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 MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; 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,19 +42,21 @@ function initializeImportsAndExports( // we want to have same instance of MONO, BINDING and Module in dotnet iffe set_imports_exports(imports, exports); - set_legacy_exports(exports); + if (MonoWasmLegacyJsInterop) { + 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()); - Object.assign(exports.internal, export_internal()); + if (MonoWasmLegacyJsInterop) { + 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, @@ -62,6 +67,13 @@ function initializeImportsAndExports( }, ...API, }); + if (MonoWasmLegacyJsInterop) { + Object.assign(exportedRuntimeAPI, { + MONO: exports.mono, + BINDING: exports.binding, + }); + } + Object.assign(callbackAPI, API); if (exports.module.__undefinedConfig) { module.disableDotnet6Compatibility = true; @@ -82,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 (MonoWasmLegacyJsInterop) { + // 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 01a3f9cdcf4e4..67a64351b3d77 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; @@ -59,5 +59,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/exports-legacy.ts b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts index f63fbdce64f1a..c124397a77a02 100644 --- a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts +++ b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts @@ -17,6 +17,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 { @@ -40,7 +41,7 @@ export function export_mono_api(): MONOType { mono_wasm_load_runtime, config: runtimeHelpers.config, - loaded_files: [], + loaded_files: runtimeHelpers.loadedFiles, // memory accessors setB32, @@ -76,6 +77,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/startup.ts b/src/mono/wasm/runtime/startup.ts index 00eea0f796dfe..c41234bb65a6e 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 MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigError, 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,21 @@ 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_with_retries, 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; let isCustomStartup = false; @@ -291,9 +295,10 @@ function mono_wasm_pre_init_essential(): void { // init_polyfills() is already called from export.ts init_c_exports(); cwraps_internal(INTERNAL); - cwraps_mono_api(MONO); - cwraps_binding_api(BINDING); - + if (MonoWasmLegacyJsInterop) { + cwraps_mono_api(MONO); + cwraps_binding_api(BINDING); + } Module.removeRunDependency("mono_wasm_pre_init_essential"); } @@ -532,7 +537,9 @@ export function bindings_init(): void { try { const mark = startMeasure(); init_managed_exports(); - init_legacy_exports(); + if (MonoWasmLegacyJsInterop) { + 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 81739f9a0b3a9..6750ce2a65008 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -225,6 +225,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/wasm.proj b/src/mono/wasm/wasm.proj index 564a9c05a47a9..6e3fed503b82e 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -279,6 +279,7 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASM_OPT_ADDITIONAL_FLAGS="--enable-simd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 + $(CMakeBuildRuntimeConfigureCmd) -DFEATURE_LEGACY_JS_INTEROP=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) From d7c360cfde7bbd00551f342b082a4750a96509ab Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 14 Dec 2022 12:00:45 +0100 Subject: [PATCH 03/10] fix --- .../src/Resources/Strings.resx | 15 +++++++++++++++ .../JavaScript/Interop/JavaScriptExports.cs | 10 +++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx index f29200552dbac..046c522adac1a 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx @@ -129,6 +129,21 @@ TypedArray is not of correct type. + + Missing entrypoint + + + Can't resolve entrypoint handle + + + Return type '{0}' from main method in not supported + + + ToManagedCallback is null + + + TaskCallback is null + Unable to cast null to type {0}. diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs index 3972c50c8fa62..832e19d54ccec 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs @@ -24,7 +24,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer) arg_1.ToManaged(out IntPtr entrypointPtr); if (entrypointPtr == IntPtr.Zero) { - throw new MissingMethodException("Missing entrypoint"); + throw new MissingMethodException(SR.Format(SR.MissingEntrypoint)); } RuntimeMethodHandle methodHandle = JSHostImplementation.GetMethodHandleFromIntPtr(entrypointPtr); @@ -32,7 +32,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer) MethodInfo? method = MethodBase.GetMethodFromHandle(methodHandle) as MethodInfo; if (method == null) { - throw new InvalidProgramException("Can't resolve entrypoint handle"); + throw new InvalidProgramException(SR.Format(SR.EntrypointHandle)); } arg_2.ToManaged(out string?[]? args); @@ -75,7 +75,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer) } else { - throw new InvalidProgramException($"Return type '{method.ReturnType.FullName}' from main method in not supported"); + throw new InvalidProgramException(SR.Format(SR.ReturnTypeNotSupportedForMain, method.ReturnType.FullName)); } arg_result.ToJS(result, (ref JSMarshalerArgument arg, int value) => { @@ -154,7 +154,7 @@ public static void CallDelegate(JSMarshalerArgument* arguments_buffer) } else { - throw new InvalidOperationException("ToManagedCallback is null"); + throw new InvalidOperationException(SR.Format(SR.NullToManagedCallback)); } } catch (Exception ex) @@ -181,7 +181,7 @@ public static void CompleteTask(JSMarshalerArgument* arguments_buffer) } else { - throw new InvalidOperationException("TaskCallback is null"); + throw new InvalidOperationException(SR.Format(SR.NullTaskCallback)); } } catch (Exception ex) From f6fd8173d078c9bce3cabbe0a11ad3e66966f636 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 16 Dec 2022 15:01:40 +0100 Subject: [PATCH 04/10] Update src/mono/wasm/runtime/exports-linker.ts Co-authored-by: Ankit Jain --- src/mono/wasm/runtime/exports-linker.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/wasm/runtime/exports-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index ab4e0f0e895f0..96d0c2008e268 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -53,7 +53,6 @@ const mono_wasm_legacy_interop_exports = !MonoWasmLegacyJsInterop ? undefined : 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 --- From 85e0b930932a1dbfc67cb467c4b12d01c3dbe564 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 16 Dec 2022 15:01:50 +0100 Subject: [PATCH 05/10] Update src/mono/wasm/runtime/cwraps.ts Co-authored-by: Ankit Jain --- src/mono/wasm/runtime/cwraps.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index eac1ad5219244..585386687c611 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -27,7 +27,6 @@ const legacy_interop_cwraps: SigLine[] = !MonoWasmLegacyJsInterop ? [] : [ [true, "mono_wasm_obj_array_set", "void", ["number", "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 From db1b8e6ec2bd0d77da9834c0819422e42d39f1eb Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 16 Dec 2022 15:01:57 +0100 Subject: [PATCH 06/10] Update src/mono/wasm/runtime/startup.ts Co-authored-by: Ankit Jain --- src/mono/wasm/runtime/startup.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index c41234bb65a6e..0d10269cb962c 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -33,7 +33,6 @@ 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; let isCustomStartup = false; From d14a2bb2d67650b4f072fce47db5aedf2d243c42 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 26 Dec 2022 21:51:20 +0100 Subject: [PATCH 07/10] fix merge --- .../src/Resources/Strings.resx | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx index 44d95092ebd6f..dc490f9911b2e 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx @@ -129,21 +129,6 @@ TypedArray is not of correct type. - - Missing entrypoint - - - Can't resolve entrypoint handle - - - Return type '{0}' from main method in not supported - - - ToManagedCallback is null - - - TaskCallback is null - Unable to cast null to type {0}. From a6e1542104585cfac05dcccc84bd65f493890775 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 3 Jan 2023 13:54:35 +0100 Subject: [PATCH 08/10] fix --- src/mono/wasm/runtime/startup.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index ae22b03570fd8..9602bf2ad0ac3 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -22,7 +22,6 @@ import { init_managed_exports } from "./managed-exports"; import { cwraps_internal } from "./exports-internal"; 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"; @@ -296,8 +295,8 @@ function mono_wasm_pre_init_essential(): void { init_c_exports(); cwraps_internal(INTERNAL); if (MonoWasmLegacyJsInterop) { - cwraps_mono_api(MONO); - cwraps_binding_api(BINDING); + cwraps_mono_api(MONO); + cwraps_binding_api(BINDING); } Module.removeRunDependency("mono_wasm_pre_init_essential"); } @@ -538,7 +537,7 @@ export function bindings_init(): void { const mark = startMeasure(); init_managed_exports(); if (MonoWasmLegacyJsInterop) { - init_legacy_exports(); + init_legacy_exports(); } initialize_marshalers_to_js(); initialize_marshalers_to_cs(); From f54d2a35ea379cb214e5e577c4bab54b2b10fc99 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 3 Jan 2023 15:23:00 +0100 Subject: [PATCH 09/10] wip --- ....Runtime.InteropServices.JavaScript.csproj | 5 ++-- .../JavaScript/Interop/JavaScriptImports.cs | 4 ++- .../JavaScript/JSHostImplementation.cs | 7 ------ .../JavaScript/JSObject.References.cs | 6 +++++ .../JavaScript/Legacy/Array.cs | 2 +- .../Legacy/LegacyHostImplementation.cs | 7 ++++++ .../JavaScript/Legacy/Runtime.cs | 4 +-- ...ervices.JavaScript.Legacy.UnitTests.csproj | 8 +++++- ...me.InteropServices.JavaScript.Tests.csproj | 5 ++++ src/mono/mono.proj | 2 ++ src/mono/wasm/build/WasmApp.Native.targets | 2 +- src/mono/wasm/runtime/CMakeLists.txt | 1 + src/mono/wasm/runtime/corebindings.c | 25 +++++++++++-------- src/mono/wasm/runtime/cwraps.ts | 4 +-- src/mono/wasm/runtime/driver.c | 3 --- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 +- src/mono/wasm/runtime/exports-linker.ts | 4 +-- src/mono/wasm/runtime/exports.ts | 10 ++++---- src/mono/wasm/runtime/rollup.config.js | 4 +-- src/mono/wasm/runtime/startup.ts | 6 ++--- src/mono/wasm/runtime/wasm-config.h.in | 3 +++ src/mono/wasm/wasm.proj | 9 ++++--- 22 files changed, 76 insertions(+), 47 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index 121e9861a87ff..d3c4d1d77f262 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -3,7 +3,8 @@ $(NetCoreAppCurrent)-browser;$(NetCoreAppCurrent) true true - true + false + true $(DefineConstants);FEATURE_WASM_THREADS $(DefineConstants);FEATURE_LEGACY_JS_INTEROP @@ -60,7 +61,7 @@ - + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs index 36ea076bd4c5e..8e0a838253f07 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptImports.cs @@ -21,6 +21,7 @@ public static void MarshalPromise(Span arguments) } #region legacy +#if FEATURE_LEGACY_JS_INTEROP public static object GetGlobalObject(string? str = null) { @@ -30,7 +31,7 @@ public static object GetGlobalObject(string? str = null) if (exception != 0) throw new JSException(SR.Format(SR.ErrorResolvingFromGlobalThis, str)); - JSHostImplementation.ReleaseInFlight(jsObj); + LegacyHostImplementation.ReleaseInFlight(jsObj); return jsObj; } @@ -43,6 +44,7 @@ public static IntPtr CreateCSOwnedObject(string typeName, object[] parms) return (IntPtr)(int)res; } +#endif #endregion } } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs index c573311897eab..cdb3c3ad3f469 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSHostImplementation.cs @@ -42,13 +42,6 @@ public static void ReleaseCSOwnedObject(nint jsHandle) throw new InvalidOperationException(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ReleaseInFlight(object obj) - { - JSObject? jsObj = obj as JSObject; - jsObj?.ReleaseInFlight(); - } - // A JSOwnedObject is a managed object with its lifetime controlled by javascript. // The managed side maintains a strong reference to the object, while the JS side // maintains a weak reference and notifies the managed side if the JS wrapper object diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs index 17622520a01a1..9d9d4e2e9df61 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.References.cs @@ -10,17 +10,22 @@ public partial class JSObject { internal nint JSHandle; +#if FEATURE_LEGACY_JS_INTEROP internal GCHandle? InFlight; internal int InFlightCounter; +#endif private bool _isDisposed; internal JSObject(IntPtr jsHandle) { JSHandle = jsHandle; +#if FEATURE_LEGACY_JS_INTEROP InFlight = null; InFlightCounter = 0; +#endif } +#if FEATURE_LEGACY_JS_INTEROP internal void AddInFlight() { ObjectDisposedException.ThrowIf(IsDisposed, this); @@ -53,6 +58,7 @@ internal void ReleaseInFlight() } } } +#endif /// public override bool Equals([NotNullWhen(true)] object? obj) => obj is JSObject other && JSHandle == other.JSHandle; diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs index 00fa785a89846..987a2d2fd8bf0 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Array.cs @@ -91,7 +91,7 @@ public object this[int i] if (exception != 0) throw new JSException((string)indexValue); - JSHostImplementation.ReleaseInFlight(indexValue); + LegacyHostImplementation.ReleaseInFlight(indexValue); return indexValue; } set diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs index 840d25acf5edc..d24a1decdff63 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/LegacyHostImplementation.cs @@ -10,6 +10,13 @@ namespace System.Runtime.InteropServices.JavaScript [SupportedOSPlatform("browser")] internal static class LegacyHostImplementation { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ReleaseInFlight(object obj) + { + JSObject? jsObj = obj as JSObject; + jsObj?.ReleaseInFlight(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void RegisterCSOwnedObject(JSObject proxy) { diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs index aba7806ff60f8..13147c8102052 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Legacy/Runtime.cs @@ -39,7 +39,7 @@ public static object Invoke(this JSObject self, string method, params object?[] Interop.Runtime.InvokeJSWithArgsRef(self.JSHandle, method, args, out int exception, out object res); if (exception != 0) throw new JSException((string)res); - JSHostImplementation.ReleaseInFlight(res); + LegacyHostImplementation.ReleaseInFlight(res); return res; } @@ -74,7 +74,7 @@ public static object GetObjectProperty(this JSObject self, string name) Interop.Runtime.GetObjectPropertyRef(self.JSHandle, name, out int exception, out object propertyValue); if (exception != 0) throw new JSException((string)propertyValue); - JSHostImplementation.ReleaseInFlight(propertyValue); + LegacyHostImplementation.ReleaseInFlight(propertyValue); return propertyValue; } diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj index 4a5278aed7c46..b8b7e9e724e97 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests/System.Runtime.InteropServices.JavaScript.Legacy.UnitTests.csproj @@ -5,12 +5,18 @@ true $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop 0612 + true + false + true + $(DefineConstants);FEATURE_WASM_THREADS + $(DefineConstants);FEATURE_LEGACY_JS_INTEROP + $(DefineConstants);FEATURE_LEGACY_JS_INTEROP - + diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj index 9f8b1d4a39f2e..4ad8d62baa3b9 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/System.Runtime.InteropServices.JavaScript.UnitTests/System.Runtime.InteropServices.JavaScript.Tests.csproj @@ -6,6 +6,11 @@ $(WasmXHarnessArgs) --engine-arg=--expose-gc --web-server-use-cop true + true + false + true + $(DefineConstants);FEATURE_WASM_THREADS + $(DefineConstants);FEATURE_LEGACY_JS_INTEROP $(DefineConstants);FEATURE_LEGACY_JS_INTEROP diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 37d96487b4961..522ebd0afa728 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -56,6 +56,8 @@ false true true + false + true diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 87a78a556b08d..4d610e20a1dc8 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -264,7 +264,7 @@ - + diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 5c648525488ee..1d9ee7960f2b2 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -4,6 +4,7 @@ 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(FEATURE_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) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 34134cf1b8761..243cb5f6ade41 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -17,27 +17,32 @@ #include "gc-common.h" //JS funcs -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_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_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); + typedef void (*background_job_cb)(void); void mono_threads_schedule_background_job (background_job_cb cb); +#ifdef FEATURE_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_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_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); +#endif /* FEATURE_LEGACY_JS_INTEROP */ + void core_initialize_internals (void) { mono_add_internal_call ("System.Runtime.InteropServices.JavaScript.JSSynchronizationContext::ScheduleBackgroundJob", mono_threads_schedule_background_job); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 585386687c611..35944a6c9f97a 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.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 MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; +import FeatureWasmLegacyJsInterop from "consts:FeatureWasmLegacyJsInterop"; import { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, @@ -12,7 +12,7 @@ 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[] = !MonoWasmLegacyJsInterop ? [] : [ +const legacy_interop_cwraps: SigLine[] = !FeatureWasmLegacyJsInterop ? [] : [ [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"]], diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 1f4a9637926d1..01a0a1df4dd80 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -43,9 +43,6 @@ void core_initialize_internals (); extern void mono_wasm_set_entrypoint_breakpoint (const char* assembly_name, int method_token); -// 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); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index c9e758fc11814..d528d29cac905 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -106,7 +106,7 @@ if (process.env.MonoWasmThreads) { "mono_wasm_diagnostic_server_stream_signal_work_available", ] } -if (process.env.MonoWasmLegacyJsInterop) { +if (process.env.FeatureWasmLegacyJsInterop) { linked_functions = [...linked_functions, "mono_wasm_invoke_js_with_args_ref", "mono_wasm_get_object_property_ref", diff --git a/src/mono/wasm/runtime/exports-linker.ts b/src/mono/wasm/runtime/exports-linker.ts index d36c23b55e08d..6eba7d8bd87aa 100644 --- a/src/mono/wasm/runtime/exports-linker.ts +++ b/src/mono/wasm/runtime/exports-linker.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import MonoWasmThreads from "consts:monoWasmThreads"; -import MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; +import FeatureWasmLegacyJsInterop from "consts:FeatureWasmLegacyJsInterop"; import { mono_wasm_fire_debugger_agent_message, mono_wasm_debugger_log, mono_wasm_add_dbg_command_received, mono_wasm_set_entrypoint_breakpoint } from "./debug"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; import { mono_wasm_load_icu_data } from "./icu"; @@ -39,7 +39,7 @@ const mono_wasm_threads_exports = !MonoWasmThreads ? undefined : { mono_wasm_diagnostic_server_stream_signal_work_available, }; -const mono_wasm_legacy_interop_exports = !MonoWasmLegacyJsInterop ? undefined : { +const mono_wasm_legacy_interop_exports = !FeatureWasmLegacyJsInterop ? undefined : { // corebindings.c mono_wasm_invoke_js_with_args_ref, mono_wasm_get_object_property_ref, diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 734cc409b4cd4..6f19adaa47d32 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -5,7 +5,7 @@ import ProductVersion from "consts:productVersion"; import GitHash from "consts:gitHash"; import MonoWasmThreads from "consts:monoWasmThreads"; import BuildConfiguration from "consts:configuration"; -import MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; +import FeatureWasmLegacyJsInterop from "consts:FeatureWasmLegacyJsInterop"; 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"; @@ -42,13 +42,13 @@ function initializeImportsAndExports( // we want to have same instance of MONO, BINDING and Module in dotnet iffe set_imports_exports(imports, exports); - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { set_legacy_exports(exports); } init_polyfills(replacements); // here we merge methods from the local objects into exported objects - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { Object.assign(exports.mono, export_mono_api()); Object.assign(exports.binding, export_binding_api()); Object.assign(exports.internal, export_internal_api()); @@ -67,7 +67,7 @@ function initializeImportsAndExports( }, ...API, }); - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { Object.assign(exportedRuntimeAPI, { MONO: exports.mono, BINDING: exports.binding, @@ -94,7 +94,7 @@ function initializeImportsAndExports( if (imports.isGlobal || !module.disableDotnet6Compatibility) { Object.assign(module, exportedRuntimeAPI); - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { // backward compatibility // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js index e54f7dbcdff41..95cbe3e796e74 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 monoWasmLegacyJsInterop = process.env.MonoWasmLegacyJsInterop === "true" ? true : false; +const FeatureWasmLegacyJsInterop = process.env.FeatureWasmLegacyJsInterop === "true" ? true : false; const monoDiagnosticsMock = process.env.MonoDiagnosticsMock === "true" ? true : false; const terserConfig = { compress: { @@ -85,7 +85,7 @@ const typescriptConfigOptions = { include: ["**/*.ts", "../../../../artifacts/bin/native/generated/**/*.ts"] }; -const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock, gitHash, monoWasmLegacyJsInterop }), typescript(typescriptConfigOptions)]; +const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration, monoWasmThreads, monoDiagnosticsMock, gitHash, FeatureWasmLegacyJsInterop }), typescript(typescriptConfigOptions)]; const externalDependencies = [ ]; diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 9602bf2ad0ac3..cf8aae6ff1723 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -3,7 +3,7 @@ import BuildConfiguration from "consts:configuration"; import MonoWasmThreads from "consts:monoWasmThreads"; -import MonoWasmLegacyJsInterop from "consts:monoWasmLegacyJsInterop"; +import FeatureWasmLegacyJsInterop from "consts:FeatureWasmLegacyJsInterop"; import { CharPtrNull, DotnetModule, RuntimeAPI, MonoConfig, MonoConfigError, MonoConfigInternal } from "./types"; import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, Module, runtimeHelpers } from "./imports"; import cwraps, { init_c_exports } from "./cwraps"; @@ -294,7 +294,7 @@ function mono_wasm_pre_init_essential(): void { // init_polyfills() is already called from export.ts init_c_exports(); cwraps_internal(INTERNAL); - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { cwraps_mono_api(MONO); cwraps_binding_api(BINDING); } @@ -536,7 +536,7 @@ export function bindings_init(): void { try { const mark = startMeasure(); init_managed_exports(); - if (MonoWasmLegacyJsInterop) { + if (FeatureWasmLegacyJsInterop) { init_legacy_exports(); } initialize_marshalers_to_js(); diff --git a/src/mono/wasm/runtime/wasm-config.h.in b/src/mono/wasm/runtime/wasm-config.h.in index c5650ed200b45..d0e6c88d7f7aa 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 FEATURE_LEGACY_JS_INTEROP + #endif/*__MONO_WASM_CONFIG_H__*/ diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 6e3fed503b82e..423eabcb7669e 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -21,7 +21,8 @@ true false true - false + false + true @@ -279,7 +280,7 @@ $(CMakeBuildRuntimeConfigureCmd) -DWASM_OPT_ADDITIONAL_FLAGS="--enable-simd" $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=0 $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 - $(CMakeBuildRuntimeConfigureCmd) -DFEATURE_LEGACY_JS_INTEROP=1 + $(CMakeBuildRuntimeConfigureCmd) -DFEATURE_LEGACY_JS_INTEROP=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) @@ -323,7 +324,7 @@ SkipUnchangedFiles="true" /> - + @@ -400,7 +401,7 @@ - Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),MonoWasmLegacyJsInterop:$(MonoWasmLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock) + Configuration:$(Configuration),NativeBinDir:$(NativeBinDir),ProductVersion:$(ProductVersion),MonoWasmThreads:$(MonoWasmThreads),FeatureWasmLegacyJsInterop:$(FeatureWasmLegacyJsInterop),MonoDiagnosticsMock:$(MonoDiagnosticsMock) From 5afe1acaada0b94a01297507269c6201330cd725 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Wed, 4 Jan 2023 00:20:54 +0100 Subject: [PATCH 10/10] wip --- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 16 ++++++++-------- src/mono/wasm/runtime/logging.ts | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index d528d29cac905..6571786bb7960 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -4,20 +4,20 @@ "use strict"; -const usePThreads = process.env.MonoWasmThreads == "true"; -const isPThread = usePThreads ? "ENVIRONMENT_IS_PTHREAD" : "false"; +const monoWasmThreads = process.env.MonoWasmThreads == "true"; +const featureWasmLegacyJsInterop = process.env.FeatureWasmLegacyJsInterop === "true"; +const isPThread = monoWasmThreads ? "ENVIRONMENT_IS_PTHREAD" : "false"; const DotnetSupportLib = { $DOTNET: {}, - // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE + // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IIFE // Emscripten uses require function for nodeJS even in ES6 module. We need https://nodejs.org/api/module.html#modulecreaterequirefilename // We use dynamic import because there is no "module" module in the browser. // This is async init of it, note it would become available only after first tick. // Also fix of scriptDirectory would be delayed - // 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: ` -${usePThreads ? ` +${monoWasmThreads ? ` let __dotnet_replacement_PThread = { loadWasmModuleToWorker: PThread.loadWasmModuleToWorker, threadInitTLS: PThread.threadInitTLS, @@ -43,7 +43,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; @@ -96,7 +96,7 @@ let linked_functions = [ "mono_wasm_load_icu_data", ]; -if (process.env.MonoWasmThreads) { +if (monoWasmThreads) { linked_functions = [...linked_functions, /// mono-threads-wasm.c "mono_wasm_pthread_on_pthread_attached", @@ -106,7 +106,7 @@ if (process.env.MonoWasmThreads) { "mono_wasm_diagnostic_server_stream_signal_work_available", ] } -if (process.env.FeatureWasmLegacyJsInterop) { +if (featureWasmLegacyJsInterop) { linked_functions = [...linked_functions, "mono_wasm_invoke_js_with_args_ref", "mono_wasm_get_object_property_ref", diff --git a/src/mono/wasm/runtime/logging.ts b/src/mono/wasm/runtime/logging.ts index cdb2d00dba723..bb06aaa68beca 100644 --- a/src/mono/wasm/runtime/logging.ts +++ b/src/mono/wasm/runtime/logging.ts @@ -1,5 +1,5 @@ -//! Licensed to the .NET Foundation under one or more agreements. -//! The .NET Foundation licenses this file to you under the MIT license. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. import BuildConfiguration from "consts:configuration"; import { INTERNAL, Module, runtimeHelpers } from "./imports";