From 0a6c9048f6078b3880e68771bcdf74ca1c5067aa Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 7 Dec 2021 21:44:33 +0100 Subject: [PATCH 001/128] Initial changes for emscripten 2.0.34 --- src/mono/mono/mini/mini-wasm.c | 37 ---------------------- src/mono/wasm/build/WasmApp.Native.targets | 1 + src/mono/wasm/emscripten-version.txt | 2 +- src/mono/wasm/runtime/CMakeLists.txt | 4 +-- src/mono/wasm/wasm.proj | 33 +++++++++++++------ 5 files changed, 27 insertions(+), 50 deletions(-) diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 2b5e7bc22c6640..1edaae4d615ab5 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -676,8 +676,6 @@ mono_arch_patch_code_new (MonoCompile *cfg, guint8 *code, MonoJumpInfo *ji, gpoi G_BEGIN_DECLS -void * getgrnam (const char *name); -void * getgrgid (gid_t gid); int inotify_init (void); int inotify_rm_watch (int fd, int wd); int inotify_add_watch (int fd, const char *pathname, uint32_t mask); @@ -707,13 +705,6 @@ pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *pa return 0; } -int -pthread_sigmask (int how, const sigset_t *set, sigset_t *oset) -{ - return 0; -} - - int sigsuspend(const sigset_t *sigmask) { @@ -727,18 +718,6 @@ getdtablesize (void) return 256; //random constant that is the fd limit } -void * -getgrnam (const char *name) -{ - return NULL; -} - -void * -getgrgid (gid_t gid) -{ - return NULL; -} - int inotify_init (void) { @@ -776,22 +755,6 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) return -1; } -int -getpwnam_r (const char *name, struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ - *result = NULL; - return ENOTSUP; -} - -int -getpwuid_r (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ - *result = NULL; - return ENOTSUP; -} - G_END_DECLS /* Helper for runtime debugging */ diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index ea282f9638cf1e..a82cfc860f01a3 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -216,6 +216,7 @@ <_EmccLDFlags Include="$(EmccLinkOptimizationFlag)" /> <_EmccLDFlags Include="@(_EmccCommonFlags)" /> + <_EmccLDFlags Include="-Wl,--allow-undefined" /> <_EmccLDFlags Include="-s TOTAL_MEMORY=$(EmccTotalMemory)" /> diff --git a/src/mono/wasm/emscripten-version.txt b/src/mono/wasm/emscripten-version.txt index 8fe1046e01fc8e..59ef4a7aa83773 100644 --- a/src/mono/wasm/emscripten-version.txt +++ b/src/mono/wasm/emscripten-version.txt @@ -1 +1 @@ -2.0.23 \ No newline at end of file +2.0.34 \ No newline at end of file diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index 9721e39682c9ba..955228621ab938 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -6,7 +6,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}) -target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.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 -DCORE_BINDINGS -DGEN_PINVOKE=1) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_EMCC_FLAGS}) @@ -25,7 +25,7 @@ target_link_libraries(dotnet set_target_properties(dotnet PROPERTIES LINK_DEPENDS "${NATIVE_BIN_DIR}/src/emcc-default.rsp;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js;${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js;${NATIVE_BIN_DIR}/src/pal_random.lib.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js;${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js;" - LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --extern-pre-js ${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js --js-library ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js " + LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} -DENABLE_NETCORE=1 --extern-pre-js ${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js --js-library ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js " RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}") if(CMAKE_BUILD_TYPE STREQUAL "Release") diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 5340cefff55a5d..4d0f4b78f62db7 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -12,6 +12,8 @@ emcc $(ArtifactsObjDir)wasm <_EmccDefaultsRspPath>$(NativeBinDir)src\emcc-default.rsp + <_EmccCompileRspPath>$(NativeBinDir)src\emcc-compile.rsp + <_EmccLinkRspPath>$(NativeBinDir)src\emcc-link.rsp false @@ -64,17 +66,18 @@ - <_EmccCommonFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> - <_EmccCommonFlags Include="-s NO_EXIT_RUNTIME=1" /> - <_EmccCommonFlags Include="-s FORCE_FILESYSTEM=1" /> - <_EmccCommonFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" /> - <_EmccCommonFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" /> - <_EmccCommonFlags Include="--source-map-base http://example.com" /> - - <_EmccCommonFlags Include="-s STRICT_JS=1" /> - <_EmccCommonFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> - <_EmccCommonFlags Include="-s MODULARIZE=1"/> <_EmccCommonFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> + + <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> + <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> + <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> + <_EmccLinkFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" /> + <_EmccLinkFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" /> + <_EmccLinkFlags Include="--source-map-base http://example.com" /> + <_EmccLinkFlags Include="-s STRICT_JS=1" /> + <_EmccLinkFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> + <_EmccLinkFlags Include="-s MODULARIZE=1"/> + <_EmccLinkFlags Include="-Wl,--allow-undefined"/> @@ -91,6 +94,14 @@ Lines="@(_EmccFlags)" WriteOnlyWhenDifferent="true" Overwrite="true" /> + + @@ -217,6 +228,8 @@ From 1c2f9899dadde43111c82f2c74ea2be002761990 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 8 Dec 2021 13:34:24 +0100 Subject: [PATCH 002/128] Use emcc-link.rsp in build targets --- src/mono/wasm/build/WasmApp.Native.targets | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index a82cfc860f01a3..abb9468edec19e 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -151,6 +151,7 @@ <_MonoAotCrossCompilerPath>@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','browser-wasm')) <_EmccDefaultFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-default.rsp')) + <_EmccDefaultLinkFlagsRsp>$([MSBuild]::NormalizePath($(_WasmRuntimePackSrcDir), 'emcc-link.rsp')) false true true @@ -392,14 +393,14 @@ - + From f74d8b9eff79b9b26937c582a9ac0eac3582e304 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 8 Dec 2021 15:45:43 +0100 Subject: [PATCH 003/128] Use updated docker images --- eng/pipelines/common/platform-matrix.yml | 2 +- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index ad3dbd4db8bc0d..0584fce6656ec5 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -279,7 +279,7 @@ jobs: targetRid: browser-wasm platform: Browser_wasm container: - image: ubuntu-18.04-webassembly-20210531091624-f5c7a43 + image: ubuntu-18.04-webassembly-20211208134944-544b18c registry: mcr jobParameters: runtimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 73432c9c408b1a..7d4a56976e39c7 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -185,6 +185,6 @@ jobs: # WebAssembly windows - ${{ if eq(parameters.platform, 'Browser_wasm_win') }}: - - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-webassembly-amd64-20210702131541-6837048 + - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-webassembly-amd64-20211208140215-544b18c ${{ insert }}: ${{ parameters.jobParameters }} From 20f59e58d3cd764246b8d6f12f19d11fa484a8a7 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 9 Dec 2021 16:58:02 +0100 Subject: [PATCH 004/128] Fix compiler warnings Co-authored-by: Zoltan Varga --- src/mono/mono/component/debugger-agent.c | 11 +++++++++-- src/mono/mono/metadata/seq-points-data.c | 5 ++++- src/mono/mono/metadata/sre-encode.c | 9 +++------ src/mono/mono/mini/aot-runtime.c | 8 ++++++-- src/mono/mono/mini/driver.c | 11 +++++++++-- src/mono/mono/mini/mini-generic-sharing.c | 7 ++++++- src/mono/mono/mini/mini-runtime.c | 4 ++-- src/mono/mono/mini/mini-wasm.c | 3 +-- src/mono/mono/sgen/sgen-gc.h | 1 + src/mono/mono/sgen/sgen-workers.h | 2 +- src/mono/mono/utils/mono-mmap-wasm.c | 5 ++--- 11 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 98a51b33f52594..5d733d344f27ad 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -433,7 +433,7 @@ MonoDefaults *mdbg_mono_defaults; DebuggerTlsData *tls; \ tls = (DebuggerTlsData *)mono_native_tls_get_value (debugger_tls_id); #else -#define GET_TLS_DATA_FROM_THREAD(thread) \ +#define GET_TLS_DATA_FROM_THREAD(...) \ DebuggerTlsData *tls; \ tls = &debugger_wasm_thread; #define GET_DEBUGGER_TLS() \ @@ -9135,7 +9135,9 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) int objid; ErrorCode err; MonoThread *thread_obj; +#ifndef TARGET_WASM MonoInternalThread *thread; +#endif int pos, i, len, frame_idx; StackFrame *frame; MonoDebugMethodJitInfo *jit; @@ -9149,11 +9151,16 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (err != ERR_NONE) return err; +#ifndef TARGET_WASM thread = THREAD_TO_INTERNAL (thread_obj); - +#endif id = decode_id (p, &p, end); +#ifndef TARGET_WASM GET_TLS_DATA_FROM_THREAD (thread); +#else + GET_TLS_DATA_FROM_THREAD (); +#endif g_assert (tls); for (i = 0; i < tls->frame_count; ++i) { diff --git a/src/mono/mono/metadata/seq-points-data.c b/src/mono/mono/metadata/seq-points-data.c index 308435993793c5..d70d43fb5d48da 100644 --- a/src/mono/mono/metadata/seq-points-data.c +++ b/src/mono/mono/metadata/seq-points-data.c @@ -409,7 +409,10 @@ mono_seq_point_data_read (SeqPointData *data, char *path) fseek(f, 0, SEEK_SET); buffer_orig = buffer = (guint8 *)g_malloc (fsize + 1); - fread(buffer_orig, fsize, 1, f); + size_t items = fread(buffer_orig, fsize, 1, f); + if (items != 1) + return FALSE; + fclose(f); entry_count = decode_var_int (buffer, &buffer); diff --git a/src/mono/mono/metadata/sre-encode.c b/src/mono/mono/metadata/sre-encode.c index 450b6f37d72d39..92a6376dba702f 100644 --- a/src/mono/mono/metadata/sre-encode.c +++ b/src/mono/mono/metadata/sre-encode.c @@ -422,7 +422,7 @@ mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType * HANDLE_FUNCTION_ENTER (); MonoDynamicTable *table; - guint32 token, enclosing; + guint32 token; MonoClass *klass; /* if the type requires a typespec, we must try that first*/ @@ -446,11 +446,8 @@ mono_dynimage_encode_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType * goto leave; } - if (m_class_get_nested_in (klass)) { - enclosing = mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (m_class_get_nested_in (klass)), FALSE); - /* get the typeref idx of the enclosing type */ - enclosing >>= MONO_TYPEDEFORREF_BITS; - } + if (m_class_get_nested_in (klass)) + mono_dynimage_encode_typedef_or_ref_full (assembly, m_class_get_byval_arg (m_class_get_nested_in (klass)), FALSE); table = &assembly->tables [MONO_TABLE_TYPEREF]; token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */ g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token)); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index dbb35bd6209203..45ca9c1e26a0aa 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -2658,7 +2658,7 @@ compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **c #ifdef HOST_WASM gsize min = 1 << 30, max = 0; - gsize prev = 0; + //gsize prev = 0; // FIXME: This depends on emscripten allocating ftnptr ids sequentially for (int i = 0; i < amodule->info.nmethods; ++i) { @@ -2672,7 +2672,7 @@ compute_llvm_code_range (MonoAotModule *amodule, guint8 **code_start, guint8 **c min = val; else if (val > max) max = val; - prev = val; + //prev = val; } } if (max) { @@ -5678,12 +5678,16 @@ get_new_unbox_arbitrary_trampoline_frome_page (gpointer addr) static gpointer get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size) { +#ifndef DISABLE_ASSERT_MESSAGES MonoImage *image; +#endif MonoAotModule *amodule = get_mscorlib_aot_module (); int index, tramp_size; +#ifndef DISABLE_ASSERT_MESSAGES /* Currently, we keep all trampolines in the mscorlib AOT image */ image = mono_defaults.corlib; +#endif *out_amodule = amodule; diff --git a/src/mono/mono/mini/driver.c b/src/mono/mono/mini/driver.c index a249b3d6d3678c..ba1fa81246ad2d 100644 --- a/src/mono/mono/mini/driver.c +++ b/src/mono/mono/mini/driver.c @@ -2067,9 +2067,12 @@ mono_main (int argc, char* argv[]) MonoDomain *domain; MonoImageOpenStatus open_status; const char* aname, *mname = NULL; - int i, count = 1; - guint32 opt, action = DO_EXEC, recompilation_times = 1; + int i; +#ifndef DISABLE_JIT + int count = 1; MonoGraphOptions mono_graph_options = (MonoGraphOptions)0; +#endif + guint32 opt, action = DO_EXEC, recompilation_times = 1; int mini_verbose_level = 0; char *trace_options = NULL; char *aot_options = NULL; @@ -2222,6 +2225,7 @@ mono_main (int argc, char* argv[]) } else if (strcmp (argv [i], "--mixed-mode") == 0) { mixed_mode = TRUE; #endif +#ifndef DISABLE_JIT } else if (strcmp (argv [i], "--ncompile") == 0) { if (i + 1 >= argc){ fprintf (stderr, "error: --ncompile requires an argument\n"); @@ -2229,6 +2233,7 @@ mono_main (int argc, char* argv[]) } count = atoi (argv [++i]); action = DO_BENCH; +#endif } else if (strcmp (argv [i], "--trace") == 0) { trace_options = (char*)""; } else if (strncmp (argv [i], "--trace=", 8) == 0) { @@ -2346,6 +2351,7 @@ mono_main (int argc, char* argv[]) mname = argv [++i]; action = DO_BENCH; +#ifndef DISABLE_JIT } else if (strncmp (argv [i], "--graph=", 8) == 0) { if (i + 1 >= argc){ fprintf (stderr, "error: --graph option requires a method name argument\n"); @@ -2364,6 +2370,7 @@ mono_main (int argc, char* argv[]) mname = argv [++i]; mono_graph_options = MONO_GRAPH_CFG; action = DO_DRAW; +#endif } else if (strcmp (argv [i], "--debug") == 0) { enable_debugging = TRUE; } else if (strncmp (argv [i], "--debug=", 8) == 0) { diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index e69da90cfb055f..3b57f01f4a92ba 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -1738,7 +1738,9 @@ mini_get_interp_in_wrapper (MonoMethodSignature *sig) static GHashTable *cache; const char *name; gboolean generic = FALSE; +#ifndef DISABLE_JIT gboolean return_native_struct; +#endif sig = mini_get_underlying_reg_signature (sig); @@ -1762,7 +1764,10 @@ mini_get_interp_in_wrapper (MonoMethodSignature *sig) * stack, pass this address to the interp_entry and when we return it we use * CEE_MONO_LDNATIVEOBJ */ - return_native_struct = sig->ret->type == MONO_TYPE_VALUETYPE && sig->pinvoke; +#ifndef DISABLE_JIT + return_native_struct = +#endif + sig->ret->type == MONO_TYPE_VALUETYPE && sig->pinvoke; /* Create the signature for the wrapper */ csig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + (sig->param_count * sizeof (MonoType*))); diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index c48380c08748e9..ab085d7216cc10 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3278,7 +3278,7 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void static MonoObject* mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error) { - MonoMethod *invoke, *callee; + MonoMethod *callee; MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method); RuntimeInvokeInfo *info, *info2; MonoJitInfo *ji = NULL; @@ -3321,7 +3321,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoMethod *wrapper; wrapper = mono_marshal_get_array_accessor_wrapper (method); - invoke = mono_marshal_get_runtime_invoke (wrapper, FALSE); + mono_marshal_get_runtime_invoke (wrapper, FALSE); callee = wrapper; } else { callee = NULL; diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 1edaae4d615ab5..739d030cf805ec 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -247,7 +247,6 @@ mono_arch_create_vars (MonoCompile *cfg) { MonoMethodSignature *sig; CallInfo *cinfo; - MonoType *sig_ret; sig = mono_method_signature_internal (cfg->method); @@ -258,7 +257,7 @@ mono_arch_create_vars (MonoCompile *cfg) // if (cinfo->ret.storage == ArgValuetypeInReg) // cfg->ret_var_is_local = TRUE; - sig_ret = mini_get_underlying_type (sig->ret); + mini_get_underlying_type (sig->ret); if (cinfo->ret.storage == ArgValuetypeAddrInIReg || cinfo->ret.storage == ArgGsharedVTOnStack) { cfg->vret_addr = mono_compile_create_var (cfg, mono_get_int_type (), OP_ARG); if (G_UNLIKELY (cfg->verbose_level > 1)) { diff --git a/src/mono/mono/sgen/sgen-gc.h b/src/mono/mono/sgen/sgen-gc.h index b5b91c9a2eec77..04a40afefc4dec 100644 --- a/src/mono/mono/sgen/sgen-gc.h +++ b/src/mono/mono/sgen/sgen-gc.h @@ -1222,6 +1222,7 @@ sgen_dummy_use (gpointer v) { #if defined(_MSC_VER) || defined(HOST_WASM) static volatile gpointer ptr; + (void)ptr; // avoid compiler warning: variable 'ptr' set but not used ptr = v; #elif defined(__GNUC__) __asm__ volatile ("" : "=r"(v) : "r"(v)); diff --git a/src/mono/mono/sgen/sgen-workers.h b/src/mono/mono/sgen/sgen-workers.h index 577466ea3c325d..cb42d695aee895 100644 --- a/src/mono/mono/sgen/sgen-workers.h +++ b/src/mono/mono/sgen/sgen-workers.h @@ -81,7 +81,7 @@ void sgen_workers_set_num_active_workers (int generation, int num_workers); #ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC void sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job); #else -#define sgen_workers_start_all_workers(...) +#define sgen_workers_start_all_workers(generation, object_ops_nopar, object_ops_par, finish_job) (void)object_ops_par; // avoid compiler warning: variable 'object_ops_par' set but not used #endif void sgen_workers_enqueue_job (int generation, SgenThreadPoolJob *job, gboolean enqueue); diff --git a/src/mono/mono/utils/mono-mmap-wasm.c b/src/mono/mono/utils/mono-mmap-wasm.c index b04d69ab1b5e2b..8f2feb6af98f1c 100644 --- a/src/mono/mono/utils/mono-mmap-wasm.c +++ b/src/mono/mono/utils/mono-mmap-wasm.c @@ -154,7 +154,6 @@ int mono_vfree (void *addr, size_t length, MonoMemAccountType type) { VallocInfo *info = (VallocInfo*)(valloc_hash ? g_hash_table_lookup (valloc_hash, addr) : NULL); - int res; if (info) { /* @@ -162,13 +161,13 @@ mono_vfree (void *addr, size_t length, MonoMemAccountType type) * mono_valloc_align (), free the original mapping. */ BEGIN_CRITICAL_SECTION; - res = munmap (info->addr, info->size); + munmap (info->addr, info->size); END_CRITICAL_SECTION; g_free (info); g_hash_table_remove (valloc_hash, addr); } else { BEGIN_CRITICAL_SECTION; - res = munmap (addr, length); + munmap (addr, length); END_CRITICAL_SECTION; } From 31197d9a9f056300f9e820effe77832d00e56615 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 9 Dec 2021 19:25:40 +0100 Subject: [PATCH 005/128] Put `--profiling-funcs` to `_EmccLinkFlags` --- src/mono/wasm/wasm.proj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 4d0f4b78f62db7..469967cdbdf630 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -81,7 +81,7 @@ - <_EmccFlags Include="--profiling-funcs" /> + <_EmccLinkFlags Include="--profiling-funcs" /> <_EmccFlags Include="@(_EmccCommonFlags)" /> From 2063241b0ce55d961efa91a0fc5148ef390cd11c Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 9 Dec 2021 22:16:01 +0100 Subject: [PATCH 006/128] Fix build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/mono/mono/mini/mini-runtime.c:3407:25: error: ‘invoke’ undeclared (first use in this function); did you mean ‘revoke’? 3407 | invoke = mono_marshal_get_runtime_invoke_dynamic (); --- src/mono/mono/mini/mini-runtime.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index ab085d7216cc10..49aa7e3055404b 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -3397,8 +3397,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec static RuntimeInvokeDynamicFunction dyn_runtime_invoke = NULL; if (info->dyn_call_info) { if (!dyn_runtime_invoke) { - invoke = mono_marshal_get_runtime_invoke_dynamic (); - RuntimeInvokeDynamicFunction invoke_func = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (invoke, error); + MonoMethod *dynamic_invoke = mono_marshal_get_runtime_invoke_dynamic (); + RuntimeInvokeDynamicFunction invoke_func = (RuntimeInvokeDynamicFunction)mono_jit_compile_method_jit_only (dynamic_invoke, error); mono_memory_barrier (); dyn_runtime_invoke = invoke_func; if (!dyn_runtime_invoke && mono_use_interpreter) { From 6aed1c531d6ebcddd2f9efaf097fd31fe38a81fc Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 13 Dec 2021 10:40:00 +0100 Subject: [PATCH 007/128] Add shell to the environment Environment setting https://github.com/emscripten-core/emscripten/blob/2.0.34/src/settings.js#L616-L641 From emscripten 2.0.25 release notes - Support for the 'shell' environment is now disabled by default. Running under `d8`, `js`, or `jsc` is not something that most emscripten users ever want to do, so including the support code is, more often than not, unnecessary. Users who want shell support can enable it by including 'shell' in `-s ENVIRONMENT` (#14535). Example of the the size increase for bench sample: -a--- 12/10/2021 3:35 PM 382113 dotnet.js -a--- 12/13/2021 10:37 AM 383589 dotnet.js --- src/mono/wasm/wasm.proj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 469967cdbdf630..172f0773f9f770 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -78,6 +78,7 @@ <_EmccLinkFlags Include="-s EXPORT_NAME="'createDotnetRuntime'"" /> <_EmccLinkFlags Include="-s MODULARIZE=1"/> <_EmccLinkFlags Include="-Wl,--allow-undefined"/> + <_EmccLinkFlags Include="-s ENVIRONMENT="web,webview,worker,node,shell"" /> From 11e2ce53a0293345b6aff5a3a6dc5634043999c2 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 4 Jan 2022 17:47:54 +0100 Subject: [PATCH 008/128] Add emcc-link.rsp to PlatformManifestFileEntry --- .../pkg/sfx/Microsoft.NETCore.App/Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index f122fd1fcf526d..e94c73bb92386f 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -235,6 +235,7 @@ + From 3eb44cf745fbdb8782352d306de3d0ca1a05d041 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Fri, 7 Jan 2022 21:09:25 +0100 Subject: [PATCH 009/128] Feedback https://github.com/emscripten-core/emscripten/blob/2fda25eea756c78c8cb024aa5b6c2b188bf7990f/src/settings.js#L1173-L1176 -s EXPORT_ES6 is link option --- src/mono/wasm/wasm.proj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 72ca75842b3952..fe1e7a43cb0bb5 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -66,8 +66,7 @@ - <_EmccCommonFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> - + <_EmccLinkFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> From 460d09a561fdd0ede1cf5190d733ba9dc3c72090 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 17 Jan 2022 18:05:41 +0100 Subject: [PATCH 010/128] Bump emscripten version --- src/mono/wasm/emscripten-version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/emscripten-version.txt b/src/mono/wasm/emscripten-version.txt index 59ef4a7aa83773..50e47c89cafc3e 100644 --- a/src/mono/wasm/emscripten-version.txt +++ b/src/mono/wasm/emscripten-version.txt @@ -1 +1 @@ -2.0.34 \ No newline at end of file +3.1.1 \ No newline at end of file From 6f7d0c2736f2c005d1c41b4cd3e2e845c0482756 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Mon, 17 Jan 2022 18:05:55 +0100 Subject: [PATCH 011/128] Bump llvm package version and use its libclang --- eng/Versions.props | 16 ++++++++-------- src/mono/mono.proj | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 449e76bc7c77a0..be5fcb3ee9c2f3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -183,14 +183,14 @@ 7.0.0-alpha.1.21529.3 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 - 11.1.0-alpha.1.21615.1 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 + 11.1.0-alpha.1.22064.2 7.0.0-alpha.1.21601.1 $(MicrosoftNETWorkloadEmscriptenManifest70100Version) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index c7febf933f5c97..0b4e28deacb911 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -589,9 +589,9 @@ true wasm32-unknown-none $(MonoObjCrossDir)offsets-wasm32-unknown-none.h - $(EMSDK_PATH)/upstream/lib/libclang.dylib - $(EMSDK_PATH)/upstream/lib/libclang.so - $([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'upstream', 'bin', 'libclang.dll')) + $(MonoAOTLLVMDir)/lib/libclang.dylib + $(MonoAOTLLVMDir)/lib/libclang.so + $([MSBuild]::NormalizePath('$(MonoAOTLLVMDir)', 'bin', 'libclang.dll')) setlocal EnableDelayedExpansion && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && !EMSDK_PYTHON! <_ForceRelease Condition="$([MSBuild]::IsOSPlatform('Windows')) and '$(TargetArchitecture)' == 'wasm' and '$(Configuration)' == 'Debug'">true From e089ab100d533147f423a904f44af61dd6479869 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 19 Jan 2022 17:03:55 +0100 Subject: [PATCH 012/128] Use newer docker images with emscripten 3.1.1 --- eng/pipelines/common/platform-matrix.yml | 2 +- eng/pipelines/libraries/helix-queues-setup.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/common/platform-matrix.yml b/eng/pipelines/common/platform-matrix.yml index 0584fce6656ec5..a8a77b5e6188d2 100644 --- a/eng/pipelines/common/platform-matrix.yml +++ b/eng/pipelines/common/platform-matrix.yml @@ -279,7 +279,7 @@ jobs: targetRid: browser-wasm platform: Browser_wasm container: - image: ubuntu-18.04-webassembly-20211208134944-544b18c + image: ubuntu-18.04-webassembly-20220118141522-180197c registry: mcr jobParameters: runtimeFlavor: ${{ parameters.runtimeFlavor }} diff --git a/eng/pipelines/libraries/helix-queues-setup.yml b/eng/pipelines/libraries/helix-queues-setup.yml index 8fa6388d1e2d50..1991b922f75589 100644 --- a/eng/pipelines/libraries/helix-queues-setup.yml +++ b/eng/pipelines/libraries/helix-queues-setup.yml @@ -187,6 +187,6 @@ jobs: # WebAssembly windows - ${{ if eq(parameters.platform, 'Browser_wasm_win') }}: - - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-2004-helix-webassembly-amd64-20211208140215-544b18c + - (Windows.Server.Core.1909.Amd64.Open)windows.10.amd64.server20h1.open@mcr.microsoft.com/dotnet-buildtools/prereqs:windowsservercore-ltsc2022-helix-webassembly-20220118164817-dc6e6f1 ${{ insert }}: ${{ parameters.jobParameters }} From 01c9516cd6479d1b4ad80bc110f7a756bd548b8f Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 20 Jan 2022 15:59:13 +0100 Subject: [PATCH 013/128] Remove unused variable --- src/mono/mono/component/hot_reload.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index e44ae56e5f4afe..42b07d6d488a3d 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -1692,9 +1692,6 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen #if defined(ALLOW_METHOD_ADD) || defined(ALLOW_FIELD_ADD) MonoClass *add_member_klass = NULL; #endif -#ifdef ALLOW_METHOD_ADD - uint32_t add_param_method_index = 0; -#endif gboolean assemblyref_updated = FALSE; for (int i = 0; i < rows ; ++i) { @@ -1731,7 +1728,6 @@ apply_enclog_pass2 (MonoImage *image_base, BaselineInfo *base_info, uint32_t gen case ENC_FUNC_ADD_PARAM: { g_assert (token_table == MONO_TABLE_METHOD); - add_param_method_index = token_index; break; } #endif From 731818aeea6d1322a3ac72ee6eee975c3710c2c3 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Tue, 25 Jan 2022 17:35:04 -0500 Subject: [PATCH 014/128] Add runtime support for threads in the wasm build To enable, pass `/p:WasmEnableThreads` when building the runtime ./build.sh -Subset mono+libs -os Browser -arch wasm /p:WasmEnableThreads=true --- .../src/System/Threading/Thread.cs | 13 +++++----- .../ref/System.Threading.Thread.cs | 8 +++--- .../ApiCompatBaseline.PreviousNetCoreApp.txt | 15 ++++++++++- .../System.Private.CoreLib.csproj | 2 +- src/mono/cmake/configure.cmake | 2 ++ src/mono/mono.proj | 11 ++++++-- src/mono/mono/utils/memfuncs.c | 2 +- src/mono/sample/wasm/browser/Program.cs | 25 +++++++++++++++++++ src/mono/sample/wasm/browser/index.html | 1 + src/mono/sample/wasm/browser/main.js | 2 +- src/mono/sample/wasm/wasm.mk | 6 ++--- src/mono/wasm/runtime/driver.c | 7 ++++++ src/mono/wasm/wasm.proj | 7 +++++- 13 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index 43c30ecbfcf810..0f7340ee8dc386 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -163,8 +163,7 @@ public Thread(ParameterizedThreadStart start, int maxStackSize) Initialize(); } -#if !TARGET_BROWSER - [UnsupportedOSPlatformGuard("browser")] +// [UnsupportedOSPlatformGuard("browser")] internal static bool IsThreadStartSupported => true; /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. @@ -172,7 +171,7 @@ public Thread(ParameterizedThreadStart start, int maxStackSize) /// The thread has already been started. /// There is not enough memory available to start this thread. /// This thread was created using a delegate instead of a delegate. - [UnsupportedOSPlatform("browser")] +// [UnsupportedOSPlatform("browser")] public void Start(object? parameter) => Start(parameter, captureContext: true); /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. @@ -184,7 +183,7 @@ public Thread(ParameterizedThreadStart start, int maxStackSize) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// - [UnsupportedOSPlatform("browser")] +// [UnsupportedOSPlatform("browser")] public void UnsafeStart(object? parameter) => Start(parameter, captureContext: false); private void Start(object? parameter, bool captureContext) @@ -211,7 +210,7 @@ private void Start(object? parameter, bool captureContext) /// Causes the operating system to change the state of the current instance to . /// The thread has already been started. /// There is not enough memory available to start this thread. - [UnsupportedOSPlatform("browser")] +// [UnsupportedOSPlatform("browser")] public void Start() => Start(captureContext: true); /// Causes the operating system to change the state of the current instance to . @@ -221,7 +220,7 @@ private void Start(object? parameter, bool captureContext) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// - [UnsupportedOSPlatform("browser")] +// [UnsupportedOSPlatform("browser")] public void UnsafeStart() => Start(captureContext: false); private void Start(bool captureContext) @@ -238,7 +237,7 @@ private void Start(bool captureContext) StartCore(); } -#endif +//#endif private void RequireCurrentThread() { diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs index c34b32cc8aff71..f498c6b39b4eb1 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs @@ -89,16 +89,16 @@ public static void SetData(System.LocalDataStoreSlot slot, object? data) { } public static void Sleep(int millisecondsTimeout) { } public static void Sleep(System.TimeSpan timeout) { } public static void SpinWait(int iterations) { } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public void Start() { } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public void Start(object? parameter) { } [System.ObsoleteAttribute("Thread.Suspend has been deprecated. Use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.")] public void Suspend() { } public bool TrySetApartmentState(System.Threading.ApartmentState state) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public void UnsafeStart() { } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public void UnsafeStart(object? parameter) { } public static byte VolatileRead(ref byte address) { throw null; } public static double VolatileRead(ref double address) { throw null; } diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index f408c36427e63e..e413b0172741de 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -27,6 +27,10 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. Compat issues with assembly netstandard: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -75,6 +79,10 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. Compat issues with assembly System: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -138,4 +146,9 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. -Total Issues: 132 +Compat issues with assembly System.Threading.Thread: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. +Total Issues: 144 diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index d952686ac56b89..2c82625c174e52 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -290,7 +290,7 @@ - + diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index ee6224390fa616..c1a4124c9b3379 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -110,6 +110,8 @@ ac_check_funcs( check_symbol_exists(madvise "sys/mman.h" HAVE_MADVISE) check_symbol_exists(pthread_mutexattr_setprotocol "pthread.h" HAVE_DECL_PTHREAD_MUTEXATTR_SETPROTOCOL) +check_symbol_exists(pthread_getattr_np "pthread.h" HAVE_PTHREAD_GETATTR_NP) +check_symbol_exists(pthread_create "pthread.h" HAVE_STEVE_PTHREAD_CHECK) check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC) check_symbol_exists(CLOCK_MONOTONIC_COARSE "time.h" HAVE_CLOCK_MONOTONIC_COARSE) check_symbol_exists(sys_signame "signal.h" HAVE_SYSSIGNAME) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index fb54e713f3313f..f63e00410136b6 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -321,17 +321,24 @@ <_MonoMinimal Condition="'$(Configuration)' == 'Release'">,debugger_agent,log_dest <_MonoMinimal Condition="'$(Configuration)' == 'Release' and '$(MonoEnableAssertMessages)' != 'true'">$(_MonoMinimal),assert_messages + <_MonoMinimal Condition="'$(WasmEnableThreads)' == ''">$(_MonoMinimal),threads - <_MonoCMakeArgs Include="-DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,shared_perfcounters,interpreter,threads,qcalls$(_MonoMinimal)"/> + <_MonoCMakeArgs Include="-DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,shared_perfcounters,interpreter,qcalls$(_MonoMinimal)"/> <_MonoCMakeArgs Include="-DENABLE_INTERP_LIB=1"/> <_MonoCMakeArgs Include="-DDISABLE_ICALL_TABLES=1"/> <_MonoCMakeArgs Include="-DENABLE_ICALL_EXPORT=1"/> <_MonoCMakeArgs Include="-DENABLE_LAZY_GC_THREAD_CREATION=1"/> <_MonoCMakeArgs Include="-DENABLE_LLVM_RUNTIME=1"/> <_MonoCFLAGS Include="-fexceptions"/> + <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-pthread"/> + <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> <_MonoCXXFLAGS Include="-fexceptions"/> - <_MonoCFLAGS Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/> + <_MonoCXXFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-pthread"/> + <_MonoCXXFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> + <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include'))$(EscapedQuoteW)"/> + + <_MonoCFLAGS Condition="'$(WasmEnableThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/> diff --git a/src/mono/mono/utils/memfuncs.c b/src/mono/mono/utils/memfuncs.c index 4fc78079626abc..e95553ba9aa71a 100644 --- a/src/mono/mono/utils/memfuncs.c +++ b/src/mono/mono/utils/memfuncs.c @@ -53,7 +53,7 @@ #define unaligned_bytes(ptr) (_toi(ptr) & ptr_mask) #define align_down(ptr) ((void*)(_toi(ptr) & ~ptr_mask)) #define align_up(ptr) ((void*) ((_toi(ptr) + ptr_mask) & ~ptr_mask)) -#if SIZEOF_VOID_P == 4 +#if SIZEOF_VOID_P == 4 || SIZEOF_VOID_P == 7 #define bytes_to_words(n) ((size_t)(n) >> 2) #elif SIZEOF_VOID_P == 8 #define bytes_to_words(n) ((size_t)(n) >> 3) diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser/Program.cs index 743f481896fcb5..c552b8ecf3673a 100644 --- a/src/mono/sample/wasm/browser/Program.cs +++ b/src/mono/sample/wasm/browser/Program.cs @@ -3,6 +3,8 @@ using System; using System.Runtime.CompilerServices; +using System.Collections.Generic; +using System.Threading; namespace Sample { @@ -16,7 +18,30 @@ public static void Main(string[] args) [MethodImpl(MethodImplOptions.NoInlining)] public static int TestMeaning() { + List myList = new List{ 1, 2, 3, 4 }; + Console.WriteLine(myList); + + Thread t = new Thread(new ThreadStart(ThreadFuncTest)); + t.Start(); + + for (int i = 0; i < 4; i++) + { + Console.WriteLine("Main Thread is doing stuff too... " + i.ToString()); + Thread.Sleep(0); + } + return 42; } + + public static void ThreadFuncTest() + { + Console.WriteLine("Hello from another thread"); + + for (int i = 0; i < 10; i++) + { + Console.WriteLine("Sleeping from another thread: " + i.ToString()); + Thread.Sleep(0); + } + } } } diff --git a/src/mono/sample/wasm/browser/index.html b/src/mono/sample/wasm/browser/index.html index 765d8ccede0849..e0a5f09c94108c 100644 --- a/src/mono/sample/wasm/browser/index.html +++ b/src/mono/sample/wasm/browser/index.html @@ -13,6 +13,7 @@ Answer to the Ultimate Question of Life, the Universe, and Everything is : + diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index e50bf9daebf00d..d12c69f0d40982 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -43,4 +43,4 @@ async function main() { } } -main(); \ No newline at end of file +setTimeout(main, 10000); \ No newline at end of file diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 89759c3c7745ca..612d9b3a45e8a8 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -13,10 +13,10 @@ WASM_DEFAULT_BUILD_ARGS?=/p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Confi all: publish build: - EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) build $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) $(MSBUILD_ARGS) $(PROJECT_NAME) + $(DOTNET) build $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) $(MSBUILD_ARGS) $(PROJECT_NAME) publish: - EMSDK_PATH=$(realpath $(TOP)/src/mono/wasm/emsdk) $(DOTNET) publish $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) $(MSBUILD_ARGS) $(PROJECT_NAME) + $(DOTNET) publish $(DOTNET_Q_ARGS) $(WASM_DEFAULT_BUILD_ARGS) $(MSBUILD_ARGS) $(PROJECT_NAME) clean: rm -rf bin $(TOP)/artifacts/obj/mono/$(PROJECT_NAME:%.csproj=%) @@ -26,7 +26,7 @@ run-browser: echo "The tool dotnet-serve could not be found. Install with: $(DOTNET) tool install --global dotnet-serve"; \ exit 1; \ else \ - $(DOTNET) serve -d:bin/$(CONFIG)/AppBundle -o -p:8000; \ + $(DOTNET) serve -d:bin/$(CONFIG)/AppBundle -h "Cross-Origin-Opener-Policy:same-origin" -h "Cross-Origin-Embedder-Policy:require-corp" -o -p:8000; \ fi run-console: diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index a84d1d9b0ec041..98ae3e764d7235 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -449,6 +449,13 @@ mono_wasm_load_runtime (const char *unused, int debug_level) mono_wasm_link_icu_shim (); #endif + monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); + monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); + // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this + // output will be sent to the console. Right now this is the only way to emit debug logging from + // corlib assemblies. + monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); + #ifdef DEBUG // monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); // monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0); diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index e37d31ad800e07..b49333e0a78fcd 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -6,7 +6,8 @@ browser-wasm $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'native', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)')) - $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) false false emcc @@ -70,6 +71,9 @@ <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> + <_EmccCommonFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-s USE_PTHREADS=1" /> + <_EmccLinkFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-Wno-pthreads-mem-growth" /> + <_EmccLinkFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-s PTHREAD_POOL_SIZE=2" /> <_EmccLinkFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency']"" /> <_EmccLinkFlags Include="-s EXPORTED_FUNCTIONS="['_free','_malloc']"" /> <_EmccLinkFlags Include="--source-map-base http://example.com" /> @@ -164,6 +168,7 @@ -Oz $(CMakeConfigurationEmccFlags) -O2 + $(CMakeConfigurationLinkFlags) -Wno-pthreads-mem-growth -DEMSDK_PATH="$(EMSDK_PATH.TrimEnd('\/'))" emcmake cmake $(MSBuildThisFileDirectory)runtime -DCMAKE_BUILD_TYPE=$(Configuration) -DCONFIGURATION_EMCC_FLAGS="$(CMakeConfigurationEmccFlags)" -DCONFIGURATION_LINK_FLAGS="$(CMakeConfigurationLinkFlags)" -DMONO_INCLUDES="$(MonoArtifactsPath)include/mono-2.0" -DMONO_OBJ_INCLUDES="$(MonoObjDir.TrimEnd('\/'))" -DICU_LIB_DIR="$(ICULibDir.TrimEnd('\/'))" -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/'))" -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/'))" $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) From 7142965798a3d16d863d59dc79fa7d514b5a5b02 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 27 Jan 2022 19:27:46 -0800 Subject: [PATCH 015/128] Prevent runtime from starting twice when loaded in a web worker --- src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js index 9326071c42e0a9..daa0782d477ad0 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.extpost.js @@ -1,6 +1,7 @@ var require = require || undefined; // if loaded into global namespace and configured with global Module, we will self start in compatibility mode -let ENVIRONMENT_IS_GLOBAL = typeof globalThis.Module === "object" && globalThis.__dotnet_runtime === __dotnet_runtime; +const __isWorker = typeof globalThis.importScripts === "function"; +let ENVIRONMENT_IS_GLOBAL = !__isWorker && (typeof globalThis.Module === "object" && globalThis.__dotnet_runtime === __dotnet_runtime); if (ENVIRONMENT_IS_GLOBAL) { createDotnetRuntime(() => { return globalThis.Module; }).then((exports) => exports); } From f83f09376ac537f7737fa8f40483c2109694584e Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 27 Jan 2022 20:08:07 -0800 Subject: [PATCH 016/128] Automatically populate the emscripten mainScriptUrlOrBlob property so that worker initialization can find dotnet.js --- src/mono/wasm/runtime/startup.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 8801ac704b0eb3..4c9d092ee6b010 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -25,6 +25,22 @@ export const mono_wasm_runtime_is_initialized = new Promise((resolve, reject) => let ctx: DownloadAssetsContext | null = null; export function configure_emscripten_startup(module: DotnetModule, exportedAPI: DotnetPublicAPI): void { + // HACK: Emscripten expects us to provide it a fully qualified path where it can find + // our main script so that it can be loaded from inside of workers, because workers + // have their paths relative to the root instead of relative to our location + // In the browser we can create a hyperlink and set its href to a relative URL, + // and the browser will convert it into an absolute one for us + if ( + (typeof (globalThis.document) === "object") && + (typeof (globalThis.document.createElement) === "function") + ) { + const temp = globalThis.document.createElement("a"); + temp.href = "dotnet.js"; + console.log("determined url of main script to be " + temp.href); + (module)["mainScriptUrlOrBlob"] = temp.href; + } else + console.log("could not determine url of main script for workers"); + // these could be overriden on DotnetModuleConfig if (!module.preInit) { module.preInit = []; @@ -42,7 +58,7 @@ export function configure_emscripten_startup(module: DotnetModule, exportedAPI: module.postRun = [module.postRun]; } - // when user set configSrc or config, we are running our default startup sequence. + // when user set configSrc or config, we are running our default startup sequence. if (module.configSrc || module.config) { // execution order == [0] == // - default or user Module.instantiateWasm (will start downloading dotnet.wasm) From 01cbb8d72d38b62dd82dacb2c62469793e50053a Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 28 Jan 2022 15:34:52 -0800 Subject: [PATCH 017/128] Add compatibility shim so that emscripten's generated worker.js can properly get a Module instance, since we broke the API --- src/mono/wasm/runtime/exports.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 7942377aa411fe..795326ee3e7521 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -129,6 +129,7 @@ let exportedAPI: DotnetPublicAPI; // this is executed early during load of emscripten runtime // it exports methods to global objects MONO, BINDING and Module in backward compatible way +// At runtime this will be referred to as 'createDotnetRuntime' // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types function initializeImportsAndExports( imports: { isESM: boolean, isGlobal: boolean, isNode: boolean, isShell: boolean, isWeb: boolean, locateFile: Function, quit_: Function, requirePromise: Promise }, @@ -250,6 +251,10 @@ function initializeImportsAndExports( configure_emscripten_startup(module, exportedAPI); + // HACK: Maintain compatibility with emscripten's generated dotnet.worker.js + if (typeof ((globalThis)["importScripts"]) === "function") + return exportedAPI.Module; + return exportedAPI; } From e7162e7a5f2b731f0f6d90408a4e4cc27a4603bb Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 11 Feb 2022 07:21:28 -0800 Subject: [PATCH 018/128] Checkpoint --- src/mono/mono.proj | 5 +++++ src/mono/mono/utils/mono-threads-wasm.c | 3 +++ .../browser/Wasm.Browser.CJS.Sample.csproj | 7 ++++++- src/mono/sample/wasm/browser/main.js | 2 ++ src/mono/wasm/build/WasmApp.InTree.props | 2 +- src/mono/wasm/build/WasmApp.Native.targets | 1 + src/native/eventpipe/ds-ipc.c | 20 +------------------ 7 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index f63e00410136b6..5b77c87ceb9f4b 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -467,6 +467,11 @@ <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT=1"/> + + <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_PERFTRACING_LISTEN_PORTS=1"/> + <_MonoCMakeArgs Include="-DFEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT=1"/> + + <_MonoCMakeArgs Include="-DSTATIC_COMPONENTS=1" /> diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index e7415532cbf095..5afe2c4b361e5b 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -110,6 +110,7 @@ mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2) return id1 == id2; } +static int pthread_warning_count = 0; MonoNativeThreadId mono_native_thread_id_get (void) @@ -117,6 +118,7 @@ mono_native_thread_id_get (void) #ifdef __EMSCRIPTEN_PTHREADS__ return pthread_self (); #else + g_assert_not_reached (); return (MonoNativeThreadId)1; #endif } @@ -127,6 +129,7 @@ mono_native_thread_os_id_get (void) #ifdef __EMSCRIPTEN_PTHREADS__ return (guint64)pthread_self (); #else + g_assert_not_reached (); return 1; #endif } diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj index d836a8539a8ecb..e16a8821b7ef7c 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -6,13 +6,18 @@ embedded 1 false - + true true $(ExecXHarnessCmd) wasm test-browser --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- $(MSBuildProjectName).dll + diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index d12c69f0d40982..ad9ac8df301068 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -28,6 +28,8 @@ async function main() { postRun: () => { console.log('user code Module.postRun') }, } }); + globalThis.__Module = Module; + globalThis.MONO = MONO; console.log('after createDotnetRuntime') const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning"); diff --git a/src/mono/wasm/build/WasmApp.InTree.props b/src/mono/wasm/build/WasmApp.InTree.props index ab70ccd739d44a..adabd009d9c401 100644 --- a/src/mono/wasm/build/WasmApp.InTree.props +++ b/src/mono/wasm/build/WasmApp.InTree.props @@ -15,7 +15,7 @@ <_MonoRuntimeComponentDontLink Include="libmono-component-debugger-stub-static.a" /> - <_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" /> + <_MonoRuntimeComponentDontLink Include="libmono-component-hot_reload-stub-static.a" /> diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 8cf5d6676457e6..f91b7c0c8d2b4d 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -203,6 +203,7 @@ <_EmccCFlags Include="$(EmccCompileOptimizationFlag)" /> <_EmccCFlags Include="@(_EmccCommonFlags)" /> + <_EmccCFlags Include="-DENABLE_AOT=1" Condition="'$(_WasmShouldAOT)' == 'true'" /> <_EmccCFlags Include="-DDRIVER_GEN=1" Condition="'$(_WasmShouldAOT)' == 'true'" /> <_EmccCFlags Include="-DINVARIANT_GLOBALIZATION=1" Condition="'$(InvariantGlobalization)' == 'true'" /> diff --git a/src/native/eventpipe/ds-ipc.c b/src/native/eventpipe/ds-ipc.c index b9c00030e69bf9..6a92aa53c3ad54 100644 --- a/src/native/eventpipe/ds-ipc.c +++ b/src/native/eventpipe/ds-ipc.c @@ -263,7 +263,7 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) bool result = true; ep_char8_t *ports = ds_rt_config_value_get_ports (); - if (ports) { + if (0 && ports) { DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY (port_configs); DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY (port_config_parts); @@ -319,25 +319,7 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) ep_rt_utf8_string_free (ports); } -#ifndef DS_IPC_DISABLE_DEFAULT_LISTEN_PORT - // create the default listen port - uint32_t port_suspend = ds_rt_config_value_get_default_port_suspend (); - - DiagnosticsPortBuilder default_port_builder; - if (ds_port_builder_init (&default_port_builder)) { - default_port_builder.path = NULL; - default_port_builder.suspend_mode = port_suspend > 0 ? DS_PORT_SUSPEND_MODE_SUSPEND : DS_PORT_SUSPEND_MODE_NOSUSPEND; - default_port_builder.type = DS_PORT_TYPE_LISTEN; - - result &= ipc_stream_factory_build_and_add_port (&default_port_builder, callback, true); - - ds_port_builder_fini (&default_port_builder); - } else { - result &= false; - } -#else DS_LOG_DEBUG_0 ("ds_ipc_stream_factory_configure - Ignoring default LISTEN port"); -#endif return result; } From 7380334f590bf8fdecdbb34a7cf72273a2e37c52 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 16 Mar 2022 19:14:52 -0400 Subject: [PATCH 019/128] Bring back threadpool and add some tracing in diagnostics --- .../System/Threading/ThreadPool.Windows.cs | 1 - .../System.Diagnostics.Tracing.Counters.cs | 5 --- .../System.Private.CoreLib.Shared.projitems | 2 +- .../src/System/AppContext.AnyOS.cs | 2 + .../Diagnostics/Tracing/CounterGroup.cs | 3 -- .../Diagnostics/Tracing/DiagnosticCounter.cs | 3 -- .../Diagnostics/Tracing/EventCounter.cs | 3 -- .../Tracing/IncrementingEventCounter.cs | 3 -- .../Tracing/IncrementingPollingCounter.cs | 3 -- .../Tracing/NativeRuntimeEventSource.cs | 1 + .../Diagnostics/Tracing/PollingCounter.cs | 5 +-- .../RegisteredWaitHandle.Portable.cs | 1 - .../System/Threading/ThreadPoolWorkQueue.cs | 8 ---- .../ref/System.Threading.ThreadPool.cs | 10 +---- .../ApiCompatBaseline.PreviousNetCoreApp.txt | 41 ++++++++++++++++++- .../System.Private.CoreLib.csproj | 10 ++--- src/mono/mono/eventpipe/ep-rt-mono.c | 1 + src/mono/mono/eventpipe/ep-rt-mono.h | 13 +++++- 18 files changed, 65 insertions(+), 50 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs index 44536e1145e646..2fc269cd7be7ba 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs @@ -13,7 +13,6 @@ namespace System.Threading // // Windows-specific implementation of ThreadPool // - [UnsupportedOSPlatform("browser")] public sealed class RegisteredWaitHandle : MarshalByRefObject { private readonly Lock _lock; diff --git a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs index 56c748f026e3e2..2e1cce9f780a48 100644 --- a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs +++ b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs @@ -3,7 +3,6 @@ namespace System.Diagnostics.Tracing { - [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public abstract partial class DiagnosticCounter : System.IDisposable { internal DiagnosticCounter() { } @@ -14,13 +13,11 @@ internal DiagnosticCounter() { } public void AddMetadata(string key, string? value) { } public void Dispose() { } } - [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public partial class PollingCounter : System.Diagnostics.Tracing.DiagnosticCounter { public PollingCounter(string name, System.Diagnostics.Tracing.EventSource eventSource, System.Func metricProvider) { } public override string ToString() { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public partial class IncrementingEventCounter : System.Diagnostics.Tracing.DiagnosticCounter { public IncrementingEventCounter(string name, System.Diagnostics.Tracing.EventSource eventSource) { } @@ -28,14 +25,12 @@ public IncrementingEventCounter(string name, System.Diagnostics.Tracing.EventSou public void Increment(double increment = 1) { } public override string ToString() { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public partial class IncrementingPollingCounter : System.Diagnostics.Tracing.DiagnosticCounter { public IncrementingPollingCounter(string name, System.Diagnostics.Tracing.EventSource eventSource, System.Func totalValueProvider) { } public System.TimeSpan DisplayRateTimeScale { get { throw null; } set { } } public override string ToString() { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public partial class EventCounter : System.Diagnostics.Tracing.DiagnosticCounter { public EventCounter(string name, System.Diagnostics.Tracing.EventSource eventSource) { } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index d5ce32af96642c..c8aff7ee6987a6 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -72,7 +72,7 @@ - + diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs index 25bda986d7408b..edf22600425729 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs @@ -12,6 +12,7 @@ namespace System { public static partial class AppContext { +#if INCLUDE_ME_ [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "Single File apps should always set APP_CONTEXT_BASE_DIRECTORY therefore code handles Assembly.Location equals null")] private static string GetBaseDirectoryCore() @@ -33,6 +34,7 @@ private static string GetBaseDirectoryCore() return directory; } +#endif #if FEATURE_PERFTRACING internal static void LogSwitchValues(RuntimeEventSource ev) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs index aec84922437a36..cf7b4471ff7e61 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/CounterGroup.cs @@ -15,9 +15,6 @@ namespace Microsoft.Diagnostics.Tracing namespace System.Diagnostics.Tracing #endif { -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif internal sealed class CounterGroup { private readonly EventSource _eventSource; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/DiagnosticCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/DiagnosticCounter.cs index 0c23cf99222b2c..0f4f898c82840b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/DiagnosticCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/DiagnosticCounter.cs @@ -20,9 +20,6 @@ namespace System.Diagnostics.Tracing /// DiagnosticCounter is an abstract class that serves as the parent class for various Counter* classes, /// namely EventCounter, PollingCounter, IncrementingEventCounter, and IncrementingPollingCounter. /// -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif public abstract class DiagnosticCounter : IDisposable { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs index 0c4460facc30f2..6fea134739756b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventCounter.cs @@ -24,9 +24,6 @@ namespace System.Diagnostics.Tracing /// See https://github.com/dotnet/runtime/blob/main/src/libraries/System.Diagnostics.Tracing/tests/BasicEventSourceTest/TestEventCounter.cs /// which shows tests, which are also useful in seeing actual use. /// -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif public partial class EventCounter : DiagnosticCounter { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingEventCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingEventCounter.cs index 13e5f1906ec327..3d20263b80f4d2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingEventCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingEventCounter.cs @@ -21,9 +21,6 @@ namespace System.Diagnostics.Tracing /// It does not calculate statistics like mean, standard deviation, etc. because it only accumulates /// the counter value. /// -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif public partial class IncrementingEventCounter : DiagnosticCounter { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingPollingCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingPollingCounter.cs index 86d46a040faa50..c4d1567629e553 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingPollingCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/IncrementingPollingCounter.cs @@ -22,9 +22,6 @@ namespace System.Diagnostics.Tracing /// Unlike IncrementingEventCounter, this takes in a polling callback that it can call to update /// its own metric periodically. /// -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif public partial class IncrementingPollingCounter : DiagnosticCounter { /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs index 0d97fdedaa2287..79a7731f5f0ddd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs @@ -38,6 +38,7 @@ private NativeRuntimeEventSource(int _) { } [NonEvent] internal unsafe void ProcessEvent(uint eventID, uint osThreadID, DateTime timeStamp, Guid activityId, Guid childActivityId, ReadOnlySpan payload) { + Internal.Console.WriteLine("STEVE: PROCESSEVENT CALLED"); // A simple fix to avoid dependencies brought by this method if event source is disabled via a feature switch. // Should be reconsidered when https://github.com/dotnet/runtime/issues/43657 is done. if (!IsSupported) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs index ed9697d2450229..2a1f7e9c252e0b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs @@ -20,9 +20,6 @@ namespace System.Diagnostics.Tracing /// function to collect metrics on its own rather than the user having to call WriteMetric() /// every time. /// -#if NETCOREAPP - [UnsupportedOSPlatform("browser")] -#endif public partial class PollingCounter : DiagnosticCounter { /// @@ -54,6 +51,8 @@ public PollingCounter(string name, EventSource eventSource, Func metricP #endif internal override void WritePayload(float intervalSec, int pollingIntervalMillisec) { + Internal.Console.WriteLine("STEVE: WRITING POLLING PAYLOAD"); + lock (this) { double value = 0; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs index 5fea9dda9246eb..b3adb85c2ce21d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs @@ -10,7 +10,6 @@ namespace System.Threading /// /// An object representing the registration of a via . /// - [UnsupportedOSPlatform("browser")] public sealed partial class RegisteredWaitHandle : MarshalByRefObject { internal RegisteredWaitHandle(WaitHandle waitHandle, _ThreadPoolWaitOrTimerCallback callbackHelper, diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs index 45a665b8830cfa..ad23c628e6ddf2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPoolWorkQueue.cs @@ -1067,7 +1067,6 @@ public static partial class ThreadPool internal static bool EnableWorkerTracking => IsWorkerTrackingEnabledInConfig && EventSource.IsSupported; [CLSCompliant(false)] - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1082,7 +1081,6 @@ public static RegisteredWaitHandle RegisterWaitForSingleObject( } [CLSCompliant(false)] - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1096,7 +1094,6 @@ public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( return RegisterWaitForSingleObject(waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce, false); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1110,7 +1107,6 @@ public static RegisteredWaitHandle RegisterWaitForSingleObject( return RegisterWaitForSingleObject(waitObject, callBack, state, (uint)millisecondsTimeOutInterval, executeOnlyOnce, true); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1124,7 +1120,6 @@ public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( return RegisterWaitForSingleObject(waitObject, callBack, state, (uint)millisecondsTimeOutInterval, executeOnlyOnce, false); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1140,7 +1135,6 @@ public static RegisteredWaitHandle RegisterWaitForSingleObject( return RegisterWaitForSingleObject(waitObject, callBack, state, (uint)millisecondsTimeOutInterval, executeOnlyOnce, true); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1156,7 +1150,6 @@ public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( return RegisterWaitForSingleObject(waitObject, callBack, state, (uint)millisecondsTimeOutInterval, executeOnlyOnce, false); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, @@ -1173,7 +1166,6 @@ bool executeOnlyOnce return RegisterWaitForSingleObject(waitObject, callBack, state, (uint)tm, executeOnlyOnce, true); } - [UnsupportedOSPlatform("browser")] public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( WaitHandle waitObject, WaitOrTimerCallback callBack, diff --git a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs index 23411ce260f332..5b3ea771b18ab3 100644 --- a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs +++ b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs @@ -10,7 +10,7 @@ public partial interface IThreadPoolWorkItem { void Execute(); } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] + public sealed partial class RegisteredWaitHandle : System.MarshalByRefObject { internal RegisteredWaitHandle() { } @@ -32,14 +32,10 @@ public static partial class ThreadPool public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack) { throw null; } public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack, object? state) { throw null; } public static bool QueueUserWorkItem(System.Action callBack, TState state, bool preferLocal) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, System.TimeSpan timeout, bool executeOnlyOnce) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { throw null; } public static bool SetMinThreads(int workerThreads, int completionPortThreads) { throw null; } @@ -49,14 +45,10 @@ public static partial class ThreadPool public static bool UnsafeQueueUserWorkItem(System.Threading.IThreadPoolWorkItem callBack, bool preferLocal) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Threading.WaitCallback callBack, object? state) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Action callBack, TState state, bool preferLocal) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, System.TimeSpan timeout, bool executeOnlyOnce) { throw null; } [System.CLSCompliantAttribute(false)] - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } } public delegate void WaitCallback(object? state); diff --git a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt index e413b0172741de..a37610e8cdb654 100644 --- a/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt +++ b/src/libraries/shims/ApiCompatBaseline.PreviousNetCoreApp.txt @@ -27,13 +27,27 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. Compat issues with assembly netstandard: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.DiagnosticCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.EventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingEventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingPollingCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.PollingCounter' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(T[])' in the contract but not the implementation. @@ -79,10 +93,19 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. Compat issues with assembly System: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -95,6 +118,12 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo Compat issues with assembly System.Diagnostics.Process: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. +Compat issues with assembly System.Diagnostics.Tracing: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.DiagnosticCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.EventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingEventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingPollingCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.PollingCounter' in the contract but not the implementation. Compat issues with assembly System.Numerics.Vectors: CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. @@ -151,4 +180,14 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. -Total Issues: 144 +Compat issues with assembly System.Threading.ThreadPool: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +Total Issues: 181 diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 2c82625c174e52..423dc135d2758c 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -118,8 +118,8 @@ true true true - true - true + true + true true @@ -289,9 +289,9 @@ - - - + diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index b50c78617ea8b9..4d60b114cc1f74 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2664,6 +2664,7 @@ ep_rt_mono_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkp bool ep_rt_mono_write_event_ee_startup_start (void) { + mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: FIRING ep_rt_mono_write_event_ee_startup_start"); return FireEtwEEStartupStart_V1 ( clr_instance_get_id (), NULL, diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 6829e696f41d87..702144244dd2ce 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -25,6 +25,7 @@ #include #include #include +#include "mono/utils/mono-logger-internals.h" #include #include @@ -870,14 +871,22 @@ inline bool ep_rt_config_value_get_enable (void) { + /* bool enable = false; gchar *value = g_getenv ("DOTNET_EnableEventPipe"); if (!value) value = g_getenv ("COMPlus_EnableEventPipe"); - if (value && atoi (value) == 1) + if (value && atoi (value) == 1) { + mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: EnableEventPipe: TRUE"); enable = true; + } + else { + mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: EnableEventPipe: FALSE"); + } g_free (value); return enable; + */ + return true; } static @@ -1410,6 +1419,8 @@ ep_rt_file_open_write (const ep_char8_t *path) ep_char16_t *path_utf16 = ep_rt_utf8_to_utf16_string (path, -1); ep_return_null_if_nok (path_utf16 != NULL); + mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: ep_rt_file_open_write"); + gpointer file_handle = ep_rt_mono_w32file_create ((gunichar2 *)path_utf16, GENERIC_WRITE, FILE_SHARE_READ, CREATE_ALWAYS, FileAttributes_Normal); ep_rt_utf16_string_free (path_utf16); From 3121ca5c714e0d6bd9d46214fae88734554519a8 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 24 Feb 2022 17:08:29 -0800 Subject: [PATCH 020/128] Add comments and fix a typo --- src/mono/wasm/runtime/cs-to-js.ts | 1 + src/mono/wasm/runtime/js-to-cs.ts | 4 +++- src/mono/wasm/runtime/method-binding.ts | 3 ++- src/mono/wasm/runtime/method-calls.ts | 1 + src/mono/wasm/runtime/strings.ts | 3 ++- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index de208efe3c93b2..3a0001fd6ca73d 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -154,6 +154,7 @@ export function _mono_array_root_to_js_array(arrayRoot: WasmRoot): an const len = cwraps.mono_wasm_array_length(arrayRoot.value); const res = new Array(len); for (let i = 0; i < len; ++i) { + // TODO: pass arrayRoot.address and elemRoot.address into new API that copies elemRoot.value = cwraps.mono_wasm_array_get(arrayRoot.value, i); if (is_nested_array(elemRoot.value)) diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 8bafaec669cd8f..f946d83f68f468 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -180,7 +180,9 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul if (asString) obj = obj.toString(); + // TODO: pass elemRoot into new API that copies elemRoot.value = _js_to_mono_obj(should_add_in_flight, obj); + // TODO: Create new API that copies and pass in elemRoot.address cwraps.mono_wasm_obj_array_set(arrayRoot.value, i, elemRoot.value); } @@ -203,7 +205,7 @@ export function _wrap_js_thenable_as_task(thenable: Promise): { // ideally, this should be hold alive by lifespan of the resulting C# Task, but this is good cheap aproximation const thenable_js_handle = mono_wasm_get_js_handle(thenable); - // Note that we do not implement promise/task roundtrip. + // Note that we do not implement promise/task roundtrip. // With more complexity we could recover original instance when this Task is marshaled back to JS. // TODO optimization: return the tcs.Task on this same call instead of _get_tcs_task const tcs_gc_handle = corebindings._create_tcs(); diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 04010b20ab72be..0708c76fefe3ff 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -124,7 +124,7 @@ export function _create_primitive_converters(): void { result.set("m", { steps: [{}], size: 0 }); result.set("s", { steps: [{ convert: js_string_to_mono_string.bind(BINDING) }], size: 0, needs_root: true }); result.set("S", { steps: [{ convert: js_string_to_mono_string_interned.bind(BINDING) }], size: 0, needs_root: true }); - // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, + // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, // because we will root the reference, so we don't need in-flight reference // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end result.set("o", { steps: [{ convert: _js_to_mono_obj.bind(BINDING, false) }], size: 0, needs_root: true }); @@ -480,6 +480,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null // The end result is that bound method invocations don't always allocate, so no more nursery GCs. Yay! -kg body.push( "", + // TODO: Create new invoke_method variant that writes the result into resultRoot directly "resultRoot.value = invoke_method (method, this_arg, buffer, exceptionRoot.get_address ());", `_handle_exception_for_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, argsRootBuffer);`, "", diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 3bd1057c1c154a..a9388c1ef1a20a 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -235,6 +235,7 @@ function _call_method_with_converted_args( is_result_marshaled: boolean, argsRootBuffer?: WasmRootBuffer ): any { const resultRoot = mono_wasm_new_root(), exceptionRoot = mono_wasm_new_root(); + // TODO: Create new invoke_method variant that writes the result into resultRoot directly resultRoot.value = cwraps.mono_wasm_invoke_method(method, this_arg, buffer, exceptionRoot.get_address()); return _handle_exception_and_produce_result_for_call(converter, token, buffer, resultRoot, exceptionRoot, argsRootBuffer, is_result_marshaled); } diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 02c3b1fa302e89..6e6f0498bb1744 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -30,7 +30,8 @@ export class StringDecoder { pLengthBytes = this.mono_wasm_string_decoder_buffer + 4, pIsInterned = this.mono_wasm_string_decoder_buffer + 8; - cwraps.mono_wasm_string_get_data(mono_string, ppChars, pLengthBytes, pIsInterned); + // TODO: Create new version of this API that takes the address of the root instead + cwraps.mono_wasm_string_get_data(this.mono_wasm_string_root.value, ppChars, pLengthBytes, pIsInterned); let result = mono_wasm_empty_string; const lengthBytes = getI32(pLengthBytes), From 2cd8459c93a34633226b31a996280ffd383c10ab Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 14:35:07 -0800 Subject: [PATCH 021/128] Introduce 'MonoObjectRef' ts type. Migrate mono_string_intern to not have a retval --- src/mono/wasm/runtime/cwraps.ts | 6 +++--- src/mono/wasm/runtime/driver.c | 6 +++--- src/mono/wasm/runtime/roots.ts | 11 ++++++----- src/mono/wasm/runtime/strings.ts | 18 ++++++++---------- src/mono/wasm/runtime/types.ts | 4 ++++ 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index fab4a0e2645491..7cd55c728915a9 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -4,7 +4,7 @@ import { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, - MonoType + MonoType, MonoObjectRef } from "./types"; import { Module } from "./imports"; import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr } from "./types/emscripten"; @@ -48,7 +48,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_register_bundled_satellite_assemblies", "void", []], ["mono_wasm_try_unbox_primitive_and_get_type", "number", ["number", "number", "number"]], ["mono_wasm_box_primitive", "number", ["number", "number", "number"]], - ["mono_wasm_intern_string", "number", ["number"]], + ["mono_wasm_intern_string_ref", "void", ["number"]], ["mono_wasm_assembly_get_entry_point", "number", ["number"]], ["mono_wasm_get_delegate_invoke", "number", ["number"]], ["mono_wasm_string_array_new", "number", ["number"]], @@ -108,7 +108,7 @@ export interface t_Cwraps { mono_wasm_register_bundled_satellite_assemblies(): void; mono_wasm_try_unbox_primitive_and_get_type(obj: MonoObject, buffer: VoidPtr, buffer_size: number): number; mono_wasm_box_primitive(klass: MonoClass, value: VoidPtr, value_size: number): MonoObject; - mono_wasm_intern_string(str: MonoString): MonoString; + mono_wasm_intern_string_ref(strRef: MonoObjectRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; mono_wasm_get_delegate_invoke(delegate: MonoObject): MonoMethod; mono_wasm_string_array_new(size: number): MonoArray; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 98ae3e764d7235..4b688d84935edd 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -1111,10 +1111,10 @@ mono_wasm_enable_on_demand_gc (int enable) mono_wasm_enable_gc = enable ? 1 : 0; } -EMSCRIPTEN_KEEPALIVE MonoString * -mono_wasm_intern_string (MonoString *string) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_intern_string_ref (MonoString **string) { - return mono_string_intern (string); + *string = mono_string_intern (*string); } EMSCRIPTEN_KEEPALIVE void diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index 2d473fb22ff20f..f6efd95ee9167c 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -4,6 +4,7 @@ import cwraps from "./cwraps"; import { Module } from "./imports"; import { VoidPtr, ManagedPointer, NativePointer } from "./types/emscripten"; +import { MonoObjectRef } from "./types"; const maxScratchRoots = 8192; let _scratch_root_buffer: WasmRootBuffer | null = null; @@ -207,7 +208,7 @@ export class WasmRootBuffer { this._throw_index_out_of_range(); } - get_address(index: number): NativePointer { + get_address(index: number): MonoObjectRef { this._check_in_range(index); return this.__offset + (index * 4); } @@ -261,7 +262,7 @@ export class WasmRootBuffer { } export interface WasmRoot { - get_address(): NativePointer; + get_address(): MonoObjectRef; get_address_32(): number; get(): T; set(value: T): T; @@ -282,7 +283,7 @@ class WasmJsOwnedRoot implements WasmR this.__index = index; } - get_address(): NativePointer { + get_address(): MonoObjectRef { return this.__buffer.get_address(this.__index); } @@ -349,8 +350,8 @@ class WasmExternalRoot implements Wasm this.__external_address_32 = address >>> 2; } - get_address(): NativePointer { - return this.__external_address; + get_address(): MonoObjectRef { + return this.__external_address; } get_address_32(): number { diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 6e6f0498bb1744..24aa9404ea0de9 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -129,21 +129,19 @@ function _store_string_in_intern_table(string: string, ptr: MonoString, internIt // Store the managed string into the managed intern table. This can theoretically // provide a different managed object than the one we passed in, so update our // pointer (stored in the root) with the result. - if (internIt) { - ptr = cwraps.mono_wasm_intern_string(ptr); - rootBuffer.set(index, ptr); - } + if (internIt) + cwraps.mono_wasm_intern_string_ref(rootBuffer.get_address(index)); - if (!ptr) - throw new Error("mono_wasm_intern_string produced a null pointer"); + if (!rootBuffer.get(index)) + throw new Error("mono_wasm_intern_string_ref produced a null pointer"); - interned_js_string_table.set(string, ptr); - interned_string_table.set(ptr, string); + interned_js_string_table.set(string, rootBuffer.get(index)); + interned_string_table.set(rootBuffer.get(index), string); if ((string.length === 0) && !_empty_string_ptr) - _empty_string_ptr = ptr; + _empty_string_ptr = rootBuffer.get(index); - return ptr; + return rootBuffer.get(index); } export function js_string_to_mono_string_interned(string: string | symbol): MonoString { diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index b208aeedcd06a8..f16af1d3682fe2 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -31,6 +31,10 @@ export interface MonoArray extends MonoObject { export interface MonoAssembly extends MonoObject { __brand: "MonoAssembly" } +// Pointer to a MonoObject* (i.e. the address of a root) +export interface MonoObjectRef extends NativePointer { + __brandMonoObject: "MonoObjectRef" +} export const MonoMethodNull: MonoMethod = 0; export const MonoObjectNull: MonoObject = 0; export const MonoArrayNull: MonoArray = 0; From e483d20b3e9d91a1555b1b7fb8edd828c3c0482d Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 15:13:30 -0800 Subject: [PATCH 022/128] Checkpoint (strings are broken for some reason) --- src/mono/wasi/mono-wasi-driver/driver.c | 23 +++++--- src/mono/wasm/runtime/cwraps.ts | 7 +++ src/mono/wasm/runtime/dotnet.d.ts | 12 ++++- src/mono/wasm/runtime/driver.c | 19 ++++--- src/mono/wasm/runtime/roots.ts | 70 ++++++++++++++++++++++--- src/mono/wasm/runtime/strings.ts | 61 +++++++++++++-------- src/mono/wasm/runtime/types.ts | 1 + 7 files changed, 147 insertions(+), 46 deletions(-) diff --git a/src/mono/wasi/mono-wasi-driver/driver.c b/src/mono/wasi/mono-wasi-driver/driver.c index cadbcbd4aebc41..a6475f8a7a7190 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.c +++ b/src/mono/wasi/mono-wasi-driver/driver.c @@ -366,7 +366,7 @@ mono_wasm_assembly_load (const char *name) return res; } -MonoClass* +MonoClass* mono_wasm_find_corlib_class (const char *namespace, const char *name) { return mono_class_from_name (mono_get_corlib (), namespace, name); @@ -446,7 +446,7 @@ mono_wasm_assembly_get_entry_point (MonoAssembly *assembly) uint32_t entry = mono_image_get_entry_point (image); if (!entry) return NULL; - + mono_domain_ensure_entry_assembly (root_domain, assembly); method = mono_get_method (image, entry, NULL); @@ -566,10 +566,10 @@ mono_wasm_string_array_new (int size) } void -mono_wasm_string_get_data ( - MonoString *string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned +mono_wasm_string_get_data_ref ( + MonoString **string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned ) { - if (!string) { + if (!string || !(*string)) { if (outChars) *outChars = 0; if (outLengthBytes) @@ -580,14 +580,21 @@ mono_wasm_string_get_data ( } if (outChars) - *outChars = mono_string_chars (string); + *outChars = mono_string_chars (*string); if (outLengthBytes) - *outLengthBytes = mono_string_length (string) * 2; + *outLengthBytes = mono_string_length (*string) * 2; if (outIsInterned) - *outIsInterned = mono_string_instance_is_interned (string); + *outIsInterned = mono_string_instance_is_interned (*string); 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/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 7cd55c728915a9..9b0867242f931b 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -14,6 +14,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_register_root", "number", ["number", "number", "string"]], ["mono_wasm_deregister_root", null, ["number"]], ["mono_wasm_string_get_data", null, ["number", "number", "number", "number"]], + ["mono_wasm_string_get_data_ref", null, ["number", "number", "number", "number"]], ["mono_wasm_set_is_debugger_attached", "void", ["bool"]], ["mono_wasm_send_dbg_command", "bool", ["number", "number", "number", "number", "number"]], ["mono_wasm_send_dbg_command_with_parms", "bool", ["number", "number", "number", "number", "number", "number", "string"]], @@ -75,6 +76,7 @@ export interface t_Cwraps { mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; mono_wasm_deregister_root(addr: VoidPtr): void; mono_wasm_string_get_data(string: MonoString, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; + mono_wasm_string_get_data_ref(stringRef: MonoObjectRef, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; mono_wasm_set_is_debugger_attached(value: boolean): void; mono_wasm_send_dbg_command(id: number, command_set: number, command: number, data: VoidPtr, size: number): boolean; mono_wasm_send_dbg_command_with_parms(id: number, command_set: number, command: number, data: VoidPtr, size: number, valtype: number, newvalue: string): boolean; @@ -128,6 +130,11 @@ export interface t_Cwraps { mono_wasm_set_main_args(argc: number, argv: VoidPtr): void; mono_profiler_init_aot(desc: string): void; mono_wasm_exec_regression(verbose_level: number, image: string): number; +<<<<<<< HEAD +======= + mono_wasm_write_managed_pointer_unsafe(destination: VoidPtr | MonoObjectRef, pointer: ManagedPointer): void; + mono_wasm_copy_managed_pointer(destination: VoidPtr | MonoObjectRef, source: VoidPtr | MonoObjectRef): void; +>>>>>>> 4499a7cb781 (Checkpoint (strings are broken for some reason)) } const wrapped_c_functions: t_Cwraps = {}; diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 6d210e51ad7cc1..3bd736a5ee5275 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -90,10 +90,11 @@ declare class WasmRootBuffer { constructor(offset: VoidPtr, capacity: number, ownsAllocation: boolean, name?: string); _throw_index_out_of_range(): void; _check_in_range(index: number): void; - get_address(index: number): NativePointer; + get_address(index: number): MonoObjectRef; get_address_32(index: number): number; get(index: number): ManagedPointer; set(index: number, value: ManagedPointer): ManagedPointer; + copy_value_from_address(index: number, sourceAddress: MonoObjectRef): void; _unsafe_get(index: number): number; _unsafe_set(index: number, value: ManagedPointer | NativePointer): void; clear(): void; @@ -101,12 +102,16 @@ declare class WasmRootBuffer { toString(): string; } interface WasmRoot { - get_address(): NativePointer; + get_address(): MonoObjectRef; get_address_32(): number; get(): T; set(value: T): T; get value(): T; set value(value: T); + copy_from_address(source: MonoObjectRef): void; + copy_to_address(destination: MonoObjectRef): void; + copy_from(source: WasmRoot): void; + copy_to(destination: WasmRoot): void; valueOf(): T; clear(): void; release(): void; @@ -122,6 +127,9 @@ interface MonoString extends MonoObject { interface MonoArray extends MonoObject { __brand: "MonoArray"; } +interface MonoObjectRef extends NativePointer { + __brandMonoObject: "MonoObjectRef"; +} declare type MonoConfig = { isError: false; assembly_root: string; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 4b688d84935edd..53580e52285bd8 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -1118,10 +1118,10 @@ mono_wasm_intern_string_ref (MonoString **string) } EMSCRIPTEN_KEEPALIVE void -mono_wasm_string_get_data ( - MonoString *string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned +mono_wasm_string_get_data_ref ( + MonoString **string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned ) { - if (!string) { + if (!string || !(*string)) { if (outChars) *outChars = 0; if (outLengthBytes) @@ -1132,14 +1132,21 @@ mono_wasm_string_get_data ( } if (outChars) - *outChars = mono_string_chars (string); + *outChars = mono_string_chars (*string); if (outLengthBytes) - *outLengthBytes = mono_string_length (string) * 2; + *outLengthBytes = mono_string_length (*string) * 2; if (outIsInterned) - *outIsInterned = mono_string_instance_is_interned (string); + *outIsInterned = mono_string_instance_is_interned (*string); return; } +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) { diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index f6efd95ee9167c..e785469162b200 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -4,7 +4,7 @@ import cwraps from "./cwraps"; import { Module } from "./imports"; import { VoidPtr, ManagedPointer, NativePointer } from "./types/emscripten"; -import { MonoObjectRef } from "./types"; +import { MonoObjectRef, MonoObjectRefNull } from "./types"; const maxScratchRoots = 8192; let _scratch_root_buffer: WasmRootBuffer | null = null; @@ -228,11 +228,16 @@ export class WasmRootBuffer { } set(index: number, value: ManagedPointer): ManagedPointer { - const offset = this.get_address_32(index); - Module.HEAP32[offset] = value; + const address = this.get_address(index); + cwraps.mono_wasm_write_managed_pointer_unsafe(address, value); return value; } + copy_value_from_address(index: number, sourceAddress: MonoObjectRef): void { + const destinationAddress = this.get_address(index); + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); + } + _unsafe_get(index: number): number { return Module.HEAP32[this.__offset32 + index]; } @@ -268,6 +273,10 @@ export interface WasmRoot { set(value: T): T; get value(): T; set value(value: T); + copy_from_address(source: MonoObjectRef): void; + copy_to_address(destination: MonoObjectRef): void; + copy_from(source: WasmRoot): void; + copy_to(destination: WasmRoot): void; valueOf(): T; clear(): void; release(): void; @@ -297,10 +306,33 @@ class WasmJsOwnedRoot implements WasmR } set(value: T): T { - this.__buffer._unsafe_set(this.__index, value); + const destinationAddress = this.__buffer.get_address(this.__index); + cwraps.mono_wasm_write_managed_pointer_unsafe(destinationAddress, value); return value; } + copy_from(source: WasmRoot): void { + const sourceAddress = source.get_address(); + const destinationAddress = this.get_address(); + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); + } + + copy_to(destination: WasmRoot): void { + const sourceAddress = this.get_address(); + const destinationAddress = destination.get_address(); + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); + } + + copy_from_address(source: MonoObjectRef): void { + const destinationAddress = this.get_address(); + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, source); + } + + copy_to_address(destination: MonoObjectRef): void { + const sourceAddress = this.get_address(); + cwraps.mono_wasm_copy_managed_pointer(destination, sourceAddress); + } + get value(): T { return this.get(); } @@ -338,15 +370,15 @@ class WasmJsOwnedRoot implements WasmR } class WasmExternalRoot implements WasmRoot { - private __external_address: NativePointer = undefined; - private __external_address_32: number = undefined; + private __external_address: MonoObjectRef = MonoObjectRefNull; + private __external_address_32: number = 0; constructor(address: NativePointer) { this._set_address(address); } _set_address(address: NativePointer): void { - this.__external_address = address; + this.__external_address = address; this.__external_address_32 = address >>> 2; } @@ -364,10 +396,32 @@ class WasmExternalRoot implements Wasm } set(value: T): T { - Module.HEAPU32[this.__external_address_32] = value; + cwraps.mono_wasm_write_managed_pointer_unsafe(this.__external_address, value); return value; } + copy_from(source: WasmRoot): void { + const sourceAddress = source.get_address(); + const destinationAddress = this.__external_address; + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); + } + + copy_to(destination: WasmRoot): void { + const sourceAddress = this.__external_address; + const destinationAddress = destination.get_address(); + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); + } + + copy_from_address(source: MonoObjectRef): void { + const destinationAddress = this.__external_address; + cwraps.mono_wasm_copy_managed_pointer(destinationAddress, source); + } + + copy_to_address(destination: MonoObjectRef): void { + const sourceAddress = this.__external_address; + cwraps.mono_wasm_copy_managed_pointer(destination, sourceAddress); + } + get value(): T { return this.get(); } diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 24aa9404ea0de9..aeb4678e03c029 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -2,10 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. import { mono_wasm_new_root_buffer, WasmRootBuffer } from "./roots"; -import { MonoString, MonoStringNull, } from "./types"; +import { MonoString, MonoStringNull, MonoObjectRef, MonoObjectRefNull } from "./types"; import { Module } from "./imports"; import cwraps from "./cwraps"; -import { mono_wasm_new_root } from "./roots"; +import { mono_wasm_new_root, WasmRoot } from "./roots"; import { getI32 } from "./memory"; import { NativePointer, CharPtr } from "./types/emscripten"; @@ -15,23 +15,35 @@ export class StringDecoder { private mono_text_decoder: TextDecoder | undefined | null; private mono_wasm_string_decoder_buffer: NativePointer | undefined; - copy(mono_string: MonoString): string | null { + init_fields(): void { if (!this.mono_wasm_string_decoder_buffer) { this.mono_text_decoder = typeof TextDecoder !== "undefined" ? new TextDecoder("utf-16le") : null; this.mono_wasm_string_root = mono_wasm_new_root(); this.mono_wasm_string_decoder_buffer = Module._malloc(12); } + } + + copy(mono_string: MonoString): string | null { + this.init_fields(); if (mono_string === MonoStringNull) return null; this.mono_wasm_string_root.value = mono_string; + const result = this.copy_rooted(this.mono_wasm_string_root); + this.mono_wasm_string_root.value = MonoStringNull; + return result; + } + + copy_rooted(root: WasmRoot): string | null { + this.init_fields(); + if (root.value === MonoStringNull) + return null; const ppChars = this.mono_wasm_string_decoder_buffer + 0, pLengthBytes = this.mono_wasm_string_decoder_buffer + 4, pIsInterned = this.mono_wasm_string_decoder_buffer + 8; - // TODO: Create new version of this API that takes the address of the root instead - cwraps.mono_wasm_string_get_data(this.mono_wasm_string_root.value, ppChars, pLengthBytes, pIsInterned); + cwraps.mono_wasm_string_get_data_ref(root.get_address(), ppChars, pLengthBytes, pIsInterned); let result = mono_wasm_empty_string; const lengthBytes = getI32(pLengthBytes), @@ -41,21 +53,19 @@ export class StringDecoder { if (pLengthBytes && pChars) { if ( isInterned && - - interned_string_table.has(mono_string) //TODO remove 2x lookup + interned_string_table.has(root.value) //TODO remove 2x lookup ) { - result = interned_string_table.get(mono_string)!; + result = interned_string_table.get(root.value)!; // console.log(`intern table cache hit ${mono_string} ${result.length}`); } else { result = this.decode(pChars, pChars + lengthBytes); if (isInterned) { // console.log("interned", mono_string, result.length); - interned_string_table.set(mono_string, result); + interned_string_table.set(root.value, result); } } } - this.mono_wasm_string_root.value = 0; return result; } @@ -105,11 +115,9 @@ export function mono_intern_string(string: string): string { return result!; } -function _store_string_in_intern_table(string: string, ptr: MonoString, internIt: boolean) { - if (!ptr) +function _store_string_in_intern_table(string: string, root: WasmRoot, internIt: boolean): void { + if (!root.value) throw new Error("null pointer passed to _store_string_in_intern_table"); - else if (typeof (ptr) !== "number") - throw new Error(`non-pointer passed to _store_string_in_intern_table: ${typeof (ptr)}`); const internBufferSize = 8192; @@ -124,7 +132,7 @@ function _store_string_in_intern_table(string: string, ptr: MonoString, internIt const rootBuffer = _interned_string_current_root_buffer; const index = _interned_string_current_root_buffer_count++; - rootBuffer.set(index, ptr); + rootBuffer.copy_value_from_address(index, root.get_address()); // Store the managed string into the managed intern table. This can theoretically // provide a different managed object than the one we passed in, so update our @@ -140,8 +148,6 @@ function _store_string_in_intern_table(string: string, ptr: MonoString, internIt if ((string.length === 0) && !_empty_string_ptr) _empty_string_ptr = rootBuffer.get(index); - - return rootBuffer.get(index); } export function js_string_to_mono_string_interned(string: string | symbol): MonoString { @@ -149,17 +155,28 @@ export function js_string_to_mono_string_interned(string: string | symbol): Mono ? (string.description || Symbol.keyFor(string) || "") : string; + if (typeof(text) !== "string") { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + throw new Error(`Argument to js_string_to_mono_string_interned must be a string but was ${string}`); + } + if ((text.length === 0) && _empty_string_ptr) return _empty_string_ptr; - let ptr = interned_js_string_table.get(text); + const ptr = interned_js_string_table.get(text); if (ptr) return ptr; - ptr = js_string_to_mono_string_new(text); - ptr = _store_string_in_intern_table(text, ptr, true); - - return ptr; + const root = mono_wasm_new_root(); + try { + root.value = js_string_to_mono_string_new(text); + _store_string_in_intern_table(text, root, true); + return root.value; + } finally { + if (root) + root.release(); + } } export function js_string_to_mono_string(string: string): MonoString { diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index f16af1d3682fe2..558c00ccba1d59 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -42,6 +42,7 @@ export const MonoAssemblyNull: MonoAssembly = 0; export const MonoClassNull: MonoClass = 0; export const MonoTypeNull: MonoType = 0; export const MonoStringNull: MonoString = 0; +export const MonoObjectRefNull: MonoObjectRef = 0; export const JSHandleDisposed: JSHandle = -1; export const JSHandleNull: JSHandle = 0; export const VoidPtrNull: VoidPtr = 0; From 1bff86017d32d0e845df2fb290146aa813cabb5b Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 15:23:39 -0800 Subject: [PATCH 023/128] Fix string interning --- src/mono/wasm/runtime/strings.ts | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index aeb4678e03c029..1be64c2bc3afcd 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -112,6 +112,8 @@ export function mono_intern_string(string: string): string { const ptr = js_string_to_mono_string_interned(string); const result = interned_string_table.get(ptr); + if (!result) + throw new Error("internal error: interned_string_table did not contain string after js_string_to_mono_string_interned"); return result!; } @@ -132,22 +134,25 @@ function _store_string_in_intern_table(string: string, root: WasmRootrootBuffer.get(index)); - interned_string_table.set(rootBuffer.get(index), string); + interned_js_string_table.set(string, root.value); + interned_string_table.set(root.value, string); if ((string.length === 0) && !_empty_string_ptr) - _empty_string_ptr = rootBuffer.get(index); + _empty_string_ptr = root.value; + + // Copy the final pointer into our interned string root buffer to ensure the string + // remains rooted. TODO: Is this actually necessary? + rootBuffer.copy_value_from_address(index, root.get_address()); } export function js_string_to_mono_string_interned(string: string | symbol): MonoString { @@ -174,8 +179,7 @@ export function js_string_to_mono_string_interned(string: string | symbol): Mono _store_string_in_intern_table(text, root, true); return root.value; } finally { - if (root) - root.release(); + root.release(); } } From 29ae4f77d295d5bc7e4e18c56aed5dfc819cdb28 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 15:31:53 -0800 Subject: [PATCH 024/128] Checkpoint --- src/mono/wasm/runtime/cs-to-js.ts | 6 +++--- src/mono/wasm/runtime/dotnet.d.ts | 2 ++ src/mono/wasm/runtime/event-listener.ts | 6 +++--- src/mono/wasm/runtime/exports.ts | 3 ++- src/mono/wasm/runtime/method-calls.ts | 11 ++++++----- src/mono/wasm/runtime/strings.ts | 4 ++++ src/mono/wasm/runtime/web-socket.ts | 8 ++++---- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 3a0001fd6ca73d..6dc82f19939539 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -8,7 +8,7 @@ import { MonoType, MonoTypeNull } from "./types"; import { runtimeHelpers } from "./imports"; -import { conv_string } from "./strings"; +import { conv_string_rooted } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; @@ -51,7 +51,7 @@ function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot; declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean; declare function conv_string(mono_obj: MonoString): string | null; +declare function conv_string_rooted(root: WasmRoot): string | null; declare function js_string_to_mono_string(string: string): MonoString; declare function js_to_mono_obj(js_obj: any): MonoObject; @@ -326,6 +327,7 @@ declare const BINDING: { js_to_mono_obj: typeof js_to_mono_obj; mono_array_to_js_array: typeof mono_array_to_js_array; conv_string: typeof conv_string; + conv_string_rooted: typeof conv_string_rooted; bind_static_method: typeof mono_bind_static_method; call_assembly_entry_point: typeof mono_call_assembly_entry_point; unbox_mono_obj: typeof unbox_mono_obj; diff --git a/src/mono/wasm/runtime/event-listener.ts b/src/mono/wasm/runtime/event-listener.ts index e2f1b59d4bf774..d38d896b0601f9 100644 --- a/src/mono/wasm/runtime/event-listener.ts +++ b/src/mono/wasm/runtime/event-listener.ts @@ -7,14 +7,14 @@ import { JSHandle, GCHandle, MonoString, MonoStringNull } from "./types"; import { _wrap_delegate_gc_handle_as_function } from "./cs-to-js"; import { mono_wasm_get_jsobj_from_js_handle, _js_owned_object_finalized, _lookup_js_owned_object, _use_finalization_registry } from "./gc-handles"; import { wrap_error } from "./method-calls"; -import { conv_string } from "./strings"; +import { conv_string_rooted } from "./strings"; const listener_registration_count_symbol = Symbol.for("wasm listener_registration_count"); export function mono_wasm_add_event_listener(js_handle: JSHandle, name: MonoString, listener_gc_handle: GCHandle, optionsHandle: JSHandle): MonoString { const nameRoot = mono_wasm_new_root(name); try { - const sName = conv_string(nameRoot.value); + const sName = conv_string_rooted(nameRoot); const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); if (!obj) @@ -60,7 +60,7 @@ export function mono_wasm_remove_event_listener(js_handle: JSHandle, name: MonoS // Removing a nonexistent listener should not be treated as an error if (!listener) return MonoStringNull; - const sName = conv_string(nameRoot.value); + const sName = conv_string_rooted(nameRoot); obj.removeEventListener(sName, listener, !!capture); // We do not manually remove the listener from the delegate registry here, diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 795326ee3e7521..bd9620b079315c 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -35,7 +35,7 @@ import { } from "./startup"; import { mono_set_timeout, schedule_background_exec } from "./scheduling"; import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu"; -import { conv_string, js_string_to_mono_string, mono_intern_string } from "./strings"; +import { conv_string, conv_string_rooted, js_string_to_mono_string, mono_intern_string } from "./strings"; import { js_to_mono_obj, js_typed_array_to_array, mono_wasm_typed_array_to_array } from "./js-to-cs"; import { mono_array_to_js_array, mono_wasm_create_cs_owned_object, unbox_mono_obj @@ -119,6 +119,7 @@ const BINDING = { js_to_mono_obj, mono_array_to_js_array, conv_string, + conv_string_rooted, bind_static_method: mono_bind_static_method, call_assembly_entry_point: mono_call_assembly_entry_point, unbox_mono_obj, diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index a9388c1ef1a20a..1c4decc9edd219 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -17,7 +17,7 @@ import { _decide_if_result_is_marshaled, find_method, BoundMethodToken } from "./method-binding"; -import { conv_string, js_string_to_mono_string } from "./strings"; +import { conv_string, conv_string_rooted, js_string_to_mono_string } from "./strings"; import cwraps from "./cwraps"; import { bindings_lazy_init } from "./startup"; import { _create_temp_frame, _release_temp_frame } from "./memory"; @@ -117,6 +117,7 @@ function _convert_exception_for_method_call(result: MonoString, exception: MonoO if (exception === MonoObjectNull) return null; + // FIXME: rooted const msg = conv_string(result); const err = new Error(msg!); //the convention is that invoke_method ToString () any outgoing exception // console.warn (`error ${msg} at location ${err.stack}); @@ -293,7 +294,7 @@ export function mono_call_assembly_entry_point(assembly: string, args?: any[], s export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: MonoString, args: MonoArray, is_exception: Int32Ptr): any { const argsRoot = mono_wasm_new_root(args), nameRoot = mono_wasm_new_root(method_name); try { - const js_name = conv_string(nameRoot.value); + const js_name = conv_string_rooted(nameRoot); if (!js_name || (typeof (js_name) !== "string")) { return wrap_error(is_exception, "ERR12: Invalid method name object '" + nameRoot.value + "'"); } @@ -323,7 +324,7 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: export function mono_wasm_get_object_property(js_handle: JSHandle, property_name: MonoString, is_exception: Int32Ptr): any { const nameRoot = mono_wasm_new_root(property_name); try { - const js_name = conv_string(nameRoot.value); + const js_name = conv_string_rooted(nameRoot); if (!js_name) { return wrap_error(is_exception, "Invalid property name object '" + nameRoot.value + "'"); } @@ -349,7 +350,7 @@ export function mono_wasm_set_object_property(js_handle: JSHandle, property_name const valueRoot = mono_wasm_new_root(value), nameRoot = mono_wasm_new_root(property_name); try { - const property = conv_string(nameRoot.value); + const property = conv_string_rooted(nameRoot); if (!property) { return wrap_error(is_exception, "Invalid property name object '" + property_name + "'"); } @@ -429,7 +430,7 @@ export function mono_wasm_set_by_index(js_handle: JSHandle, property_index: numb export function mono_wasm_get_global_object(global_name: MonoString, is_exception: Int32Ptr): MonoObject { const nameRoot = mono_wasm_new_root(global_name); try { - const js_name = conv_string(nameRoot.value); + const js_name = conv_string_rooted(nameRoot); let globalObj; diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 1be64c2bc3afcd..c3c5668615bfa1 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -104,6 +104,10 @@ export function conv_string(mono_obj: MonoString): string | null { return string_decoder.copy(mono_obj); } +export function conv_string_rooted(root: WasmRoot): string | null { + return string_decoder.copy_rooted(root); +} + // Ensures the string is already interned on both the managed and JavaScript sides, // then returns the interned string value (to provide fast reference comparisons like C#) export function mono_intern_string(string: string): string { diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 3a6753b4f7fc9f..352bcad127c450 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -9,7 +9,7 @@ import { _mono_array_root_to_js_array, _wrap_delegate_root_as_function } from ". import { mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle } from "./gc-handles"; import { _wrap_js_thenable_as_task } from "./js-to-cs"; import { wrap_error } from "./method-calls"; -import { conv_string } from "./strings"; +import { conv_string_rooted } from "./strings"; import { JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString } from "./types"; import { Module } from "./imports"; import { Int32Ptr } from "./types/emscripten"; @@ -34,7 +34,7 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr const sub_root = mono_wasm_new_root(subProtocols); const on_close_root = mono_wasm_new_root(on_close); try { - const js_uri = conv_string(uri_root.value); + const js_uri = conv_string_rooted(uri_root); if (!js_uri) { return wrap_error(is_exception, "ERR12: Invalid uri '" + uri_root.value + "'"); } @@ -193,7 +193,7 @@ export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: return MonoObjectNull;// no promise } - const js_reason = conv_string(reason_root.value); + const js_reason = conv_string_rooted(reason_root); if (wait_for_close_received) { const { promise, promise_control } = _create_cancelable_promise(); @@ -270,7 +270,7 @@ function _mono_wasm_web_socket_send_and_wait(ws: WebSocketExtension, buffer: Uin ws.send(buffer); ws[wasm_ws_pending_send_buffer] = null; - // if the remaining send buffer is small, we don't block so that the throughput doesn't suffer. + // if the remaining send buffer is small, we don't block so that the throughput doesn't suffer. // Otherwise we block so that we apply some backpresure to the application sending large data. // this is different from Managed implementation if (ws.bufferedAmount < ws_send_buffer_blocking_threshold) { From 54fa62fb467e208c547b6b689811f0fcdfae9320 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 16:25:41 -0800 Subject: [PATCH 025/128] Migrate ObjectToString and GetDateValue --- .../Runtime/InteropServices/JavaScript/Runtime.cs | 4 ++-- src/mono/wasm/runtime/corebindings.ts | 10 +++++----- src/mono/wasm/runtime/cs-to-js.ts | 6 +++--- src/mono/wasm/runtime/method-calls.ts | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index 4b5d072e8ac43e..bb14e8c33b2839 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -296,12 +296,12 @@ internal static char GetCallSignatureCharacterForMarshalType(MarshalType t, char return null; } - public static string ObjectToString(object o) + public static string ObjectToStringRef(ref object o) { return o.ToString() ?? string.Empty; } - public static double GetDateValue(object dtv) + public static double GetDateValueRef(ref object dtv!!) { if (dtv == null) throw new ArgumentNullException(nameof(dtv)); diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index 8f64ad00dbaf85..b31c408e17c8e8 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.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 { JSHandle, GCHandle, MonoObject } from "./types"; +import { JSHandle, GCHandle, MonoObject, MonoObjectRef } from "./types"; import { PromiseControl } from "./cancelable-promise"; import { runtimeHelpers } from "./imports"; @@ -22,8 +22,8 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_task_from_result", "TaskFromResult", "o!"], ["_setup_js_cont", "SetupJSContinuation", "mo"], - ["_object_to_string", "ObjectToString", "m"], - ["_get_date_value", "GetDateValue", "m"], + ["_object_to_string_ref", "ObjectToStringRef", "m"], + ["_get_date_value_ref", "GetDateValueRef", "m"], ["_create_date_time", "CreateDateTime", "d!"], ["_create_uri", "CreateUri", "s!"], ["_is_simple_array", "IsSimpleArray", "m"], @@ -47,8 +47,8 @@ export interface t_CSwraps { _task_from_result(result: MonoObject): MonoObject _setup_js_cont(task: MonoObject, continuation: PromiseControl): MonoObject - _object_to_string(obj: MonoObject): string; - _get_date_value(obj: MonoObject): number; + _object_to_string_ref(obj: MonoObjectRef): string; + _get_date_value_ref(obj: MonoObjectRef): number; _create_date_time(ticks: number): MonoObject; _create_uri(uri: string): MonoObject; _is_simple_array(obj: MonoObject): boolean; diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 6dc82f19939539..d87ba9d3ecd08e 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -71,11 +71,11 @@ function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot20: // clr .NET DateTime - return new Date(corebindings._get_date_value(root.value)); + return new Date(corebindings._get_date_value_ref(root.get_address())); case 21: // clr .NET DateTimeOffset - return corebindings._object_to_string(root.value); + return corebindings._object_to_string_ref(root.get_address()); case MarshalType.URI: - return corebindings._object_to_string(root.value); + return corebindings._object_to_string_ref(root.get_address()); case MarshalType.SAFEHANDLE: return _unbox_cs_owned_root_as_js_object(root); case MarshalType.VOID: diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 1c4decc9edd219..94409f5fd6bbf0 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -113,12 +113,12 @@ function _release_buffer_from_method_call( Module._free(buffer); } -function _convert_exception_for_method_call(result: MonoString, exception: MonoObject) { - if (exception === MonoObjectNull) +function _convert_exception_for_method_call(result: WasmRoot, exception: WasmRoot) { + if (exception.value === MonoObjectNull) return null; // FIXME: rooted - const msg = conv_string(result); + const msg = conv_string_rooted(result); const err = new Error(msg!); //the convention is that invoke_method ToString () any outgoing exception // console.warn (`error ${msg} at location ${err.stack}); return err; @@ -180,7 +180,7 @@ export function _handle_exception_for_call( buffer: VoidPtr, resultRoot: WasmRoot, exceptionRoot: WasmRoot, argsRootBuffer?: WasmRootBuffer ): void { - const exc = _convert_exception_for_method_call(resultRoot.value, exceptionRoot.value); + const exc = _convert_exception_for_method_call(resultRoot, exceptionRoot); if (!exc) return; From 50b52014d4fe6b117c410fb9c9fcf344c2d0ae3b Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 16:59:36 -0800 Subject: [PATCH 026/128] Checkpoint gc safe/unsafe region work --- src/mono/wasm/runtime/cs-to-js.ts | 4 +- src/mono/wasm/runtime/cwraps.ts | 4 +- src/mono/wasm/runtime/driver.c | 116 ++++++++++++++++++------ src/mono/wasm/runtime/method-binding.ts | 8 +- 4 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index d87ba9d3ecd08e..81462d4a9b491d 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -45,6 +45,8 @@ function _unbox_cs_owned_root_as_js_object(root: WasmRoot) { function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot, type: MarshalType, typePtr: MonoType, unbox_buffer: VoidPtr): any { //See MARSHAL_TYPE_ defines in driver.c switch (type) { + case MarshalType.NULL: + return null; case MarshalType.INT64: case MarshalType.UINT64: // TODO: Fix this once emscripten offers HEAPI64/HEAPU64 or can return them @@ -104,7 +106,7 @@ export function _unbox_mono_obj_root(root: WasmRoot): any { return undefined; const unbox_buffer = runtimeHelpers._unbox_buffer; - const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type(root.value, unbox_buffer, runtimeHelpers._unbox_buffer_size); + const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.get_address(), unbox_buffer, runtimeHelpers._unbox_buffer_size); switch (type) { case MarshalType.INT: return getI32(unbox_buffer); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 9b0867242f931b..3980ab692de737 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -47,7 +47,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_obj_array_new", "number", ["number"]], ["mono_wasm_obj_array_set", "void", ["number", "number", "number"]], ["mono_wasm_register_bundled_satellite_assemblies", "void", []], - ["mono_wasm_try_unbox_primitive_and_get_type", "number", ["number", "number", "number"]], + ["mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], ["mono_wasm_box_primitive", "number", ["number", "number", "number"]], ["mono_wasm_intern_string_ref", "void", ["number"]], ["mono_wasm_assembly_get_entry_point", "number", ["number"]], @@ -108,7 +108,7 @@ export interface t_Cwraps { mono_wasm_obj_array_new(size: number): MonoArray; mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; mono_wasm_register_bundled_satellite_assemblies(): void; - mono_wasm_try_unbox_primitive_and_get_type(obj: MonoObject, buffer: VoidPtr, buffer_size: number): number; + mono_wasm_try_unbox_primitive_and_get_type_ref(obj: MonoObjectRef, buffer: VoidPtr, buffer_size: number): number; mono_wasm_box_primitive(klass: MonoClass, value: VoidPtr, value_size: number): MonoObject; mono_wasm_intern_string_ref(strRef: MonoObjectRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 53580e52285bd8..82cc8cd146d502 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -55,6 +55,48 @@ void mono_free (void*); int32_t mini_parse_debug_option (const char *option); char *mono_method_get_full_name (MonoMethod *method); +// ????????????? + +#define gpointer void* + +MONO_API MONO_RT_EXTERNAL_ONLY gpointer +mono_threads_enter_gc_unsafe_region (gpointer* stackdata); + +MONO_API MONO_RT_EXTERNAL_ONLY void +mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer* stackdata); + +MONO_API MONO_RT_EXTERNAL_ONLY void +mono_threads_assert_gc_unsafe_region (void); + +MONO_API MONO_RT_EXTERNAL_ONLY gpointer +mono_threads_enter_gc_safe_region (gpointer *stackdata); + +MONO_API MONO_RT_EXTERNAL_ONLY void +mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata); + +MONO_API void +mono_threads_assert_gc_safe_region (void); +#define MONO_ENTER_GC_UNSAFE \ + do { \ + gpointer __dummy; \ + gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__dummy) \ + +#define MONO_EXIT_GC_UNSAFE \ + mono_threads_exit_gc_unsafe_region (__gc_unsafe_cookie, &__dummy); \ + } while (0) + +#define MONO_ENTER_GC_SAFE \ + do { \ + gpointer __dummy; \ + gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__dummy) \ + +#define MONO_EXIT_GC_SAFE \ + mono_threads_exit_gc_safe_region (__gc_safe_cookie, &__dummy); \ + } while (0) + +// ????????????????? + + #define MARSHAL_TYPE_NULL 0 #define MARSHAL_TYPE_INT 1 #define MARSHAL_TYPE_FP64 2 @@ -155,13 +197,19 @@ void mono_gc_deregister_root (char* addr); EMSCRIPTEN_KEEPALIVE int mono_wasm_register_root (char *start, size_t size, const char *name) { - return mono_gc_register_root (start, size, (MonoGCDescriptor)NULL, MONO_ROOT_SOURCE_EXTERNAL, NULL, name ? name : "mono_wasm_register_root"); + int result; + MONO_ENTER_GC_SAFE; + result = mono_gc_register_root (start, size, (MonoGCDescriptor)NULL, MONO_ROOT_SOURCE_EXTERNAL, NULL, name ? name : "mono_wasm_register_root"); + MONO_EXIT_GC_SAFE; + return result; } EMSCRIPTEN_KEEPALIVE void mono_wasm_deregister_root (char *addr) { + MONO_ENTER_GC_SAFE; mono_gc_deregister_root (addr); + MONO_EXIT_GC_SAFE; } #ifdef DRIVER_GEN @@ -906,29 +954,14 @@ mono_wasm_get_obj_type (MonoObject *obj) return mono_wasm_marshal_type_from_mono_type (mono_type, klass, type); } -EMSCRIPTEN_KEEPALIVE int -mono_wasm_try_unbox_primitive_and_get_type (MonoObject *obj, void *result, int result_capacity) -{ +// This code runs inside a gc unsafe region +int _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (MonoObject *obj, void *result, int result_capacity) { void **resultP = result; int *resultI = result; int64_t *resultL = result; float *resultF = result; double *resultD = result; - if (result_capacity >= sizeof (int64_t)) - *resultL = 0; - else if (result_capacity >= sizeof (int)) - *resultI = 0; - - if (!result) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - if (result_capacity < 16) - return MARSHAL_ERROR_BUFFER_TOO_SMALL; - - if (!obj) - return MARSHAL_TYPE_NULL; - /* Process obj before calling into the runtime, class_from_name () can invoke managed code */ MonoClass *klass = mono_object_get_class (obj); if (!klass) @@ -1031,7 +1064,6 @@ mono_wasm_try_unbox_primitive_and_get_type (MonoObject *obj, void *result, int r // 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; - obj = NULL; int fallbackResultType = mono_wasm_marshal_type_from_mono_type (mono_type, klass, original_type); assert (fallbackResultType != MARSHAL_TYPE_VT); return fallbackResultType; @@ -1039,12 +1071,38 @@ mono_wasm_try_unbox_primitive_and_get_type (MonoObject *obj, void *result, int r // 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) - obj = NULL; int resultType = mono_wasm_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) +{ + 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) + return MARSHAL_ERROR_BUFFER_TOO_SMALL; + + 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 (MonoArray *array) { @@ -1121,6 +1179,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_string_get_data_ref ( MonoString **string, mono_unichar2 **outChars, int *outLengthBytes, int *outIsInterned ) { + MONO_ENTER_GC_UNSAFE; if (!string || !(*string)) { if (outChars) *outChars = 0; @@ -1128,16 +1187,15 @@ mono_wasm_string_get_data_ref ( *outLengthBytes = 0; if (outIsInterned) *outIsInterned = 1; - return; + } else { + if (outChars) + *outChars = mono_string_chars (*string); + if (outLengthBytes) + *outLengthBytes = mono_string_length (*string) * 2; + if (outIsInterned) + *outIsInterned = mono_string_instance_is_interned (*string); } - - if (outChars) - *outChars = mono_string_chars (*string); - if (outLengthBytes) - *outLengthBytes = mono_string_length (*string) * 2; - if (outIsInterned) - *outIsInterned = mono_string_instance_is_interned (*string); - return; + MONO_EXIT_GC_UNSAFE; } EMSCRIPTEN_KEEPALIVE void diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 0708c76fefe3ff..4192f363e28c2c 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -403,7 +403,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null _get_buffer_for_method_call, _handle_exception_for_call, _teardown_after_call, - mono_wasm_try_unbox_primitive_and_get_type: cwraps.mono_wasm_try_unbox_primitive_and_get_type, + mono_wasm_try_unbox_primitive_and_get_type_ref: cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref, _unbox_mono_obj_root_with_known_nonprimitive_type, invoke_method: cwraps.mono_wasm_invoke_method, method, @@ -496,12 +496,12 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null if (!converter.is_result_definitely_unmarshaled) body.push( - "if (is_result_marshaled && (resultPtr !== 0)) {", + "if (is_result_marshaled) {", // For the common scenario where the return type is a primitive, we want to try and unbox it directly // into our existing heap allocation and then read it out of the heap. Doing this all in one operation // means that we only need to enter a gc safe region twice (instead of 3+ times with the normal, // slower check-type-and-then-unbox flow which has extra checks since unbox verifies the type). - " let resultType = mono_wasm_try_unbox_primitive_and_get_type (resultPtr, unbox_buffer, unbox_buffer_size);", + " let resultType = mono_wasm_try_unbox_primitive_and_get_type_ref (resultRoot.get_address(), unbox_buffer, unbox_buffer_size);", " switch (resultType) {", ` case ${MarshalType.INT}:`, " result = getI32(unbox_buffer); break;", @@ -516,6 +516,8 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null " result = getI32(unbox_buffer) !== 0; break;", ` case ${MarshalType.CHAR}:`, " result = String.fromCharCode(getI32(unbox_buffer)); break;", + ` case ${MarshalType.NULL}:`, + " result = null; break;", " default:", " result = _unbox_mono_obj_root_with_known_nonprimitive_type (resultRoot, resultType, unbox_buffer); break;", " }", From 094ce5bd2df8231e5a883a0ab2a208eb1a3f10de Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 25 Feb 2022 17:12:17 -0800 Subject: [PATCH 027/128] Checkpoint --- src/mono/wasm/runtime/cs-to-js.ts | 4 +++- src/mono/wasm/runtime/cwraps.ts | 4 ++++ src/mono/wasm/runtime/driver.c | 16 ++++++++++++++++ src/mono/wasm/runtime/js-to-cs.ts | 5 +++-- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 81462d4a9b491d..89453047a38825 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -150,14 +150,16 @@ export function _mono_array_root_to_js_array(arrayRoot: WasmRoot): an if (arrayRoot.value === MonoArrayNull) return null; + const arrayAddress = arrayRoot.get_address(); const elemRoot = mono_wasm_new_root(); + const elemAddress = elemRoot.get_address(); try { const len = cwraps.mono_wasm_array_length(arrayRoot.value); const res = new Array(len); for (let i = 0; i < len; ++i) { // TODO: pass arrayRoot.address and elemRoot.address into new API that copies - elemRoot.value = cwraps.mono_wasm_array_get(arrayRoot.value, i); + cwraps.mono_wasm_array_get_ref(arrayAddress, i, elemAddress); if (is_nested_array(elemRoot.value)) res[i] = _mono_array_root_to_js_array(elemRoot); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 3980ab692de737..a4d7d4d0034590 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -44,8 +44,10 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_get_obj_type", "number", ["number"]], ["mono_wasm_array_length", "number", ["number"]], ["mono_wasm_array_get", "number", ["number", "number"]], + ["mono_wasm_array_get_ref", "void", ["number", "number", "number"]], ["mono_wasm_obj_array_new", "number", ["number"]], ["mono_wasm_obj_array_set", "void", ["number", "number", "number"]], + ["mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], ["mono_wasm_register_bundled_satellite_assemblies", "void", []], ["mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], ["mono_wasm_box_primitive", "number", ["number", "number", "number"]], @@ -105,8 +107,10 @@ export interface t_Cwraps { mono_wasm_get_obj_type(str: MonoObject): number; mono_wasm_array_length(array: MonoArray): number; mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; + mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; mono_wasm_obj_array_new(size: number): MonoArray; mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): 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(klass: MonoClass, value: VoidPtr, value_size: number): MonoObject; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 82cc8cd146d502..0e7e32ea11d250 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -1115,6 +1115,14 @@ mono_wasm_array_get (MonoArray *array, int idx) return mono_array_get (array, MonoObject*, idx); } +EMSCRIPTEN_KEEPALIVE void +mono_wasm_array_get_ref (MonoArray **array, int idx, MonoObject **result) +{ + MONO_ENTER_GC_UNSAFE; + *result = mono_array_get (*array, MonoObject*, idx); + MONO_EXIT_GC_UNSAFE; +} + EMSCRIPTEN_KEEPALIVE MonoArray* mono_wasm_obj_array_new (int size) { @@ -1127,6 +1135,14 @@ 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 MonoArray* mono_wasm_string_array_new (int size) { diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index f946d83f68f468..399f7b042be092 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -173,6 +173,8 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul const mono_array = asString ? cwraps.mono_wasm_string_array_new(js_array.length) : cwraps.mono_wasm_obj_array_new(js_array.length); const arrayRoot = mono_wasm_new_root(mono_array); const elemRoot = mono_wasm_new_root(MonoObjectNull); + const arrayAddress = arrayRoot.get_address(); + const elemAddress = elemRoot.get_address(); try { for (let i = 0; i < js_array.length; ++i) { @@ -182,8 +184,7 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul // TODO: pass elemRoot into new API that copies elemRoot.value = _js_to_mono_obj(should_add_in_flight, obj); - // TODO: Create new API that copies and pass in elemRoot.address - cwraps.mono_wasm_obj_array_set(arrayRoot.value, i, elemRoot.value); + cwraps.mono_wasm_obj_array_set_ref(arrayAddress, i, elemAddress); } return mono_array; From f49b008edc1f53355efe86f79c608234e69be0fb Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 28 Feb 2022 15:57:51 -0800 Subject: [PATCH 028/128] More ref conversion --- .../InteropServices/JavaScript/Runtime.cs | 2 +- src/mono/wasi/mono-wasi-driver/driver.c | 38 +++++++++----- src/mono/wasm/runtime/corebindings.ts | 4 +- src/mono/wasm/runtime/cs-to-js.ts | 24 ++++----- src/mono/wasm/runtime/cwraps.ts | 4 +- src/mono/wasm/runtime/dotnet.d.ts | 1 + src/mono/wasm/runtime/driver.c | 38 +++++++++----- src/mono/wasm/runtime/js-to-cs.ts | 4 +- src/mono/wasm/runtime/method-binding.ts | 9 ++-- src/mono/wasm/runtime/method-calls.ts | 50 +++++++++++-------- src/mono/wasm/runtime/roots.ts | 29 +++++++---- src/mono/wasm/runtime/strings.ts | 6 +-- 12 files changed, 126 insertions(+), 83 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index bb14e8c33b2839..bb0ebd1198cb90 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -37,7 +37,7 @@ public static void DumpAotProfileData(ref byte buf, int len, string extraArg) Interop.Runtime.DumpAotProfileData(ref buf, len, extraArg); } - public static bool IsSimpleArray(object a) + public static bool IsSimpleArrayRef(ref object a) { return a is System.Array arr && arr.Rank == 1 && arr.GetLowerBound(0) == 0; } diff --git a/src/mono/wasi/mono-wasi-driver/driver.c b/src/mono/wasi/mono-wasi-driver/driver.c index a6475f8a7a7190..dbb8449e00aa0e 100644 --- a/src/mono/wasi/mono-wasi-driver/driver.c +++ b/src/mono/wasi/mono-wasi-driver/driver.c @@ -405,25 +405,37 @@ mono_wasm_box_primitive (MonoClass *klass, void *value, int value_size) return mono_value_box (root_domain, klass, value); } -MonoObject* -mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) +void +mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **out_exc, MonoObject **out_result) { - MonoObject *exc = NULL; - MonoObject *res; - + MonoObject* temp_exc = NULL; if (out_exc) *out_exc = NULL; - res = mono_runtime_invoke (method, this_arg, params, &exc); - if (exc) { - if (out_exc) - *out_exc = exc; + else + out_exc = &temp_exc; + + if (out_result) { + *out_result = NULL; + *out_result = mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + } else { + mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + } + if (*out_exc && out_result) { MonoObject *exc2 = NULL; - res = (MonoObject*)mono_object_to_string (exc, &exc2); + *out_result = (MonoObject*)mono_object_to_string (*out_exc, &exc2); if (exc2) - res = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); - return res; + *out_result = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); + return; } +} + +// deprecated +MonoObject* +mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) +{ + MonoObject* result = NULL; + mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, &result); MonoMethodSignature *sig = mono_method_signature (method); MonoType *type = mono_signature_get_return_type (sig); @@ -433,7 +445,7 @@ mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[ if (mono_type_get_type (type) == MONO_TYPE_VOID) return NULL; - return res; + return result; } MonoMethod* diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index b31c408e17c8e8..0eda7b3f4b44b2 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -26,7 +26,7 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_get_date_value_ref", "GetDateValueRef", "m"], ["_create_date_time", "CreateDateTime", "d!"], ["_create_uri", "CreateUri", "s!"], - ["_is_simple_array", "IsSimpleArray", "m"], + ["_is_simple_array_ref", "IsSimpleArrayRef", "m"], ]; export interface t_CSwraps { @@ -51,7 +51,7 @@ export interface t_CSwraps { _get_date_value_ref(obj: MonoObjectRef): number; _create_date_time(ticks: number): MonoObject; _create_uri(uri: string): MonoObject; - _is_simple_array(obj: MonoObject): boolean; + _is_simple_array_ref(obj: MonoObjectRef): boolean; } const wrapped_cs_functions: t_CSwraps = {}; diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 89453047a38825..faeb6ec3ea93b8 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -73,29 +73,29 @@ function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot20: // clr .NET DateTime - return new Date(corebindings._get_date_value_ref(root.get_address())); + return new Date(corebindings._get_date_value_ref(root.address)); case 21: // clr .NET DateTimeOffset - return corebindings._object_to_string_ref(root.get_address()); + return corebindings._object_to_string_ref(root.address); case MarshalType.URI: - return corebindings._object_to_string_ref(root.get_address()); + return corebindings._object_to_string_ref(root.address); case MarshalType.SAFEHANDLE: return _unbox_cs_owned_root_as_js_object(root); case MarshalType.VOID: return undefined; default: - throw new Error(`no idea on how to unbox object of MarshalType ${type} at offset ${root.value} (root address is ${root.get_address()})`); + throw new Error(`no idea on how to unbox object of MarshalType ${type} at offset ${root.value} (root address is ${root.address})`); } } export function _unbox_mono_obj_root_with_known_nonprimitive_type(root: WasmRoot, type: MarshalType, unbox_buffer: VoidPtr): any { if (type >= MarshalError.FIRST) - throw new Error(`Got marshaling error ${type} when attempting to unbox object at address ${root.value} (root located at ${root.get_address()})`); + throw new Error(`Got marshaling error ${type} when attempting to unbox object at address ${root.value} (root located at ${root.address})`); let typePtr = MonoTypeNull; if ((type === MarshalType.VT) || (type == MarshalType.OBJECT)) { typePtr = getU32(unbox_buffer); if (typePtr < 1024) - throw new Error(`Got invalid MonoType ${typePtr} for object at address ${root.value} (root located at ${root.get_address()})`); + throw new Error(`Got invalid MonoType ${typePtr} for object at address ${root.value} (root located at ${root.address})`); } return _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root, type, typePtr, unbox_buffer); @@ -106,7 +106,7 @@ export function _unbox_mono_obj_root(root: WasmRoot): any { return undefined; const unbox_buffer = runtimeHelpers._unbox_buffer; - const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.get_address(), unbox_buffer, runtimeHelpers._unbox_buffer_size); + const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.address, unbox_buffer, runtimeHelpers._unbox_buffer_size); switch (type) { case MarshalType.INT: return getI32(unbox_buffer); @@ -142,17 +142,17 @@ export function mono_array_to_js_array(mono_array: MonoArray): any[] | null { } } -function is_nested_array(ele: MonoObject) { - return corebindings._is_simple_array(ele); +function is_nested_array_ref(ele: WasmRoot) { + return corebindings._is_simple_array_ref(ele.address); } export function _mono_array_root_to_js_array(arrayRoot: WasmRoot): any[] | null { if (arrayRoot.value === MonoArrayNull) return null; - const arrayAddress = arrayRoot.get_address(); + const arrayAddress = arrayRoot.address; const elemRoot = mono_wasm_new_root(); - const elemAddress = elemRoot.get_address(); + const elemAddress = elemRoot.address; try { const len = cwraps.mono_wasm_array_length(arrayRoot.value); @@ -161,7 +161,7 @@ export function _mono_array_root_to_js_array(arrayRoot: WasmRoot): an // TODO: pass arrayRoot.address and elemRoot.address into new API that copies cwraps.mono_wasm_array_get_ref(arrayAddress, i, elemAddress); - if (is_nested_array(elemRoot.value)) + if (is_nested_array_ref(elemRoot)) res[i] = _mono_array_root_to_js_array(elemRoot); else res[i] = _unbox_mono_obj_root(elemRoot); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index a4d7d4d0034590..f513b58b458ecf 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -39,6 +39,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_assembly_find_type", "number", ["number", "string", "string"]], ["mono_wasm_assembly_find_method", "number", ["number", "string", "number"]], ["mono_wasm_invoke_method", "number", ["number", "number", "number", "number"]], + ["mono_wasm_invoke_method_ref", "void", ["number", "number", "number", "number", "number"]], ["mono_wasm_string_get_utf8", "number", ["number"]], ["mono_wasm_string_from_utf16", "number", ["number", "number"]], ["mono_wasm_get_obj_type", "number", ["number"]], @@ -101,7 +102,8 @@ export interface t_Cwraps { 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(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: VoidPtr): MonoObject; + mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; + mono_wasm_invoke_method_ref(method: MonoMethod, this_arg: MonoObjectRef, params: VoidPtr, out_exc: MonoObjectRef, out_result: MonoObjectRef): void; mono_wasm_string_get_utf8(str: MonoString): CharPtr; mono_wasm_string_from_utf16(str: CharPtr, len: number): MonoString; mono_wasm_get_obj_type(str: MonoObject): number; diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index d3f0d5f2043e29..d281deb88c1797 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -104,6 +104,7 @@ declare class WasmRootBuffer { interface WasmRoot { get_address(): MonoObjectRef; get_address_32(): number; + get address(): MonoObjectRef; get(): T; set(value: T): T; get value(): T; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 0e7e32ea11d250..1ac57bfc75d091 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -670,25 +670,37 @@ mono_wasm_box_primitive (MonoClass *klass, void *value, int value_size) return mono_value_box (root_domain, klass, value); } -EMSCRIPTEN_KEEPALIVE MonoObject* -mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **out_exc, MonoObject **out_result) { - MonoObject *exc = NULL; - MonoObject *res; - + MonoObject* temp_exc = NULL; if (out_exc) *out_exc = NULL; - res = mono_runtime_invoke (method, this_arg, params, &exc); - if (exc) { - if (out_exc) - *out_exc = exc; + else + out_exc = &temp_exc; + + if (out_result) { + *out_result = NULL; + *out_result = mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + } else { + mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + } + if (*out_exc && out_result) { MonoObject *exc2 = NULL; - res = (MonoObject*)mono_object_to_string (exc, &exc2); + *out_result = (MonoObject*)mono_object_to_string (*out_exc, &exc2); if (exc2) - res = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); - return res; + *out_result = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); + return; } +} + +// deprecated +MonoObject* +mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) +{ + MonoObject* result = NULL; + mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, &result); MonoMethodSignature *sig = mono_method_signature (method); MonoType *type = mono_signature_get_return_type (sig); @@ -698,7 +710,7 @@ mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[ if (mono_type_get_type (type) == MONO_TYPE_VOID) return NULL; - return res; + return result; } EMSCRIPTEN_KEEPALIVE MonoMethod* diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 399f7b042be092..65edcb46c411ee 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -173,8 +173,8 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul const mono_array = asString ? cwraps.mono_wasm_string_array_new(js_array.length) : cwraps.mono_wasm_obj_array_new(js_array.length); const arrayRoot = mono_wasm_new_root(mono_array); const elemRoot = mono_wasm_new_root(MonoObjectNull); - const arrayAddress = arrayRoot.get_address(); - const elemAddress = elemRoot.get_address(); + const arrayAddress = arrayRoot.address; + const elemAddress = elemRoot.address; try { for (let i = 0; i < js_array.length; ++i) { diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 4192f363e28c2c..01df2740867038 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -376,6 +376,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null if (typeof (args_marshal) !== "string") throw new Error("args_marshal argument invalid, expected string"); this_arg = coerceNull(this_arg); + const this_arg_root = this_arg ? mono_wasm_new_root(this_arg) : null; let converter: Converter | null = null; if (typeof (args_marshal) === "string") { @@ -405,9 +406,9 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null _teardown_after_call, mono_wasm_try_unbox_primitive_and_get_type_ref: cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref, _unbox_mono_obj_root_with_known_nonprimitive_type, - invoke_method: cwraps.mono_wasm_invoke_method, + invoke_method_ref: cwraps.mono_wasm_invoke_method_ref, method, - this_arg, + this_arg_root, token, unbox_buffer, unbox_buffer_size, @@ -481,7 +482,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null body.push( "", // TODO: Create new invoke_method variant that writes the result into resultRoot directly - "resultRoot.value = invoke_method (method, this_arg, buffer, exceptionRoot.get_address ());", + "invoke_method_ref (method, this_arg_root ? this_arg_root.address : 0, buffer, exceptionRoot.address, resultRoot.address);", `_handle_exception_for_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, argsRootBuffer);`, "", "let resultPtr = resultRoot.value, result = undefined;" @@ -501,7 +502,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null // into our existing heap allocation and then read it out of the heap. Doing this all in one operation // means that we only need to enter a gc safe region twice (instead of 3+ times with the normal, // slower check-type-and-then-unbox flow which has extra checks since unbox verifies the type). - " let resultType = mono_wasm_try_unbox_primitive_and_get_type_ref (resultRoot.get_address(), unbox_buffer, unbox_buffer_size);", + " let resultType = mono_wasm_try_unbox_primitive_and_get_type_ref (resultRoot.address, unbox_buffer, unbox_buffer_size);", " switch (resultType) {", ` case ${MarshalType.INT}:`, " result = getI32(unbox_buffer); break;", diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 94409f5fd6bbf0..1b7dc6b8b3a8eb 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -5,7 +5,7 @@ import { mono_wasm_new_root, mono_wasm_new_root_buffer, WasmRoot, WasmRootBuffer import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, coerceNull as coerceNull, - VoidPtrNull, MonoStringNull + VoidPtrNull, MonoStringNull, MonoObjectRef, MonoObjectRefNull } from "./types"; import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports"; import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js"; @@ -144,34 +144,40 @@ to suppress marshaling of the return value, place '!' at the end of args_marshal export function call_method(method: MonoMethod, this_arg: MonoObject | undefined, args_marshal: string/*ArgsMarshalString*/, args: ArrayLike): any { // HACK: Sometimes callers pass null or undefined, coerce it to 0 since that's what wasm expects this_arg = coerceNull(this_arg); + const this_arg_root = this_arg ? mono_wasm_new_root(this_arg) : null; + const this_arg_ref = this_arg ? (this_arg_root).address : MonoObjectRefNull; + try { + // Detect someone accidentally passing the wrong type of value to method + if (typeof method !== "number") + throw new Error(`method must be an address in the native heap, but was '${method}'`); + if (!method) + throw new Error("no method specified"); - // Detect someone accidentally passing the wrong type of value to method - if (typeof method !== "number") - throw new Error(`method must be an address in the native heap, but was '${method}'`); - if (!method) - throw new Error("no method specified"); - - const needs_converter = _verify_args_for_method_call(args_marshal, args); + const needs_converter = _verify_args_for_method_call(args_marshal, args); - let buffer = VoidPtrNull, converter = undefined, argsRootBuffer = undefined; - let is_result_marshaled = true; + let buffer = VoidPtrNull, converter = undefined, argsRootBuffer = undefined; + let is_result_marshaled = true; - // TODO: Only do this if the signature needs marshalling - _create_temp_frame(); + // TODO: Only do this if the signature needs marshalling + _create_temp_frame(); - // check if the method signature needs argument mashalling - if (needs_converter) { - converter = _compile_converter_for_marshal_string(args_marshal); + // check if the method signature needs argument mashalling + if (needs_converter) { + converter = _compile_converter_for_marshal_string(args_marshal); - is_result_marshaled = _decide_if_result_is_marshaled(converter, args.length); + is_result_marshaled = _decide_if_result_is_marshaled(converter, args.length); - argsRootBuffer = _get_args_root_buffer_for_method_call(converter, null); + argsRootBuffer = _get_args_root_buffer_for_method_call(converter, null); - const scratchBuffer = _get_buffer_for_method_call(converter, null); + const scratchBuffer = _get_buffer_for_method_call(converter, null); - buffer = converter.compiled_variadic_function!(scratchBuffer, argsRootBuffer, method, args); + buffer = converter.compiled_variadic_function!(scratchBuffer, argsRootBuffer, method, args); + } + return _call_method_with_converted_args(method, this_arg_ref, converter, null, buffer, is_result_marshaled, argsRootBuffer); + } finally { + if (this_arg_root) + this_arg_root.release(); } - return _call_method_with_converted_args(method, this_arg!, converter, null, buffer, is_result_marshaled, argsRootBuffer); } @@ -231,13 +237,13 @@ export function _teardown_after_call( } function _call_method_with_converted_args( - method: MonoMethod, this_arg: MonoObject, converter: Converter | undefined, + method: MonoMethod, this_arg_ref: MonoObjectRef, converter: Converter | undefined, token: BoundMethodToken | null, buffer: VoidPtr, is_result_marshaled: boolean, argsRootBuffer?: WasmRootBuffer ): any { const resultRoot = mono_wasm_new_root(), exceptionRoot = mono_wasm_new_root(); // TODO: Create new invoke_method variant that writes the result into resultRoot directly - resultRoot.value = cwraps.mono_wasm_invoke_method(method, this_arg, buffer, exceptionRoot.get_address()); + cwraps.mono_wasm_invoke_method_ref(method, this_arg_ref, buffer, exceptionRoot.address, resultRoot.address); return _handle_exception_and_produce_result_for_call(converter, token, buffer, resultRoot, exceptionRoot, argsRootBuffer, is_result_marshaled); } diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index e785469162b200..bcf5fe627de836 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -269,6 +269,7 @@ export class WasmRootBuffer { export interface WasmRoot { get_address(): MonoObjectRef; get_address_32(): number; + get address(): MonoObjectRef; get(): T; set(value: T): T; get value(): T; @@ -300,6 +301,10 @@ class WasmJsOwnedRoot implements WasmR return this.__buffer.get_address_32(this.__index); } + get address(): MonoObjectRef { + return this.__buffer.get_address(this.__index); + } + get(): T { const result = this.__buffer._unsafe_get(this.__index); return result; @@ -312,24 +317,24 @@ class WasmJsOwnedRoot implements WasmR } copy_from(source: WasmRoot): void { - const sourceAddress = source.get_address(); - const destinationAddress = this.get_address(); + const sourceAddress = source.address; + const destinationAddress = this.address; cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); } copy_to(destination: WasmRoot): void { - const sourceAddress = this.get_address(); - const destinationAddress = destination.get_address(); + const sourceAddress = this.address; + const destinationAddress = destination.address; cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); } copy_from_address(source: MonoObjectRef): void { - const destinationAddress = this.get_address(); + const destinationAddress = this.address; cwraps.mono_wasm_copy_managed_pointer(destinationAddress, source); } copy_to_address(destination: MonoObjectRef): void { - const sourceAddress = this.get_address(); + const sourceAddress = this.address; cwraps.mono_wasm_copy_managed_pointer(destination, sourceAddress); } @@ -365,7 +370,7 @@ class WasmJsOwnedRoot implements WasmR } toString(): string { - return `[root @${this.get_address()}]`; + return `[root @${this.address}]`; } } @@ -382,6 +387,10 @@ class WasmExternalRoot implements Wasm this.__external_address_32 = address >>> 2; } + get address(): MonoObjectRef { + return this.__external_address; + } + get_address(): MonoObjectRef { return this.__external_address; } @@ -401,14 +410,14 @@ class WasmExternalRoot implements Wasm } copy_from(source: WasmRoot): void { - const sourceAddress = source.get_address(); + const sourceAddress = source.address; const destinationAddress = this.__external_address; cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); } copy_to(destination: WasmRoot): void { const sourceAddress = this.__external_address; - const destinationAddress = destination.get_address(); + const destinationAddress = destination.address; cwraps.mono_wasm_copy_managed_pointer(destinationAddress, sourceAddress); } @@ -445,6 +454,6 @@ class WasmExternalRoot implements Wasm } toString(): string { - return `[external root @${this.get_address()}]`; + return `[external root @${this.address}]`; } } \ No newline at end of file diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index c3c5668615bfa1..1ae7a5307cceb0 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -43,7 +43,7 @@ export class StringDecoder { pLengthBytes = this.mono_wasm_string_decoder_buffer + 4, pIsInterned = this.mono_wasm_string_decoder_buffer + 8; - cwraps.mono_wasm_string_get_data_ref(root.get_address(), ppChars, pLengthBytes, pIsInterned); + cwraps.mono_wasm_string_get_data_ref(root.address, ppChars, pLengthBytes, pIsInterned); let result = mono_wasm_empty_string; const lengthBytes = getI32(pLengthBytes), @@ -143,7 +143,7 @@ function _store_string_in_intern_table(string: string, root: WasmRoot Date: Mon, 28 Feb 2022 16:36:06 -0800 Subject: [PATCH 029/128] Checkpoint (broken?) --- .../InteropServices/JavaScript/JSObject.cs | 4 +- .../JavaScript/Runtime.CS.Owned.cs | 20 +++---- .../JavaScript/Runtime.JS.Owned.cs | 10 ++-- src/mono/wasm/runtime/corebindings.ts | 27 +++++----- src/mono/wasm/runtime/cs-to-js.ts | 19 ++++--- src/mono/wasm/runtime/gc-handles.ts | 17 +++--- src/mono/wasm/runtime/js-to-cs.ts | 53 ++++++++++--------- 7 files changed, 81 insertions(+), 69 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs index 33588095b31583..c54f5266ed8b5f 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs @@ -64,7 +64,7 @@ public int AddEventListener(string name, Action listener, EventListene if (options?.Signal != null) throw new NotImplementedException("EventListenerOptions.Signal"); - var jsfunc = Runtime.GetJSOwnedObjectGCHandle(listener); + var jsfunc = Runtime.GetJSOwnedObjectGCHandleRef(listener); // int exception; if (options.HasValue) { // TODO: Optimize this @@ -93,7 +93,7 @@ public void RemoveEventListener(string name, Action? listener, EventLi if (listener == null) return; - var jsfunc = Runtime.GetJSOwnedObjectGCHandle(listener); + var jsfunc = Runtime.GetJSOwnedObjectGCHandleRef(listener); RemoveEventListener(name, jsfunc, options); } diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs index 370525c935a49e..89cd8baf56ac34 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs @@ -9,7 +9,7 @@ public static partial class Runtime { private static readonly Dictionary> _csOwnedObjects = new Dictionary>(); - public static JSObject? GetCSOwnedObjectByJSHandle(int jsHandle, int shouldAddInflight) + public static void GetCSOwnedObjectByJSHandleRef(int jsHandle, int shouldAddInflight, out JSObject? result) { lock (_csOwnedObjects) { @@ -20,14 +20,14 @@ public static partial class Runtime { jsObject.AddInFlight(); } - return jsObject; + result = jsObject; + return; } } - return null; - + result = null; } - public static int TryGetCSOwnedObjectJSHandle(object rawObj, int shouldAddInflight) + public static int TryGetCSOwnedObjectJSHandleRef(ref object rawObj, int shouldAddInflight) { JSObject? jsObject = rawObj as JSObject; if (jsObject != null && shouldAddInflight != 0) @@ -37,7 +37,7 @@ public static int TryGetCSOwnedObjectJSHandle(object rawObj, int shouldAddInflig return jsObject?.JSHandle ?? 0; } - public static int GetCSOwnedObjectJSHandle(JSObject jsObject, int shouldAddInflight) + public static int GetCSOwnedObjectJSHandleRef(ref JSObject jsObject, int shouldAddInflight) { jsObject.AssertNotDisposed(); @@ -48,9 +48,9 @@ public static int GetCSOwnedObjectJSHandle(JSObject jsObject, int shouldAddInfli return jsObject.JSHandle; } - public static JSObject CreateCSOwnedProxy(IntPtr jsHandle, MappedType mappedType, int shouldAddInflight) + public static void CreateCSOwnedProxyRef(IntPtr jsHandle, MappedType mappedType, int shouldAddInflight, out JSObject? jsObject) { - JSObject? jsObject = null; + jsObject = null; lock (_csOwnedObjects) { @@ -85,12 +85,11 @@ public static JSObject CreateCSOwnedProxy(IntPtr jsHandle, MappedType mappedType { jsObject.AddInFlight(); } - - return jsObject; } #region used from C# side + // TODO: Ref internal static bool ReleaseCSOwnedObject(JSObject objToRelease) { objToRelease.AssertNotDisposed(); @@ -103,6 +102,7 @@ internal static bool ReleaseCSOwnedObject(JSObject objToRelease) return true; } + // TODO: Ref internal static IntPtr CreateCSOwnedObject(JSObject proxy, string typeName, params object[] parms) { object res = Interop.Runtime.CreateCSOwnedObject(typeName, parms, out int exception); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index d91fd2407a8979..44fae1d71fd85b 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -13,10 +13,10 @@ public static partial class Runtime private static Dictionary GCHandleFromJSOwnedObject = new Dictionary(); - public static object GetJSOwnedObjectByGCHandle(int gcHandle) + public static void GetJSOwnedObjectByGCHandleRef(int gcHandle, out object result) { GCHandle h = (GCHandle)(IntPtr)gcHandle; - return h.Target!; + result = h.Target!; } // A JSOwnedObject is a managed object with its lifetime controlled by javascript. @@ -26,7 +26,7 @@ public static object GetJSOwnedObjectByGCHandle(int gcHandle) // strong references, allowing the managed object to be collected. // This ensures that things like delegates and promises will never 'go away' while JS // is expecting to be able to invoke or await them. - public static int GetJSOwnedObjectGCHandle(object obj) + public static int GetJSOwnedObjectGCHandleRef(in object obj) { if (obj == null) return 0; @@ -58,10 +58,10 @@ public static void ReleaseJSOwnedObjectByGCHandle(int gcHandle) public static int CreateTaskSource() { var tcs = new TaskCompletionSource(); - return GetJSOwnedObjectGCHandle(tcs); + return GetJSOwnedObjectGCHandleRef(tcs); } - public static void SetTaskSourceResult(int tcsGCHandle, object result) + public static void SetTaskSourceResultRef(int tcsGCHandle, ref object result) { GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; // this is JS owned Normal handle. We always have a Target diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index 0eda7b3f4b44b2..42a27e0054bba7 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -6,13 +6,13 @@ import { PromiseControl } from "./cancelable-promise"; import { runtimeHelpers } from "./imports"; const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMarshalString*/][] = [ - ["_get_cs_owned_object_by_js_handle", "GetCSOwnedObjectByJSHandle", "ii!"], - ["_get_cs_owned_object_js_handle", "GetCSOwnedObjectJSHandle", "mi"], - ["_try_get_cs_owned_object_js_handle", "TryGetCSOwnedObjectJSHandle", "mi"], - ["_create_cs_owned_proxy", "CreateCSOwnedProxy", "iii!"], + ["_get_cs_owned_object_by_js_handle_ref", "GetCSOwnedObjectByJSHandleRef", "iim"], + ["_get_cs_owned_object_js_handle_ref", "GetCSOwnedObjectJSHandleRef", "mi"], + ["_try_get_cs_owned_object_js_handle_ref", "TryGetCSOwnedObjectJSHandleRef", "mi"], + ["_create_cs_owned_proxy_ref", "CreateCSOwnedProxyRef", "iiim"], - ["_get_js_owned_object_by_gc_handle", "GetJSOwnedObjectByGCHandle", "i!"], - ["_get_js_owned_object_gc_handle", "GetJSOwnedObjectGCHandle", "m"], + ["_get_js_owned_object_by_gc_handle_ref", "GetJSOwnedObjectByGCHandleRef", "im"], + ["_get_js_owned_object_gc_handle_ref", "GetJSOwnedObjectGCHandleRef", "m"], ["_release_js_owned_object_by_gc_handle", "ReleaseJSOwnedObjectByGCHandle", "i"], ["_create_tcs", "CreateTaskSource", ""], @@ -31,17 +31,18 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar export interface t_CSwraps { // BINDING - _get_cs_owned_object_by_js_handle(jsHandle: JSHandle, shouldAddInflight: 0 | 1): MonoObject; - _get_cs_owned_object_js_handle(jsHandle: JSHandle, shouldAddInflight: 0 | 1): JSHandle; - _try_get_cs_owned_object_js_handle(obj: MonoObject, shouldAddInflight: 0 | 1): JSHandle; - _create_cs_owned_proxy(jsHandle: JSHandle, mappedType: number, shouldAddInflight: 0 | 1): MonoObject; + _get_cs_owned_object_by_js_handle_ref(jsHandle: JSHandle, shouldAddInflight: 0 | 1, result: MonoObjectRef): void; + _get_cs_owned_object_js_handle_ref(obj: MonoObjectRef, shouldAddInflight: 0 | 1): JSHandle; + _try_get_cs_owned_object_js_handle_ref(obj: MonoObjectRef, shouldAddInflight: 0 | 1): JSHandle; + _create_cs_owned_proxy_ref(jsHandle: JSHandle, mappedType: number, shouldAddInflight: 0 | 1, result: MonoObjectRef): void; - _get_js_owned_object_by_gc_handle(gcHandle: GCHandle): MonoObject; - _get_js_owned_object_gc_handle(obj: MonoObject): GCHandle + _get_js_owned_object_by_gc_handle_ref(gcHandle: GCHandle, result: MonoObjectRef): void; + _get_js_owned_object_gc_handle_ref(obj: MonoObjectRef): GCHandle _release_js_owned_object_by_gc_handle(gcHandle: GCHandle): void; _create_tcs(): GCHandle; - _set_tcs_result(gcHandle: GCHandle, result: MonoObject): void + // FIXME: We currently rely on marshaling to convert result types + _set_tcs_result(gcHandle: GCHandle, result: any): void _set_tcs_failure(gcHandle: GCHandle, result: string): void _get_tcs_task(gcHandle: GCHandle): MonoObject; _task_from_result(result: MonoObject): MonoObject diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index faeb6ec3ea93b8..b86c03cca87b12 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -11,7 +11,7 @@ import { runtimeHelpers } from "./imports"; import { conv_string_rooted } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; -import { get_js_owned_object_by_gc_handle, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; +import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; import { mono_method_get_call_signature, call_method, wrap_error } from "./method-calls"; import { _js_to_mono_obj } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; @@ -36,7 +36,7 @@ export function unbox_mono_obj(mono_obj: MonoObject): any { function _unbox_cs_owned_root_as_js_object(root: WasmRoot) { // we don't need in-flight reference as we already have it rooted here - const js_handle = corebindings._get_cs_owned_object_js_handle(root.value, 0); + const js_handle = corebindings._get_cs_owned_object_js_handle_ref(root.address, 0); const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); return js_obj; } @@ -177,7 +177,7 @@ export function _wrap_delegate_root_as_function(root: WasmRoot): Fun return null; // get strong reference to the Delegate - const gc_handle = corebindings._get_js_owned_object_gc_handle(root.value); + const gc_handle = corebindings._get_js_owned_object_gc_handle_ref(root.address); return _wrap_delegate_gc_handle_as_function(gc_handle); } @@ -189,8 +189,10 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ if (!result) { // note that we do not implement function/delegate roundtrip result = function (...args: any[]) { - const delegateRoot = mono_wasm_new_root(get_js_owned_object_by_gc_handle(gc_handle)); + const delegateRoot = mono_wasm_new_root(); + get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address); try { + // FIXME: Pass delegateRoot by-ref const res = call_method(result[delegate_invoke_symbol], delegateRoot.value, result[delegate_invoke_signature_symbol], args); if (after_listener_callback) { after_listener_callback(); @@ -202,7 +204,8 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ }; // bind the method - const delegateRoot = mono_wasm_new_root(get_js_owned_object_by_gc_handle(gc_handle)); + const delegateRoot = mono_wasm_new_root(); + get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address); try { if (typeof result[delegate_invoke_symbol] === "undefined") { result[delegate_invoke_symbol] = cwraps.mono_wasm_get_delegate_invoke(delegateRoot.value); @@ -283,7 +286,7 @@ function _unbox_task_root_as_promise(root: WasmRoot) { throw new Error("Promises are not supported thus 'System.Threading.Tasks.Task' can not work in this context."); // get strong reference to Task - const gc_handle = corebindings._get_js_owned_object_gc_handle(root.value); + const gc_handle = corebindings._get_js_owned_object_gc_handle_ref(root.address); // see if we have js owned instance for this gc_handle already let result = _lookup_js_owned_object(gc_handle); @@ -322,7 +325,7 @@ export function _unbox_ref_type_root_as_js_object(root: WasmRoot): a // this could be JSObject proxy of a js native object // we don't need in-flight reference as we already have it rooted here - const js_handle = corebindings._try_get_cs_owned_object_js_handle(root.value, 0); + const js_handle = corebindings._try_get_cs_owned_object_js_handle_ref(root.address, 0); if (js_handle) { if (js_handle === JSHandleDisposed) { throw new Error("Cannot access a disposed JSObject at " + root.value); @@ -332,7 +335,7 @@ export function _unbox_ref_type_root_as_js_object(root: WasmRoot): a // otherwise this is C# only object // get strong reference to Object - const gc_handle = corebindings._get_js_owned_object_gc_handle(root.value); + const gc_handle = corebindings._get_js_owned_object_gc_handle_ref(root.address); // see if we have js owned instance for this gc_handle already let result = _lookup_js_owned_object(gc_handle); diff --git a/src/mono/wasm/runtime/gc-handles.ts b/src/mono/wasm/runtime/gc-handles.ts index 18e8462021a7ba..2f335199f518d2 100644 --- a/src/mono/wasm/runtime/gc-handles.ts +++ b/src/mono/wasm/runtime/gc-handles.ts @@ -2,7 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. import corebindings from "./corebindings"; -import { GCHandle, JSHandle, JSHandleDisposed, JSHandleNull, MonoObject, MonoObjectNull } from "./types"; +import { GCHandle, JSHandle, JSHandleDisposed, JSHandleNull, MonoObjectRef } from "./types"; +import { setU32 } from "./memory"; import { create_weak_ref } from "./weak-ref"; export const _use_finalization_registry = typeof globalThis.FinalizationRegistry === "function"; @@ -24,12 +25,13 @@ export const js_owned_gc_handle_symbol = Symbol.for("wasm js_owned_gc_handle"); export const cs_owned_js_handle_symbol = Symbol.for("wasm cs_owned_js_handle"); -export function get_js_owned_object_by_gc_handle(gc_handle: GCHandle): MonoObject { +export function get_js_owned_object_by_gc_handle_ref(gc_handle: GCHandle, result: MonoObjectRef): void { if (!gc_handle) { - return MonoObjectNull; + setU32(result, 0); + return; } // this is always strong gc_handle - return corebindings._get_js_owned_object_by_gc_handle(gc_handle); + corebindings._get_js_owned_object_by_gc_handle_ref(gc_handle, result); } export function mono_wasm_get_jsobj_from_js_handle(js_handle: JSHandle): any { @@ -40,11 +42,12 @@ export function mono_wasm_get_jsobj_from_js_handle(js_handle: JSHandle): any { // when should_add_in_flight === true, the JSObject would be temporarily hold by Normal gc_handle, so that it would not get collected during transition to the managed stack. // its InFlight gc_handle would be freed when the instance arrives to managed side via Interop.Runtime.ReleaseInFlight -export function get_cs_owned_object_by_js_handle(js_handle: JSHandle, should_add_in_flight: boolean): MonoObject { +export function get_cs_owned_object_by_js_handle_ref(js_handle: JSHandle, should_add_in_flight: boolean, result: MonoObjectRef): void { if (js_handle === JSHandleNull || js_handle === JSHandleDisposed) { - return MonoObjectNull; + setU32(result, 0); + return; } - return corebindings._get_cs_owned_object_by_js_handle(js_handle, should_add_in_flight ? 1 : 0); + corebindings._get_cs_owned_object_by_js_handle_ref(js_handle, should_add_in_flight ? 1 : 0, result); } export function get_js_obj(js_handle: JSHandle): any { diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 65edcb46c411ee..41e6e37a7a19cf 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -3,7 +3,8 @@ import { Module, runtimeHelpers } from "./imports"; import { - cs_owned_js_handle_symbol, get_cs_owned_object_by_js_handle, get_js_owned_object_by_gc_handle, js_owned_gc_handle_symbol, + cs_owned_js_handle_symbol, get_cs_owned_object_by_js_handle_ref, + get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, mono_wasm_release_cs_owned_object, _js_owned_object_registry, _use_finalization_registry } from "./gc-handles"; @@ -80,34 +81,38 @@ function _extract_mono_obj(should_add_in_flight: boolean, js_obj: any): MonoObje if (js_obj === null || typeof js_obj === "undefined") return MonoObjectNull; - let result = null; - if (js_obj[js_owned_gc_handle_symbol]) { - // for js_owned_gc_handle we don't want to create new proxy - // since this is strong gc_handle we don't need to in-flight reference - result = get_js_owned_object_by_gc_handle(js_obj[js_owned_gc_handle_symbol]); - return result; - } - if (js_obj[cs_owned_js_handle_symbol]) { - result = get_cs_owned_object_by_js_handle(js_obj[cs_owned_js_handle_symbol], should_add_in_flight); - - // It's possible the managed object corresponding to this JS object was collected, - // in which case we need to make a new one. - if (!result) { - delete js_obj[cs_owned_js_handle_symbol]; + const resultRoot = mono_wasm_new_root(); + try { + if (js_obj[js_owned_gc_handle_symbol]) { + // for js_owned_gc_handle we don't want to create new proxy + // since this is strong gc_handle we don't need to in-flight reference + get_js_owned_object_by_gc_handle_ref(js_obj[js_owned_gc_handle_symbol], resultRoot.address); + return resultRoot.value; + } + if (js_obj[cs_owned_js_handle_symbol]) { + get_cs_owned_object_by_js_handle_ref(js_obj[cs_owned_js_handle_symbol], should_add_in_flight, resultRoot.address); + + // It's possible the managed object corresponding to this JS object was collected, + // in which case we need to make a new one. + if (!resultRoot.value) { + delete js_obj[cs_owned_js_handle_symbol]; + } } - } - if (!result) { - // Obtain the JS -> C# type mapping. - const wasm_type = js_obj[wasm_type_symbol]; - const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type; + if (!resultRoot.value) { + // Obtain the JS -> C# type mapping. + const wasm_type = js_obj[wasm_type_symbol]; + const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type; - const js_handle = mono_wasm_get_js_handle(js_obj); + const js_handle = mono_wasm_get_js_handle(js_obj); - result = corebindings._create_cs_owned_proxy(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0); - } + corebindings._create_cs_owned_proxy_ref(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0, resultRoot.address); + } - return result; + return resultRoot.value; + } finally { + resultRoot.release(); + } } function _box_js_int(js_obj: number) { From 727c49010e8cbbd9425e180a8b63d589a16b1a6e Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 28 Feb 2022 19:35:21 -0800 Subject: [PATCH 030/128] Fix missing method --- .../Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index 44fae1d71fd85b..f0a4245bff578f 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -61,7 +61,7 @@ public static int CreateTaskSource() return GetJSOwnedObjectGCHandleRef(tcs); } - public static void SetTaskSourceResultRef(int tcsGCHandle, ref object result) + public static void SetTaskSourceResult(int tcsGCHandle, object result) { GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; // this is JS owned Normal handle. We always have a Target From d283c87343b3856119c7ccbace6e980d87042515 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 16:21:22 -0800 Subject: [PATCH 031/128] Checkpoint --- src/mono/wasm/runtime/cwraps.ts | 15 +++++++++++---- src/mono/wasm/runtime/driver.c | 31 +++++++++++++++++++++++-------- src/mono/wasm/runtime/js-to-cs.ts | 9 ++++++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index f513b58b458ecf..fd5ba1caccd3e4 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -47,6 +47,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_array_get", "number", ["number", "number"]], ["mono_wasm_array_get_ref", "void", ["number", "number", "number"]], ["mono_wasm_obj_array_new", "number", ["number"]], + ["mono_wasm_obj_array_new_ref", "void", ["number", "number"]], ["mono_wasm_obj_array_set", "void", ["number", "number", "number"]], ["mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], ["mono_wasm_register_bundled_satellite_assemblies", "void", []], @@ -55,7 +56,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_intern_string_ref", "void", ["number"]], ["mono_wasm_assembly_get_entry_point", "number", ["number"]], ["mono_wasm_get_delegate_invoke", "number", ["number"]], - ["mono_wasm_string_array_new", "number", ["number"]], + ["mono_wasm_string_array_new_ref", "void", ["number", "number"]], ["mono_wasm_typed_array_new", "number", ["number", "number", "number", "number"]], ["mono_wasm_class_get_type", "number", ["number"]], ["mono_wasm_type_get_class", "number", ["number"]], @@ -108,10 +109,16 @@ export interface t_Cwraps { mono_wasm_string_from_utf16(str: CharPtr, len: number): MonoString; mono_wasm_get_obj_type(str: MonoObject): number; mono_wasm_array_length(array: MonoArray): number; - mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; - mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; + + // Deprecated mono_wasm_obj_array_new(size: number): MonoArray; + // Deprecated + mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; + // Deprecated mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; + + 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; @@ -119,7 +126,7 @@ export interface t_Cwraps { mono_wasm_intern_string_ref(strRef: MonoObjectRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; mono_wasm_get_delegate_invoke(delegate: MonoObject): MonoMethod; - mono_wasm_string_array_new(size: number): MonoArray; + mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; mono_wasm_typed_array_new(arr: VoidPtr, length: number, size: number, type: number): MonoArray; mono_wasm_class_get_type(klass: MonoClass): MonoType; mono_wasm_type_get_class(ty: MonoType): MonoClass; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 1ac57bfc75d091..abb88956485191 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -198,18 +198,18 @@ EMSCRIPTEN_KEEPALIVE int mono_wasm_register_root (char *start, size_t size, const char *name) { int result; - MONO_ENTER_GC_SAFE; + MONO_ENTER_GC_UNSAFE; result = mono_gc_register_root (start, size, (MonoGCDescriptor)NULL, MONO_ROOT_SOURCE_EXTERNAL, NULL, name ? name : "mono_wasm_register_root"); - MONO_EXIT_GC_SAFE; + MONO_EXIT_GC_UNSAFE; return result; } EMSCRIPTEN_KEEPALIVE void mono_wasm_deregister_root (char *addr) { - MONO_ENTER_GC_SAFE; + MONO_ENTER_GC_UNSAFE; mono_gc_deregister_root (addr); - MONO_EXIT_GC_SAFE; + MONO_EXIT_GC_UNSAFE; } #ifdef DRIVER_GEN @@ -1135,10 +1135,21 @@ mono_wasm_array_get_ref (MonoArray **array, int idx, MonoObject **result) MONO_EXIT_GC_UNSAFE; } +EMSCRIPTEN_KEEPALIVE void +mono_wasm_obj_array_new_ref (int size, MonoArray **result) +{ + MONO_ENTER_GC_UNSAFE; + *result = 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) { - return mono_array_new (root_domain, mono_get_object_class (), size); + MonoArray *result = NULL; + mono_wasm_obj_array_new_ref(size, &result); + return result; } EMSCRIPTEN_KEEPALIVE void @@ -1155,10 +1166,12 @@ mono_wasm_obj_array_set_ref (MonoArray **array, int idx, MonoObject **obj) MONO_EXIT_GC_UNSAFE; } -EMSCRIPTEN_KEEPALIVE MonoArray* -mono_wasm_string_array_new (int size) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_string_array_new_ref (int size, MonoArray **result) { - return mono_array_new (root_domain, mono_get_string_class (), size); + MONO_ENTER_GC_UNSAFE; + *result = mono_array_new (root_domain, mono_get_string_class (), size); + MONO_EXIT_GC_UNSAFE; } EMSCRIPTEN_KEEPALIVE int @@ -1200,7 +1213,9 @@ mono_wasm_enable_on_demand_gc (int enable) EMSCRIPTEN_KEEPALIVE void mono_wasm_intern_string_ref (MonoString **string) { + MONO_ENTER_GC_UNSAFE; *string = mono_string_intern (*string); + MONO_EXIT_GC_UNSAFE; } EMSCRIPTEN_KEEPALIVE void diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 41e6e37a7a19cf..e5215a49d529ae 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -175,8 +175,11 @@ export function js_to_mono_enum(js_obj: any, method: MonoMethod, parmIdx: number } export function js_array_to_mono_array(js_array: any[], asString: boolean, should_add_in_flight: boolean): MonoArray { - const mono_array = asString ? cwraps.mono_wasm_string_array_new(js_array.length) : cwraps.mono_wasm_obj_array_new(js_array.length); - const arrayRoot = mono_wasm_new_root(mono_array); + const arrayRoot = mono_wasm_new_root(); + if (asString) + cwraps.mono_wasm_string_array_new_ref(js_array.length, arrayRoot.address); + else + cwraps.mono_wasm_obj_array_new_ref(js_array.length, arrayRoot.address); const elemRoot = mono_wasm_new_root(MonoObjectNull); const arrayAddress = arrayRoot.address; const elemAddress = elemRoot.address; @@ -192,7 +195,7 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul cwraps.mono_wasm_obj_array_set_ref(arrayAddress, i, elemAddress); } - return mono_array; + return arrayRoot.value; } finally { mono_wasm_release_roots(arrayRoot, elemRoot); } From 6c692929a38f9817203de6cb6037e5dc8789eaeb Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 16:43:57 -0800 Subject: [PATCH 032/128] Checkpoint --- src/mono/wasm/runtime/cwraps.ts | 4 ++-- src/mono/wasm/runtime/driver.c | 27 +++++++++++++++------------ src/mono/wasm/runtime/js-to-cs.ts | 12 ++++++++---- src/mono/wasm/runtime/roots.ts | 4 ++-- src/mono/wasm/runtime/startup.ts | 5 ++++- src/mono/wasm/runtime/types.ts | 1 + 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index fd5ba1caccd3e4..3bd48ea25e4a22 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -52,7 +52,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_obj_array_set_ref", "void", ["number", "number", "number"]], ["mono_wasm_register_bundled_satellite_assemblies", "void", []], ["mono_wasm_try_unbox_primitive_and_get_type_ref", "number", ["number", "number", "number"]], - ["mono_wasm_box_primitive", "number", ["number", "number", "number"]], + ["mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]], ["mono_wasm_intern_string_ref", "void", ["number"]], ["mono_wasm_assembly_get_entry_point", "number", ["number"]], ["mono_wasm_get_delegate_invoke", "number", ["number"]], @@ -122,7 +122,7 @@ export interface t_Cwraps { 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(klass: MonoClass, value: VoidPtr, value_size: number): MonoObject; + mono_wasm_box_primitive_ref(klass: MonoClass, value: VoidPtr, value_size: number, result: MonoObjectRef): void; mono_wasm_intern_string_ref(strRef: MonoObjectRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; mono_wasm_get_delegate_invoke(delegate: MonoObject): MonoMethod; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index abb88956485191..65471d410c4b5e 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -656,18 +656,20 @@ mono_wasm_get_delegate_invoke (MonoObject *delegate) return mono_get_delegate_invoke(mono_object_get_class (delegate)); } -EMSCRIPTEN_KEEPALIVE MonoObject* -mono_wasm_box_primitive (MonoClass *klass, void *value, int value_size) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_box_primitive_ref (MonoClass *klass, void *value, int value_size, MonoObject **result) { assert (klass); MonoType *type = mono_class_get_type (klass); int alignment; if (mono_type_size (type, &alignment) > value_size) - return NULL; + return; // TODO: use mono_value_box_checked and propagate error out - return mono_value_box (root_domain, klass, value); + MONO_ENTER_GC_UNSAFE; + mono_gc_wbarrier_generic_store_atomic(result, mono_value_box (root_domain, klass, value)); + MONO_EXIT_GC_UNSAFE; } EMSCRIPTEN_KEEPALIVE void @@ -679,20 +681,21 @@ mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void else out_exc = &temp_exc; + MONO_ENTER_GC_UNSAFE; if (out_result) { *out_result = NULL; - *out_result = mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + mono_gc_wbarrier_generic_store_atomic(out_result, mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc)); } else { mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); } if (*out_exc && out_result) { MonoObject *exc2 = NULL; - *out_result = (MonoObject*)mono_object_to_string (*out_exc, &exc2); + mono_gc_wbarrier_generic_store_atomic(out_result, (MonoObject*)mono_object_to_string (*out_exc, &exc2)); if (exc2) - *out_result = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault"); - return; + mono_gc_wbarrier_generic_store_atomic(out_result, (MonoObject*)mono_string_new (root_domain, "Exception Double Fault")); } + MONO_EXIT_GC_UNSAFE; } // deprecated @@ -1131,7 +1134,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_array_get_ref (MonoArray **array, int idx, MonoObject **result) { MONO_ENTER_GC_UNSAFE; - *result = mono_array_get (*array, MonoObject*, idx); + mono_gc_wbarrier_generic_store_atomic(result, mono_array_get (*array, MonoObject*, idx)); MONO_EXIT_GC_UNSAFE; } @@ -1139,7 +1142,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_obj_array_new_ref (int size, MonoArray **result) { MONO_ENTER_GC_UNSAFE; - *result = mono_array_new (root_domain, mono_get_object_class (), size); + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_object_class (), size)); MONO_EXIT_GC_UNSAFE; } @@ -1170,7 +1173,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_string_array_new_ref (int size, MonoArray **result) { MONO_ENTER_GC_UNSAFE; - *result = mono_array_new (root_domain, mono_get_string_class (), size); + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_array_new (root_domain, mono_get_string_class (), size)); MONO_EXIT_GC_UNSAFE; } @@ -1214,7 +1217,7 @@ EMSCRIPTEN_KEEPALIVE void mono_wasm_intern_string_ref (MonoString **string) { MONO_ENTER_GC_UNSAFE; - *string = mono_string_intern (*string); + mono_gc_wbarrier_generic_store_atomic(string, (MonoObject *)mono_string_intern (*string)); MONO_EXIT_GC_UNSAFE; } diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index e5215a49d529ae..be155e0374f8b3 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -117,22 +117,26 @@ function _extract_mono_obj(should_add_in_flight: boolean, js_obj: any): MonoObje function _box_js_int(js_obj: number) { setI32(runtimeHelpers._box_buffer, js_obj); - return cwraps.mono_wasm_box_primitive(runtimeHelpers._class_int32, runtimeHelpers._box_buffer, 4); + cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_int32, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); + return runtimeHelpers._box_root.value; } function _box_js_uint(js_obj: number) { setU32(runtimeHelpers._box_buffer, js_obj); - return cwraps.mono_wasm_box_primitive(runtimeHelpers._class_uint32, runtimeHelpers._box_buffer, 4); + cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_uint32, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); + return runtimeHelpers._box_root.value; } function _box_js_double(js_obj: number) { setF64(runtimeHelpers._box_buffer, js_obj); - return cwraps.mono_wasm_box_primitive(runtimeHelpers._class_double, runtimeHelpers._box_buffer, 8); + cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_double, runtimeHelpers._box_buffer, 8, runtimeHelpers._box_root.address); + return runtimeHelpers._box_root.value; } export function _box_js_bool(js_obj: boolean): MonoObject { setI32(runtimeHelpers._box_buffer, js_obj ? 1 : 0); - return cwraps.mono_wasm_box_primitive(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4); + cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); + return runtimeHelpers._box_root.value; } // https://github.com/Planeshifter/emscripten-examples/blob/master/01_PassingArrays/sum_post.js diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index bcf5fe627de836..1938e14727b036 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -347,7 +347,7 @@ class WasmJsOwnedRoot implements WasmR } valueOf(): T { - return this.get(); + throw new Error("Implicit conversion of roots to pointers is no longer supported. Use .value or .address as appropriate"); } clear(): void { @@ -440,7 +440,7 @@ class WasmExternalRoot implements Wasm } valueOf(): T { - return this.get(); + throw new Error("Implicit conversion of roots to pointers is no longer supported. Use .value or .address as appropriate"); } clear(): void { diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 4c9d092ee6b010..5d5ed98117bae8 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.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 { AllAssetEntryTypes, assert, AssetEntry, CharPtrNull, DotnetModule, GlobalizationMode, MonoConfig, MonoConfigError, wasm_type_symbol } from "./types"; +import { AllAssetEntryTypes, assert, AssetEntry, CharPtrNull, DotnetModule, GlobalizationMode, MonoConfig, MonoConfigError, wasm_type_symbol, MonoObject } from "./types"; import { ENVIRONMENT_IS_ESM, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, locateFile, Module, MONO, requirePromise, runtimeHelpers } from "./imports"; import cwraps from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; @@ -14,6 +14,7 @@ import { find_corlib_class } from "./class-loader"; import { VoidPtr, CharPtr } from "./types/emscripten"; import { DotnetPublicAPI } from "./exports"; import { mono_on_abort } from "./run"; +import { mono_wasm_new_root } from "./roots"; export let runtime_is_initialized_resolve: Function; export let runtime_is_initialized_reject: Function; @@ -401,6 +402,8 @@ export function bindings_lazy_init(): void { throw "Can't find GetCallSignature method"; _create_primitive_converters(); + + runtimeHelpers._box_root = mono_wasm_new_root(); } // Initializes the runtime and loads assemblies, debug information, and other files. diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index 558c00ccba1d59..2ddd6ed4ea0282 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -129,6 +129,7 @@ export type RuntimeHelpers = { _box_buffer: VoidPtr; _unbox_buffer: VoidPtr; + _box_root: any; _class_int32: MonoClass; _class_uint32: MonoClass; _class_double: MonoClass; From a28c63c6f274a7fa259fb5462c81e85af5d9710e Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 17:49:12 -0800 Subject: [PATCH 033/128] Checkpoint (broken) --- src/mono/wasm/runtime/cwraps.ts | 4 +- src/mono/wasm/runtime/driver.c | 15 ++-- src/mono/wasm/runtime/exports.ts | 3 + src/mono/wasm/runtime/js-to-cs.ts | 2 +- src/mono/wasm/runtime/method-binding.ts | 2 +- src/mono/wasm/runtime/method-calls.ts | 8 +- src/mono/wasm/runtime/strings.ts | 102 ++++++++++++++++-------- 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 3bd48ea25e4a22..4c2f7665131412 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -41,7 +41,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_invoke_method", "number", ["number", "number", "number", "number"]], ["mono_wasm_invoke_method_ref", "void", ["number", "number", "number", "number", "number"]], ["mono_wasm_string_get_utf8", "number", ["number"]], - ["mono_wasm_string_from_utf16", "number", ["number", "number"]], + ["mono_wasm_string_from_utf16_ref", "void", ["number", "number", "number"]], ["mono_wasm_get_obj_type", "number", ["number"]], ["mono_wasm_array_length", "number", ["number"]], ["mono_wasm_array_get", "number", ["number", "number"]], @@ -106,7 +106,7 @@ export interface t_Cwraps { mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; mono_wasm_invoke_method_ref(method: MonoMethod, this_arg: MonoObjectRef, params: VoidPtr, out_exc: MonoObjectRef, out_result: MonoObjectRef): void; mono_wasm_string_get_utf8(str: MonoString): CharPtr; - mono_wasm_string_from_utf16(str: CharPtr, len: number): MonoString; + mono_wasm_string_from_utf16_ref(str: CharPtr, len: number, result: MonoObjectRef): void; mono_wasm_get_obj_type(str: MonoObject): number; mono_wasm_array_length(array: MonoArray): number; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 65471d410c4b5e..164f34e99b00e6 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -783,15 +783,18 @@ mono_wasm_string_from_js (const char *str) return NULL; } -EMSCRIPTEN_KEEPALIVE MonoString * -mono_wasm_string_from_utf16 (const mono_unichar2 * chars, int length) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_string_from_utf16_ref (const mono_unichar2 * chars, int length, MonoString **result) { assert (length >= 0); - if (chars) - return mono_string_new_utf16 (root_domain, chars, length); - else - return NULL; + MONO_ENTER_GC_UNSAFE; + if (chars) { + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)mono_string_new_utf16 (root_domain, chars, length)); + } else { + mono_gc_wbarrier_generic_store_atomic(result, NULL); + } + MONO_EXIT_GC_UNSAFE; } static int diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index bd9620b079315c..f52f2d8d4a2f61 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -112,8 +112,11 @@ export type MONOType = typeof MONO; const BINDING = { //current "public" BINDING API + // Deprecated mono_obj_array_new: cwraps.mono_wasm_obj_array_new, + // Deprecated mono_obj_array_set: cwraps.mono_wasm_obj_array_set, + // Deprecated js_string_to_mono_string, js_typed_array_to_array, js_to_mono_obj, diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index be155e0374f8b3..0fada5530b8119 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -12,7 +12,7 @@ import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { mono_wasm_new_root, mono_wasm_release_roots } from "./roots"; import { wrap_error } from "./method-calls"; -import { js_string_to_mono_string, js_string_to_mono_string_interned } from "./strings"; +import { js_string_to_mono_string_ref, js_string_to_mono_string_interned_ref } from "./strings"; import { isThenable } from "./cancelable-promise"; import { has_backing_array_buffer } from "./buffers"; import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, wasm_type_symbol } from "./types"; diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 01df2740867038..83d335d63ea23b 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -5,7 +5,7 @@ import { WasmRoot, WasmRootBuffer, mono_wasm_new_root } from "./roots"; import { MonoClass, MonoMethod, MonoObject, coerceNull, VoidPtrNull, MonoType, MarshalType } from "./types"; import { BINDING, Module, runtimeHelpers } from "./imports"; import { js_to_mono_enum, _js_to_mono_obj, _js_to_mono_uri } from "./js-to-cs"; -import { js_string_to_mono_string, js_string_to_mono_string_interned } from "./strings"; +import { js_string_to_mono_string_ref, js_string_to_mono_string_interned_ref } from "./strings"; import { _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js"; import { _create_temp_frame, diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 1b7dc6b8b3a8eb..a35e2cab16fc06 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -17,7 +17,7 @@ import { _decide_if_result_is_marshaled, find_method, BoundMethodToken } from "./method-binding"; -import { conv_string, conv_string_rooted, js_string_to_mono_string } from "./strings"; +import { conv_string, conv_string_rooted, js_string_to_mono_string, js_string_to_mono_string_rooted } from "./strings"; import cwraps from "./cwraps"; import { bindings_lazy_init } from "./startup"; import { _create_temp_frame, _release_temp_frame } from "./memory"; @@ -536,8 +536,10 @@ export function mono_wasm_invoke_js_blazor(exceptionMessage: Int32Ptr, callInfo: return blazorExports._internal.invokeJSFromDotNet(callInfo, arg0, arg1, arg2); } catch (ex: any) { const exceptionJsString = ex.message + "\n" + ex.stack; - const exceptionSystemString = cwraps.mono_wasm_string_from_js(exceptionJsString); - Module.setValue(exceptionMessage, exceptionSystemString, "i32"); // *exceptionMessage = exceptionSystemString; + const exceptionRoot = mono_wasm_new_root(); + js_string_to_mono_string_rooted(exceptionJsString, exceptionRoot); + exceptionRoot.copy_to_address(exceptionMessage); + exceptionRoot.release(); return 0; } } diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 1ae7a5307cceb0..4993f60aaf0ed2 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -159,7 +159,7 @@ function _store_string_in_intern_table(string: string, root: WasmRoot): void { const text = (typeof (string) === "symbol") ? (string.description || Symbol.keyFor(string) || "") : string; @@ -170,55 +170,89 @@ export function js_string_to_mono_string_interned(string: string | symbol): Mono throw new Error(`Argument to js_string_to_mono_string_interned must be a string but was ${string}`); } - if ((text.length === 0) && _empty_string_ptr) - return _empty_string_ptr; + if ((text.length === 0) && _empty_string_ptr) { + result.set(_empty_string_ptr); + return; + } const ptr = interned_js_string_table.get(text); - if (ptr) - return ptr; - - const root = mono_wasm_new_root(); - try { - root.value = js_string_to_mono_string_new(text); - _store_string_in_intern_table(text, root, true); - return root.value; - } finally { - root.release(); + if (ptr) { + result.set(ptr); + return; } + + js_string_to_mono_string_new_rooted(text, result); + _store_string_in_intern_table(text, result, true); } -export function js_string_to_mono_string(string: string): MonoString { +export function js_string_to_mono_string_rooted(string: string, result: WasmRoot): void { + result.clear(); + if (string === null) - return MonoStringNull; + return; else if (typeof (string) === "symbol") - return js_string_to_mono_string_interned(string); + js_string_to_mono_string_interned_rooted(string, result); else if (typeof (string) !== "string") throw new Error("Expected string argument, got " + typeof (string)); + else if (string.length === 0) + // Always use an interned pointer for empty strings + js_string_to_mono_string_interned_rooted(string, result); + else { + // Looking up large strings in the intern table will require the JS runtime to + // potentially hash them and then do full byte-by-byte comparisons, which is + // very expensive. Because we can not guarantee it won't happen, try to minimize + // the cost of this and prevent performance issues for large strings + if (string.length <= 256) { + const interned = interned_js_string_table.get(string); + if (interned) { + result.set(interned); + return; + } + } - // Always use an interned pointer for empty strings - if (string.length === 0) - return js_string_to_mono_string_interned(string); - - // Looking up large strings in the intern table will require the JS runtime to - // potentially hash them and then do full byte-by-byte comparisons, which is - // very expensive. Because we can not guarantee it won't happen, try to minimize - // the cost of this and prevent performance issues for large strings - if (string.length <= 256) { - const interned = interned_js_string_table.get(string); - if (interned) - return interned; + js_string_to_mono_string_new_rooted(string, result); } - - return js_string_to_mono_string_new(string); } -export function js_string_to_mono_string_new(string: string): MonoString { +export function js_string_to_mono_string_new_rooted(string: string, result: WasmRoot): void { const buffer = Module._malloc((string.length + 1) * 2); const buffer16 = (buffer >>> 1) | 0; for (let i = 0; i < string.length; i++) Module.HEAP16[buffer16 + i] = string.charCodeAt(i); Module.HEAP16[buffer16 + string.length] = 0; - const result = cwraps.mono_wasm_string_from_utf16(buffer, string.length); + cwraps.mono_wasm_string_from_utf16_ref(buffer, string.length, result.address); Module._free(buffer); - return result; -} \ No newline at end of file +} + +// Deprecated +export function js_string_to_mono_string_interned(string: string | symbol): MonoString { + const temp = mono_wasm_new_root(); + try { + js_string_to_mono_string_interned_rooted(string, temp); + return temp.value; + } finally { + temp.release(); + } +} + +// Deprecated +export function js_string_to_mono_string(string: string): MonoString { + const temp = mono_wasm_new_root(); + try { + js_string_to_mono_string_rooted(string, temp); + return temp.value; + } finally { + temp.release(); + } +} + +// Deprecated +export function js_string_to_mono_string_new(string: string): MonoString { + const temp = mono_wasm_new_root(); + try { + js_string_to_mono_string_new_rooted(string, temp); + return temp.value; + } finally { + temp.release(); + } +} From 1315a4ab9eac832c7a339f1f6800a99adfcf4e95 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 17:59:06 -0800 Subject: [PATCH 034/128] Checkpoint (broken) --- src/mono/wasm/runtime/js-to-cs.ts | 139 ++++++++++++------------ src/mono/wasm/runtime/method-binding.ts | 15 ++- src/mono/wasm/runtime/strings.ts | 4 +- 3 files changed, 81 insertions(+), 77 deletions(-) diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 0fada5530b8119..48e51cfd078517 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -10,12 +10,12 @@ import { } from "./gc-handles"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; -import { mono_wasm_new_root, mono_wasm_release_roots } from "./roots"; +import { mono_wasm_new_root, mono_wasm_release_roots, WasmRoot } from "./roots"; import { wrap_error } from "./method-calls"; -import { js_string_to_mono_string_ref, js_string_to_mono_string_interned_ref } from "./strings"; +import { js_string_to_mono_string_rooted, js_string_to_mono_string_interned_rooted } from "./strings"; import { isThenable } from "./cancelable-promise"; import { has_backing_array_buffer } from "./buffers"; -import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, wasm_type_symbol } from "./types"; +import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, wasm_type_symbol, MonoClass } from "./types"; import { setI32, setU32, setF64 } from "./memory"; import { Int32Ptr, TypedArray } from "./types/emscripten"; @@ -36,101 +36,100 @@ export function _js_to_mono_uri(should_add_in_flight: boolean, js_obj: any): Mon // this is only used from Blazor // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function js_to_mono_obj(js_obj: any): MonoObject { - return _js_to_mono_obj(false, js_obj); + const temp = mono_wasm_new_root(); + try { + _js_to_mono_obj_rooted(false, js_obj, temp); + return temp.value; + } finally { + temp.release(); + } } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function _js_to_mono_obj(should_add_in_flight: boolean, js_obj: any): MonoObject { +export function _js_to_mono_obj_rooted(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { switch (true) { case js_obj === null: case typeof js_obj === "undefined": - return MonoObjectNull; + result.clear(); + return; case typeof js_obj === "number": { - let result = null; - if ((js_obj | 0) === js_obj) - result = _box_js_int(js_obj); - else if ((js_obj >>> 0) === js_obj) - result = _box_js_uint(js_obj); - else - result = _box_js_double(js_obj); - - if (!result) - throw new Error(`Boxing failed for ${js_obj}`); + let box_class : MonoClass; + if ((js_obj | 0) === js_obj) { + setI32(runtimeHelpers._box_buffer, js_obj); + box_class = runtimeHelpers._class_int32; + } else if ((js_obj >>> 0) === js_obj) { + setU32(runtimeHelpers._box_buffer, js_obj); + box_class = runtimeHelpers._class_uint32; + } else { + setF64(runtimeHelpers._box_buffer, js_obj); + box_class = runtimeHelpers._class_double; + } - return result; - } case typeof js_obj === "string": - return js_string_to_mono_string(js_obj); + cwraps.mono_wasm_box_primitive_ref(box_class, runtimeHelpers._box_buffer, 8, result.address); + + if (!result.value) + throw new Error(`Boxing failed for ${js_obj}`); + return; + } + case typeof js_obj === "string": + js_string_to_mono_string_rooted(js_obj, result); + return; case typeof js_obj === "symbol": - return js_string_to_mono_string_interned(js_obj); + js_string_to_mono_string_interned_rooted(js_obj, result); + return; case typeof js_obj === "boolean": - return _box_js_bool(js_obj); + // FIXME + result.value = _box_js_bool(js_obj); + return; case isThenable(js_obj) === true: { + // FIXME: ref/rooted const { task_ptr } = _wrap_js_thenable_as_task(js_obj); // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC - return task_ptr; + result.value = task_ptr; + return; } case js_obj.constructor.name === "Date": // getTime() is always UTC - return corebindings._create_date_time(js_obj.getTime()); + // FIXME: ref/rooted + result.value = corebindings._create_date_time(js_obj.getTime()); + return; default: - return _extract_mono_obj(should_add_in_flight, js_obj); + _extract_mono_obj_rooted(should_add_in_flight, js_obj, result); + return; } } -function _extract_mono_obj(should_add_in_flight: boolean, js_obj: any): MonoObject { - if (js_obj === null || typeof js_obj === "undefined") - return MonoObjectNull; - - const resultRoot = mono_wasm_new_root(); - try { - if (js_obj[js_owned_gc_handle_symbol]) { - // for js_owned_gc_handle we don't want to create new proxy - // since this is strong gc_handle we don't need to in-flight reference - get_js_owned_object_by_gc_handle_ref(js_obj[js_owned_gc_handle_symbol], resultRoot.address); - return resultRoot.value; - } - if (js_obj[cs_owned_js_handle_symbol]) { - get_cs_owned_object_by_js_handle_ref(js_obj[cs_owned_js_handle_symbol], should_add_in_flight, resultRoot.address); +function _extract_mono_obj_rooted(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { + result.clear(); - // It's possible the managed object corresponding to this JS object was collected, - // in which case we need to make a new one. - if (!resultRoot.value) { - delete js_obj[cs_owned_js_handle_symbol]; - } - } - - if (!resultRoot.value) { - // Obtain the JS -> C# type mapping. - const wasm_type = js_obj[wasm_type_symbol]; - const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type; + if (js_obj === null || typeof js_obj === "undefined") + return; - const js_handle = mono_wasm_get_js_handle(js_obj); + if (js_obj[js_owned_gc_handle_symbol]) { + // for js_owned_gc_handle we don't want to create new proxy + // since this is strong gc_handle we don't need to in-flight reference + get_js_owned_object_by_gc_handle_ref(js_obj[js_owned_gc_handle_symbol], result.address); + return; + } + if (js_obj[cs_owned_js_handle_symbol]) { + get_cs_owned_object_by_js_handle_ref(js_obj[cs_owned_js_handle_symbol], should_add_in_flight, result.address); - corebindings._create_cs_owned_proxy_ref(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0, resultRoot.address); + // It's possible the managed object corresponding to this JS object was collected, + // in which case we need to make a new one. + if (!result.value) { + delete js_obj[cs_owned_js_handle_symbol]; } - - return resultRoot.value; - } finally { - resultRoot.release(); } -} -function _box_js_int(js_obj: number) { - setI32(runtimeHelpers._box_buffer, js_obj); - cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_int32, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); - return runtimeHelpers._box_root.value; -} + if (!result.value) { + // Obtain the JS -> C# type mapping. + const wasm_type = js_obj[wasm_type_symbol]; + const wasm_type_id = typeof wasm_type === "undefined" ? 0 : wasm_type; -function _box_js_uint(js_obj: number) { - setU32(runtimeHelpers._box_buffer, js_obj); - cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_uint32, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); - return runtimeHelpers._box_root.value; -} + const js_handle = mono_wasm_get_js_handle(js_obj); -function _box_js_double(js_obj: number) { - setF64(runtimeHelpers._box_buffer, js_obj); - cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_double, runtimeHelpers._box_buffer, 8, runtimeHelpers._box_root.address); - return runtimeHelpers._box_root.value; + corebindings._create_cs_owned_proxy_ref(js_handle, wasm_type_id, should_add_in_flight ? 1 : 0, result.address); + } } export function _box_js_bool(js_obj: boolean): MonoObject { diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 83d335d63ea23b..c9c94d2df5fb26 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -4,8 +4,8 @@ import { WasmRoot, WasmRootBuffer, mono_wasm_new_root } from "./roots"; import { MonoClass, MonoMethod, MonoObject, coerceNull, VoidPtrNull, MonoType, MarshalType } from "./types"; import { BINDING, Module, runtimeHelpers } from "./imports"; -import { js_to_mono_enum, _js_to_mono_obj, _js_to_mono_uri } from "./js-to-cs"; -import { js_string_to_mono_string_ref, js_string_to_mono_string_interned_ref } from "./strings"; +import { js_to_mono_enum, _js_to_mono_obj_rooted, _js_to_mono_uri } from "./js-to-cs"; +import { js_string_to_mono_string_rooted, js_string_to_mono_string_interned_rooted } from "./strings"; import { _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js"; import { _create_temp_frame, @@ -122,12 +122,12 @@ export function _create_rebindable_named_function(name: string, argumentNames: s export function _create_primitive_converters(): void { const result = primitiveConverters; result.set("m", { steps: [{}], size: 0 }); - result.set("s", { steps: [{ convert: js_string_to_mono_string.bind(BINDING) }], size: 0, needs_root: true }); - result.set("S", { steps: [{ convert: js_string_to_mono_string_interned.bind(BINDING) }], size: 0, needs_root: true }); + result.set("s", { steps: [{ convert_rooted: js_string_to_mono_string_rooted.bind(BINDING) }], size: 0, needs_root: true }); + result.set("S", { steps: [{ convert_rooted: js_string_to_mono_string_interned_rooted.bind(BINDING) }], size: 0, needs_root: true }); // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, // because we will root the reference, so we don't need in-flight reference // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end - result.set("o", { steps: [{ convert: _js_to_mono_obj.bind(BINDING, false) }], size: 0, needs_root: true }); + result.set("o", { steps: [{ convert_rooted: _js_to_mono_obj_rooted.bind(BINDING, false) }], size: 0, needs_root: true }); result.set("u", { steps: [{ convert: _js_to_mono_uri.bind(BINDING, false) }], size: 0, needs_root: true }); // result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); @@ -241,7 +241,9 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args const argKey = "arg" + i; argumentNames.push(argKey); - if (step.convert) { + if (step.convert_rooted) { + throw new Error("Not implemented: Converter.convert_rooted"); + } else if (step.convert) { closure[closureKey] = step.convert; body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`); } else { @@ -581,6 +583,7 @@ type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "i64" export type Converter = { steps: { convert?: boolean | Function; + convert_rooted?: Function; needs_root?: boolean; needs_unbox?: boolean; indirect?: ConverterStepIndirects; diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 4993f60aaf0ed2..ec247345492d1a 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { mono_wasm_new_root_buffer, WasmRootBuffer } from "./roots"; -import { MonoString, MonoStringNull, MonoObjectRef, MonoObjectRefNull } from "./types"; +import { MonoString, MonoStringNull } from "./types"; import { Module } from "./imports"; import cwraps from "./cwraps"; import { mono_wasm_new_root, WasmRoot } from "./roots"; @@ -114,6 +114,8 @@ export function mono_intern_string(string: string): string { if (string.length === 0) return mono_wasm_empty_string; + // HACK: This would normally be unsafe, but the return value of js_string_to_mono_string_interned is always an + // interned string, so the address will never change and it is safe for us to use the raw pointer. Don't do this though const ptr = js_string_to_mono_string_interned(string); const result = interned_string_table.get(ptr); if (!result) From 2e2fc35a4ea79789956a10eab647057ce752c65d Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 18:10:55 -0800 Subject: [PATCH 035/128] Checkpoint --- src/mono/wasm/runtime/buffers.ts | 8 ++--- src/mono/wasm/runtime/cs-to-js.ts | 10 +++--- src/mono/wasm/runtime/dotnet.d.ts | 5 +-- src/mono/wasm/runtime/event-listener.ts | 6 ++-- src/mono/wasm/runtime/exports.ts | 6 ++-- src/mono/wasm/runtime/js-to-cs.ts | 41 +++++++++++++++++-------- src/mono/wasm/runtime/method-binding.ts | 23 ++++++++------ src/mono/wasm/runtime/method-calls.ts | 26 ++++++++-------- src/mono/wasm/runtime/strings.ts | 28 ++++++++--------- src/mono/wasm/runtime/web-socket.ts | 6 ++-- 10 files changed, 90 insertions(+), 69 deletions(-) diff --git a/src/mono/wasm/runtime/buffers.ts b/src/mono/wasm/runtime/buffers.ts index b0437231ccb8bf..6aa725de23f910 100644 --- a/src/mono/wasm/runtime/buffers.ts +++ b/src/mono/wasm/runtime/buffers.ts @@ -5,7 +5,7 @@ import { JSHandle, MonoArray, MonoObject, MonoString } from "./types"; import { Module } from "./imports"; import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; import { wrap_error } from "./method-calls"; -import { _js_to_mono_obj } from "./js-to-cs"; +import { _js_to_mono_obj_unsafe } from "./js-to-cs"; import { Int32Ptr, TypedArray, VoidPtr } from "./types/emscripten"; // Creates a new typed array from pinned array address from pinned_array allocated on the heap to the typed array. @@ -142,14 +142,14 @@ export function mono_wasm_typed_array_copy_to(js_handle: JSHandle, pinned_array: const res = typedarray_copy_to(js_obj, pinned_array, begin, end, bytes_per_element); // returns num_of_bytes boxed - return _js_to_mono_obj(false, res); + return _js_to_mono_obj_unsafe(false, res); } // eslint-disable-next-line @typescript-eslint/no-unused-vars export function mono_wasm_typed_array_from(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr): MonoObject { const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type); // returns JS typed array like Int8Array, to be wraped with JSObject proxy - return _js_to_mono_obj(true, res); + return _js_to_mono_obj_unsafe(true, res); } export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr): MonoObject | MonoString { @@ -160,7 +160,7 @@ export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_arra const res = typedarray_copy_from(js_obj, pinned_array, begin, end, bytes_per_element); // returns num_of_bytes boxed - return _js_to_mono_obj(false, res); + return _js_to_mono_obj_unsafe(false, res); } export function has_backing_array_buffer(js_obj: TypedArray): boolean { diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index b86c03cca87b12..8a9d16bf2d89c8 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -8,12 +8,12 @@ import { MonoType, MonoTypeNull } from "./types"; import { runtimeHelpers } from "./imports"; -import { conv_string_rooted } from "./strings"; +import { conv_string_root } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; import { mono_method_get_call_signature, call_method, wrap_error } from "./method-calls"; -import { _js_to_mono_obj } from "./js-to-cs"; +import { _js_to_mono_obj_unsafe } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; import { getU32, getI32, getF32, getF64 } from "./memory"; import { Int32Ptr, VoidPtr } from "./types/emscripten"; @@ -53,7 +53,7 @@ function _unbox_mono_obj_root_with_known_nonprimitive_type_impl(root: WasmRoot; declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean; declare function conv_string(mono_obj: MonoString): string | null; -declare function conv_string_rooted(root: WasmRoot): string | null; +declare function conv_string_root(root: WasmRoot): string | null; declare function js_string_to_mono_string(string: string): MonoString; declare function js_to_mono_obj(js_obj: any): MonoObject; @@ -328,7 +328,8 @@ declare const BINDING: { js_to_mono_obj: typeof js_to_mono_obj; mono_array_to_js_array: typeof mono_array_to_js_array; conv_string: typeof conv_string; - conv_string_rooted: typeof conv_string_rooted; + conv_string_rooted: typeof conv_string_root; + conv_string_root: typeof conv_string_root; bind_static_method: typeof mono_bind_static_method; call_assembly_entry_point: typeof mono_call_assembly_entry_point; unbox_mono_obj: typeof unbox_mono_obj; diff --git a/src/mono/wasm/runtime/event-listener.ts b/src/mono/wasm/runtime/event-listener.ts index d38d896b0601f9..ad46e8e704fc3f 100644 --- a/src/mono/wasm/runtime/event-listener.ts +++ b/src/mono/wasm/runtime/event-listener.ts @@ -7,14 +7,14 @@ import { JSHandle, GCHandle, MonoString, MonoStringNull } from "./types"; import { _wrap_delegate_gc_handle_as_function } from "./cs-to-js"; import { mono_wasm_get_jsobj_from_js_handle, _js_owned_object_finalized, _lookup_js_owned_object, _use_finalization_registry } from "./gc-handles"; import { wrap_error } from "./method-calls"; -import { conv_string_rooted } from "./strings"; +import { conv_string_root } from "./strings"; const listener_registration_count_symbol = Symbol.for("wasm listener_registration_count"); export function mono_wasm_add_event_listener(js_handle: JSHandle, name: MonoString, listener_gc_handle: GCHandle, optionsHandle: JSHandle): MonoString { const nameRoot = mono_wasm_new_root(name); try { - const sName = conv_string_rooted(nameRoot); + const sName = conv_string_root(nameRoot); const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); if (!obj) @@ -60,7 +60,7 @@ export function mono_wasm_remove_event_listener(js_handle: JSHandle, name: MonoS // Removing a nonexistent listener should not be treated as an error if (!listener) return MonoStringNull; - const sName = conv_string_rooted(nameRoot); + const sName = conv_string_root(nameRoot); obj.removeEventListener(sName, listener, !!capture); // We do not manually remove the listener from the delegate registry here, diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index f52f2d8d4a2f61..a34f65962f2a6d 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -35,7 +35,7 @@ import { } from "./startup"; import { mono_set_timeout, schedule_background_exec } from "./scheduling"; import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu"; -import { conv_string, conv_string_rooted, js_string_to_mono_string, mono_intern_string } from "./strings"; +import { conv_string, conv_string_root, js_string_to_mono_string, mono_intern_string } from "./strings"; import { js_to_mono_obj, js_typed_array_to_array, mono_wasm_typed_array_to_array } from "./js-to-cs"; import { mono_array_to_js_array, mono_wasm_create_cs_owned_object, unbox_mono_obj @@ -122,7 +122,9 @@ const BINDING = { js_to_mono_obj, mono_array_to_js_array, conv_string, - conv_string_rooted, + // Deprecated name + conv_string_rooted: conv_string_root, + conv_string_root, bind_static_method: mono_bind_static_method, call_assembly_entry_point: mono_call_assembly_entry_point, unbox_mono_obj, diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 48e51cfd078517..b2018ab1634ace 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -12,7 +12,7 @@ import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { mono_wasm_new_root, mono_wasm_release_roots, WasmRoot } from "./roots"; import { wrap_error } from "./method-calls"; -import { js_string_to_mono_string_rooted, js_string_to_mono_string_interned_rooted } from "./strings"; +import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "./strings"; import { isThenable } from "./cancelable-promise"; import { has_backing_array_buffer } from "./buffers"; import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, wasm_type_symbol, MonoClass } from "./types"; @@ -20,16 +20,20 @@ import { setI32, setU32, setF64 } from "./memory"; import { Int32Ptr, TypedArray } from "./types/emscripten"; // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function _js_to_mono_uri(should_add_in_flight: boolean, js_obj: any): MonoObject { +export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { switch (true) { case js_obj === null: case typeof js_obj === "undefined": - return MonoObjectNull; + result.clear(); + return; case typeof js_obj === "symbol": case typeof js_obj === "string": - return corebindings._create_uri(js_obj); + // FIXME + result.value = corebindings._create_uri(js_obj); + return; default: - return _extract_mono_obj(should_add_in_flight, js_obj); + _extract_mono_obj_root(should_add_in_flight, js_obj, result); + return; } } @@ -38,7 +42,19 @@ export function _js_to_mono_uri(should_add_in_flight: boolean, js_obj: any): Mon export function js_to_mono_obj(js_obj: any): MonoObject { const temp = mono_wasm_new_root(); try { - _js_to_mono_obj_rooted(false, js_obj, temp); + _js_to_mono_obj_root(false, js_obj, temp); + return temp.value; + } finally { + temp.release(); + } +} + +// Deprecated +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function _js_to_mono_obj_unsafe(should_add_in_flight: boolean, js_obj: any): MonoObject { + const temp = mono_wasm_new_root(); + try { + _js_to_mono_obj_root(should_add_in_flight, js_obj, temp); return temp.value; } finally { temp.release(); @@ -46,7 +62,7 @@ export function js_to_mono_obj(js_obj: any): MonoObject { } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function _js_to_mono_obj_rooted(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { +export function _js_to_mono_obj_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { switch (true) { case js_obj === null: case typeof js_obj === "undefined": @@ -72,10 +88,10 @@ export function _js_to_mono_obj_rooted(should_add_in_flight: boolean, js_obj: an return; } case typeof js_obj === "string": - js_string_to_mono_string_rooted(js_obj, result); + js_string_to_mono_string_root(js_obj, result); return; case typeof js_obj === "symbol": - js_string_to_mono_string_interned_rooted(js_obj, result); + js_string_to_mono_string_interned_root(js_obj, result); return; case typeof js_obj === "boolean": // FIXME @@ -94,12 +110,12 @@ export function _js_to_mono_obj_rooted(should_add_in_flight: boolean, js_obj: an result.value = corebindings._create_date_time(js_obj.getTime()); return; default: - _extract_mono_obj_rooted(should_add_in_flight, js_obj, result); + _extract_mono_obj_root(should_add_in_flight, js_obj, result); return; } } -function _extract_mono_obj_rooted(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { +function _extract_mono_obj_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot): void { result.clear(); if (js_obj === null || typeof js_obj === "undefined") @@ -193,8 +209,7 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul if (asString) obj = obj.toString(); - // TODO: pass elemRoot into new API that copies - elemRoot.value = _js_to_mono_obj(should_add_in_flight, obj); + _js_to_mono_obj_root(should_add_in_flight, obj, elemRoot); cwraps.mono_wasm_obj_array_set_ref(arrayAddress, i, elemAddress); } diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index c9c94d2df5fb26..3ed5b0b1a44193 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -4,8 +4,8 @@ import { WasmRoot, WasmRootBuffer, mono_wasm_new_root } from "./roots"; import { MonoClass, MonoMethod, MonoObject, coerceNull, VoidPtrNull, MonoType, MarshalType } from "./types"; import { BINDING, Module, runtimeHelpers } from "./imports"; -import { js_to_mono_enum, _js_to_mono_obj_rooted, _js_to_mono_uri } from "./js-to-cs"; -import { js_string_to_mono_string_rooted, js_string_to_mono_string_interned_rooted } from "./strings"; +import { js_to_mono_enum, _js_to_mono_obj_root, _js_to_mono_uri_root } from "./js-to-cs"; +import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "./strings"; import { _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js"; import { _create_temp_frame, @@ -122,13 +122,13 @@ export function _create_rebindable_named_function(name: string, argumentNames: s export function _create_primitive_converters(): void { const result = primitiveConverters; result.set("m", { steps: [{}], size: 0 }); - result.set("s", { steps: [{ convert_rooted: js_string_to_mono_string_rooted.bind(BINDING) }], size: 0, needs_root: true }); - result.set("S", { steps: [{ convert_rooted: js_string_to_mono_string_interned_rooted.bind(BINDING) }], size: 0, needs_root: true }); + result.set("s", { steps: [{ convert_root: js_string_to_mono_string_root.bind(BINDING) }], size: 0, needs_root: true }); + result.set("S", { steps: [{ convert_root: js_string_to_mono_string_interned_root.bind(BINDING) }], size: 0, needs_root: true }); // note we also bind first argument to false for both _js_to_mono_obj and _js_to_mono_uri, // because we will root the reference, so we don't need in-flight reference // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end - result.set("o", { steps: [{ convert_rooted: _js_to_mono_obj_rooted.bind(BINDING, false) }], size: 0, needs_root: true }); - result.set("u", { steps: [{ convert: _js_to_mono_uri.bind(BINDING, false) }], size: 0, needs_root: true }); + result.set("o", { steps: [{ convert_root: _js_to_mono_obj_root.bind(BINDING, false) }], size: 0, needs_root: true }); + result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(BINDING, false) }], size: 0, needs_root: true }); // result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); result.set("j", { steps: [{ convert: js_to_mono_enum.bind(BINDING), indirect: "i32" }], size: 8 }); @@ -241,8 +241,10 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args const argKey = "arg" + i; argumentNames.push(argKey); - if (step.convert_rooted) { - throw new Error("Not implemented: Converter.convert_rooted"); + if (step.convert_root) { + // FIXME: Optimize this!!! + + throw new Error("Not implemented: Converter.convert_root"); } else if (step.convert) { closure[closureKey] = step.convert; body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`); @@ -258,7 +260,7 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args // HACK: needs_unbox indicates that we were passed a pointer to a managed object, and either // it was already rooted by our caller or (needs_root = true) by us. Now we can unbox it and // pass the raw address of its boxed value into the callee. - // FIXME: I don't think this is GC safe + // FIXME: This isn't fully GC or thread safe if (step.needs_unbox) body.push(`${valueKey} = mono_wasm_unbox_rooted (${valueKey});`); @@ -583,7 +585,8 @@ type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "i64" export type Converter = { steps: { convert?: boolean | Function; - convert_rooted?: Function; + // Accepts a result param at the end of type WasmRoot<...> + convert_root?: Function; needs_root?: boolean; needs_unbox?: boolean; indirect?: ConverterStepIndirects; diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index a35e2cab16fc06..0f8de68bb8752b 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -10,14 +10,14 @@ import { import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports"; import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js"; import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; -import { js_array_to_mono_array, _box_js_bool, _js_to_mono_obj } from "./js-to-cs"; +import { js_array_to_mono_array, _box_js_bool, _js_to_mono_obj_unsafe } from "./js-to-cs"; import { mono_bind_method, Converter, _compile_converter_for_marshal_string, _decide_if_result_is_marshaled, find_method, BoundMethodToken } from "./method-binding"; -import { conv_string, conv_string_rooted, js_string_to_mono_string, js_string_to_mono_string_rooted } from "./strings"; +import { conv_string, conv_string_root, js_string_to_mono_string, js_string_to_mono_string_root } from "./strings"; import cwraps from "./cwraps"; import { bindings_lazy_init } from "./startup"; import { _create_temp_frame, _release_temp_frame } from "./memory"; @@ -118,7 +118,7 @@ function _convert_exception_for_method_call(result: WasmRoot, except return null; // FIXME: rooted - const msg = conv_string_rooted(result); + const msg = conv_string_root(result); const err = new Error(msg!); //the convention is that invoke_method ToString () any outgoing exception // console.warn (`error ${msg} at location ${err.stack}); return err; @@ -300,7 +300,7 @@ export function mono_call_assembly_entry_point(assembly: string, args?: any[], s export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: MonoString, args: MonoArray, is_exception: Int32Ptr): any { const argsRoot = mono_wasm_new_root(args), nameRoot = mono_wasm_new_root(method_name); try { - const js_name = conv_string_rooted(nameRoot); + const js_name = conv_string_root(nameRoot); if (!js_name || (typeof (js_name) !== "string")) { return wrap_error(is_exception, "ERR12: Invalid method name object '" + nameRoot.value + "'"); } @@ -317,7 +317,7 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: if (typeof m === "undefined") throw new Error("Method: '" + js_name + "' not found for: '" + Object.prototype.toString.call(obj) + "'"); const res = m.apply(obj, js_args); - return _js_to_mono_obj(true, res); + return _js_to_mono_obj_unsafe(true, res); } catch (ex) { return wrap_error(is_exception, ex); } @@ -330,7 +330,7 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: export function mono_wasm_get_object_property(js_handle: JSHandle, property_name: MonoString, is_exception: Int32Ptr): any { const nameRoot = mono_wasm_new_root(property_name); try { - const js_name = conv_string_rooted(nameRoot); + const js_name = conv_string_root(nameRoot); if (!js_name) { return wrap_error(is_exception, "Invalid property name object '" + nameRoot.value + "'"); } @@ -343,7 +343,7 @@ export function mono_wasm_get_object_property(js_handle: JSHandle, property_name try { const m = obj[js_name]; - return _js_to_mono_obj(true, m); + return _js_to_mono_obj_unsafe(true, m); } catch (ex) { return wrap_error(is_exception, ex); } @@ -356,7 +356,7 @@ export function mono_wasm_set_object_property(js_handle: JSHandle, property_name const valueRoot = mono_wasm_new_root(value), nameRoot = mono_wasm_new_root(property_name); try { - const property = conv_string_rooted(nameRoot); + const property = conv_string_root(nameRoot); if (!property) { return wrap_error(is_exception, "Invalid property name object '" + property_name + "'"); } @@ -406,7 +406,7 @@ export function mono_wasm_get_by_index(js_handle: JSHandle, property_index: numb try { const m = obj[property_index]; - return _js_to_mono_obj(true, m); + return _js_to_mono_obj_unsafe(true, m); } catch (ex) { return wrap_error(is_exception, ex); } @@ -436,7 +436,7 @@ export function mono_wasm_set_by_index(js_handle: JSHandle, property_index: numb export function mono_wasm_get_global_object(global_name: MonoString, is_exception: Int32Ptr): MonoObject { const nameRoot = mono_wasm_new_root(global_name); try { - const js_name = conv_string_rooted(nameRoot); + const js_name = conv_string_root(nameRoot); let globalObj; @@ -452,7 +452,7 @@ export function mono_wasm_get_global_object(global_name: MonoString, is_exceptio return wrap_error(is_exception, "Global object '" + js_name + "' not found."); } - return _js_to_mono_obj(true, globalObj); + return _js_to_mono_obj_unsafe(true, globalObj); } finally { nameRoot.release(); } @@ -537,7 +537,7 @@ export function mono_wasm_invoke_js_blazor(exceptionMessage: Int32Ptr, callInfo: } catch (ex: any) { const exceptionJsString = ex.message + "\n" + ex.stack; const exceptionRoot = mono_wasm_new_root(); - js_string_to_mono_string_rooted(exceptionJsString, exceptionRoot); + js_string_to_mono_string_root(exceptionJsString, exceptionRoot); exceptionRoot.copy_to_address(exceptionMessage); exceptionRoot.release(); return 0; @@ -586,7 +586,7 @@ export function mono_wasm_compile_function(code: MonoString, is_exception: Int32 if (!res || typeof res !== "function") return wrap_error(is_exception, "Code must return an instance of a JavaScript function. Please use `return` statement to return a function."); Module.setValue(is_exception, 0, "i32"); - return _js_to_mono_obj(true, res); + return _js_to_mono_obj_unsafe(true, res); } catch (ex) { return wrap_error(is_exception, ex); } diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index ec247345492d1a..35b82206cbd414 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -29,12 +29,12 @@ export class StringDecoder { return null; this.mono_wasm_string_root.value = mono_string; - const result = this.copy_rooted(this.mono_wasm_string_root); + const result = this.copy_root(this.mono_wasm_string_root); this.mono_wasm_string_root.value = MonoStringNull; return result; } - copy_rooted(root: WasmRoot): string | null { + copy_root(root: WasmRoot): string | null { this.init_fields(); if (root.value === MonoStringNull) return null; @@ -104,8 +104,8 @@ export function conv_string(mono_obj: MonoString): string | null { return string_decoder.copy(mono_obj); } -export function conv_string_rooted(root: WasmRoot): string | null { - return string_decoder.copy_rooted(root); +export function conv_string_root(root: WasmRoot): string | null { + return string_decoder.copy_root(root); } // Ensures the string is already interned on both the managed and JavaScript sides, @@ -161,7 +161,7 @@ function _store_string_in_intern_table(string: string, root: WasmRoot): void { +export function js_string_to_mono_string_interned_root(string: string | symbol, result: WasmRoot): void { const text = (typeof (string) === "symbol") ? (string.description || Symbol.keyFor(string) || "") : string; @@ -183,22 +183,22 @@ export function js_string_to_mono_string_interned_rooted(string: string | symbol return; } - js_string_to_mono_string_new_rooted(text, result); + js_string_to_mono_string_new_root(text, result); _store_string_in_intern_table(text, result, true); } -export function js_string_to_mono_string_rooted(string: string, result: WasmRoot): void { +export function js_string_to_mono_string_root(string: string, result: WasmRoot): void { result.clear(); if (string === null) return; else if (typeof (string) === "symbol") - js_string_to_mono_string_interned_rooted(string, result); + js_string_to_mono_string_interned_root(string, result); else if (typeof (string) !== "string") throw new Error("Expected string argument, got " + typeof (string)); else if (string.length === 0) // Always use an interned pointer for empty strings - js_string_to_mono_string_interned_rooted(string, result); + js_string_to_mono_string_interned_root(string, result); else { // Looking up large strings in the intern table will require the JS runtime to // potentially hash them and then do full byte-by-byte comparisons, which is @@ -212,11 +212,11 @@ export function js_string_to_mono_string_rooted(string: string, result: WasmRoot } } - js_string_to_mono_string_new_rooted(string, result); + js_string_to_mono_string_new_root(string, result); } } -export function js_string_to_mono_string_new_rooted(string: string, result: WasmRoot): void { +export function js_string_to_mono_string_new_root(string: string, result: WasmRoot): void { const buffer = Module._malloc((string.length + 1) * 2); const buffer16 = (buffer >>> 1) | 0; for (let i = 0; i < string.length; i++) @@ -230,7 +230,7 @@ export function js_string_to_mono_string_new_rooted(string: string, result: Wasm export function js_string_to_mono_string_interned(string: string | symbol): MonoString { const temp = mono_wasm_new_root(); try { - js_string_to_mono_string_interned_rooted(string, temp); + js_string_to_mono_string_interned_root(string, temp); return temp.value; } finally { temp.release(); @@ -241,7 +241,7 @@ export function js_string_to_mono_string_interned(string: string | symbol): Mono export function js_string_to_mono_string(string: string): MonoString { const temp = mono_wasm_new_root(); try { - js_string_to_mono_string_rooted(string, temp); + js_string_to_mono_string_root(string, temp); return temp.value; } finally { temp.release(); @@ -252,7 +252,7 @@ export function js_string_to_mono_string(string: string): MonoString { export function js_string_to_mono_string_new(string: string): MonoString { const temp = mono_wasm_new_root(); try { - js_string_to_mono_string_new_rooted(string, temp); + js_string_to_mono_string_new_root(string, temp); return temp.value; } finally { temp.release(); diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 352bcad127c450..1125a16f73d109 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -9,7 +9,7 @@ import { _mono_array_root_to_js_array, _wrap_delegate_root_as_function } from ". import { mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle } from "./gc-handles"; import { _wrap_js_thenable_as_task } from "./js-to-cs"; import { wrap_error } from "./method-calls"; -import { conv_string_rooted } from "./strings"; +import { conv_string_root } from "./strings"; import { JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString } from "./types"; import { Module } from "./imports"; import { Int32Ptr } from "./types/emscripten"; @@ -34,7 +34,7 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr const sub_root = mono_wasm_new_root(subProtocols); const on_close_root = mono_wasm_new_root(on_close); try { - const js_uri = conv_string_rooted(uri_root); + const js_uri = conv_string_root(uri_root); if (!js_uri) { return wrap_error(is_exception, "ERR12: Invalid uri '" + uri_root.value + "'"); } @@ -193,7 +193,7 @@ export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: return MonoObjectNull;// no promise } - const js_reason = conv_string_rooted(reason_root); + const js_reason = conv_string_root(reason_root); if (wait_for_close_received) { const { promise, promise_control } = _create_cancelable_promise(); From 2be1022c8665695efa4def7f5bab2548227ce344 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 2 Mar 2022 18:22:48 -0800 Subject: [PATCH 036/128] Checkpoint --- src/mono/wasm/runtime/method-binding.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 3ed5b0b1a44193..b53df165c9e02c 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -222,7 +222,8 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args setU32, setF32, setF64, - setI64 + setI64, + scratchValueRoot: converter.scratchValueRoot }; let indirectLocalOffset = 0; @@ -243,8 +244,13 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args if (step.convert_root) { // FIXME: Optimize this!!! + if (!converter.scratchValueRoot) + closure.scratchValueRoot = converter.scratchValueRoot = mono_wasm_new_root(); - throw new Error("Not implemented: Converter.convert_root"); + closure[closureKey] = step.convert_root; + body.push(`${closureKey}(${argKey}, scratchValueRoot);`); + // FIXME: Not GC safe + body.push(`let ${valueKey} = scratchValueRoot.value;`); } else if (step.convert) { closure[closureKey] = step.convert; body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`); @@ -584,8 +590,9 @@ type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "i64" export type Converter = { steps: { + // (value: any, method: MonoMethod, arg_index: int) convert?: boolean | Function; - // Accepts a result param at the end of type WasmRoot<...> + // (value: any, result_root: WasmRoot) convert_root?: Function; needs_root?: boolean; needs_unbox?: boolean; @@ -606,6 +613,7 @@ export type Converter = { compiled_function?: Function | null; scratchRootBuffer?: WasmRootBuffer | null; scratchBuffer?: VoidPtr; + scratchValueRoot?: WasmRoot; has_warned_about_signature?: boolean; convert?: Function | null; method?: MonoMethod | null; From 25cc304c6afe4a5a59a168583e14f31cf6da84cb Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 3 Mar 2022 22:44:49 -0800 Subject: [PATCH 037/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 10 +- .../JavaScript/Runtime.JS.Owned.cs | 10 +- .../InteropServices/JavaScript/Runtime.cs | 10 +- src/mono/wasm/runtime/corebindings.c | 12 +- src/mono/wasm/runtime/corebindings.ts | 22 +-- src/mono/wasm/runtime/cs-to-js.ts | 2 +- src/mono/wasm/runtime/js-to-cs.ts | 23 +-- src/mono/wasm/runtime/method-calls.ts | 5 + src/mono/wasm/runtime/roots.ts | 2 +- src/mono/wasm/runtime/web-socket.ts | 160 ++++++++++-------- 10 files changed, 140 insertions(+), 116 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index 051b412b1199d5..ded0008684c708 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -47,15 +47,15 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern string? RemoveEventListener(int jsHandle, string name, int gcHandle, bool capture); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object WebSocketSend(int webSocketJSHandle, IntPtr messagePtr, int offset, int length, int messageType, bool endOfMessage, out int promiseJSHandle, out int exceptionalResult); + internal static extern void WebSocketSend(int webSocketJSHandle, IntPtr messagePtr, int offset, int length, int messageType, bool endOfMessage, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object WebSocketReceive(int webSocketJSHandle, IntPtr bufferPtr, int offset, int length, IntPtr responsePtr, out int promiseJSHandle, out int exceptionalResult); + internal static extern void WebSocketReceive(int webSocketJSHandle, IntPtr bufferPtr, int offset, int length, IntPtr responsePtr, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object WebSocketOpen(string uri, object[]? subProtocols, Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult); + internal static extern void WebSocketOpen(string uri, object[]? subProtocols, Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern string WebSocketAbort(int webSocketJSHandle, out int exceptionalResult); + internal static extern void WebSocketAbort(int webSocketJSHandle, out int exceptionalResult, out string result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object WebSocketClose(int webSocketJSHandle, int code, string? reason, bool waitForCloseReceived, out int promiseJSHandle, out int exceptionalResult); + internal static extern void WebSocketClose(int webSocketJSHandle, int code, string? reason, bool waitForCloseReceived, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern string CancelPromise(int promiseJSHandle, out int exceptionalResult); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index f0a4245bff578f..35ce80b33d005b 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -77,20 +77,20 @@ public static void SetTaskSourceFailure(int tcsGCHandle, string reason) tcs.SetException(new JSException(reason)); } - public static object GetTaskSourceTask(int tcsGCHandle) + public static void GetTaskSourceTaskRef(int tcsGCHandle, out object result) { GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; // this is JS owned Normal handle. We always have a Target TaskCompletionSource tcs = (TaskCompletionSource)handle.Target!; - return tcs.Task; + result = tcs.Task; } - public static object TaskFromResult(object? obj) + public static void TaskFromResultRef(object? obj, out object result) { - return Task.FromResult(obj); + result = Task.FromResult(obj); } - public static void SetupJSContinuation(Task task, JSObject continuationObj) + public static void SetupJSContinuationRef(in Task task, JSObject continuationObj) { if (task.IsCompleted) Complete(); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index bb0ebd1198cb90..69559795f4e473 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -314,15 +314,17 @@ public static double GetDateValueRef(ref object dtv!!) return new DateTimeOffset(dt).ToUnixTimeMilliseconds(); } - public static DateTime CreateDateTime(double ticks) + // HACK: We need to implicitly box by using an 'object' out-param. + // Note that the return value would have been boxed on the C#->JS transition anyway. + public static void CreateDateTimeRef(double ticks, out object result) { DateTimeOffset unixTime = DateTimeOffset.FromUnixTimeMilliseconds((long)ticks); - return unixTime.DateTime; + result = unixTime.DateTime; } - public static Uri CreateUri(string uri) + public static void CreateUriRef(string uri, out Uri result) { - return new Uri(uri); + result = new Uri(uri); } public static void CancelPromise(int promiseJSHandle) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index fbfb5c42017986..b7e4eda4c553eb 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -25,11 +25,11 @@ extern MonoObject* mono_wasm_typed_array_copy_from (int js_handle, int ptr, int extern MonoString* mono_wasm_add_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int optionsObjHandle); extern MonoString* mono_wasm_remove_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int capture); extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exception); -extern MonoObject* mono_wasm_web_socket_open (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception); -extern MonoObject* mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception); -extern MonoObject* mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception); -extern MonoObject* mono_wasm_web_socket_close (int webSocket_js_handle, int code, MonoString * reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception); -extern MonoString* mono_wasm_web_socket_abort (int webSocket_js_handle, int *is_exception); +extern void mono_wasm_web_socket_open (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_close (int webSocket_js_handle, int code, MonoString * reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_abort (int webSocket_js_handle, int *is_exception, MonoString **result); extern MonoObject* mono_wasm_compile_function (MonoString *str, int *is_exception); void core_initialize_internals () @@ -118,7 +118,7 @@ mono_wasm_unbox_enum (MonoObject *obj) { if (!obj) return 0; - + MonoType *type = mono_class_get_type (mono_object_get_class(obj)); void *ptr = mono_object_unbox (obj); diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index 42a27e0054bba7..fab90cc782a91b 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -18,14 +18,14 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_create_tcs", "CreateTaskSource", ""], ["_set_tcs_result", "SetTaskSourceResult", "io"], ["_set_tcs_failure", "SetTaskSourceFailure", "is"], - ["_get_tcs_task", "GetTaskSourceTask", "i!"], - ["_task_from_result", "TaskFromResult", "o!"], - ["_setup_js_cont", "SetupJSContinuation", "mo"], + ["_get_tcs_task_ref", "GetTaskSourceTaskRef", "im"], + ["_task_from_result_ref", "TaskFromResultRef", "om"], + ["_setup_js_cont_ref", "SetupJSContinuationRef", "mo"], ["_object_to_string_ref", "ObjectToStringRef", "m"], ["_get_date_value_ref", "GetDateValueRef", "m"], - ["_create_date_time", "CreateDateTime", "d!"], - ["_create_uri", "CreateUri", "s!"], + ["_create_date_time_ref", "CreateDateTimeRef", "d!"], + ["_create_uri_ref", "CreateUriRef", "s!"], ["_is_simple_array_ref", "IsSimpleArrayRef", "m"], ]; @@ -44,14 +44,16 @@ export interface t_CSwraps { // FIXME: We currently rely on marshaling to convert result types _set_tcs_result(gcHandle: GCHandle, result: any): void _set_tcs_failure(gcHandle: GCHandle, result: string): void - _get_tcs_task(gcHandle: GCHandle): MonoObject; - _task_from_result(result: MonoObject): MonoObject - _setup_js_cont(task: MonoObject, continuation: PromiseControl): MonoObject + _get_tcs_task_ref(gcHandle: GCHandle, result: MonoObjectRef): void; + // FIXME: We rely on marshaling for the value to be converted + _task_from_result_ref(value: MonoObject, result: MonoObjectRef): void; + // FIXME: PromiseControl is a JS object so we can't pass an address directly + _setup_js_cont_ref(task: MonoObjectRef, continuation: PromiseControl): void; _object_to_string_ref(obj: MonoObjectRef): string; _get_date_value_ref(obj: MonoObjectRef): number; - _create_date_time(ticks: number): MonoObject; - _create_uri(uri: string): MonoObject; + _create_date_time_ref(ticks: number, result: MonoObjectRef): void; + _create_uri_ref(uri: string, result: MonoObjectRef): void; _is_simple_array_ref(obj: MonoObjectRef): boolean; } diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 8a9d16bf2d89c8..5ad6752f948bfd 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -304,7 +304,7 @@ function _unbox_task_root_as_promise(root: WasmRoot) { result = promise; // register C# side of the continuation - corebindings._setup_js_cont(root.value, promise_control); + corebindings._setup_js_cont_ref(root.address, promise_control); // register for GC of the Task after the JS side is done with the promise if (_use_finalization_registry) { diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index b2018ab1634ace..e6bd452f74e6f8 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -28,8 +28,7 @@ export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, return; case typeof js_obj === "symbol": case typeof js_obj === "string": - // FIXME - result.value = corebindings._create_uri(js_obj); + corebindings._create_uri_ref(js_obj, result.address); return; default: _extract_mono_obj_root(should_add_in_flight, js_obj, result); @@ -98,16 +97,12 @@ export function _js_to_mono_obj_root(should_add_in_flight: boolean, js_obj: any, result.value = _box_js_bool(js_obj); return; case isThenable(js_obj) === true: { - // FIXME: ref/rooted - const { task_ptr } = _wrap_js_thenable_as_task(js_obj); - // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC - result.value = task_ptr; + _wrap_js_thenable_as_task_root(js_obj, result); return; } case js_obj.constructor.name === "Date": // getTime() is always UTC - // FIXME: ref/rooted - result.value = corebindings._create_date_time(js_obj.getTime()); + corebindings._create_date_time_ref(js_obj.getTime(), result.address); return; default: _extract_mono_obj_root(should_add_in_flight, js_obj, result); @@ -219,14 +214,13 @@ export function js_array_to_mono_array(js_array: any[], asString: boolean, shoul } } -export function _wrap_js_thenable_as_task(thenable: Promise): { - task_ptr: MonoObject, +export function _wrap_js_thenable_as_task_root(thenable: Promise, resultRoot: WasmRoot): { then_js_handle: JSHandle, - } { - - if (!thenable) + if (!thenable) { + resultRoot.clear(); return null; + } // hold strong JS reference to thenable while in flight // ideally, this should be hold alive by lifespan of the resulting C# Task, but this is good cheap aproximation @@ -261,9 +255,10 @@ export function _wrap_js_thenable_as_task(thenable: Promise): { _js_owned_object_registry.register(thenable, tcs_gc_handle); } + corebindings._get_tcs_task_ref(tcs_gc_handle, resultRoot.address); + // returns raw pointer to tcs.Task return { - task_ptr: corebindings._get_tcs_task(tcs_gc_handle), then_js_handle: thenable_js_handle, }; } diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 0f8de68bb8752b..4582f4e7af5a93 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -479,6 +479,11 @@ export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { return js_string_to_mono_string(res)!; } +export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: WasmRoot): void { + // FIXME + result.value = wrap_error(is_exception, ex); +} + export function mono_method_get_call_signature(method: MonoMethod, mono_obj?: MonoObject): string/*ArgsMarshalString*/ { const instanceRoot = mono_wasm_new_root(mono_obj); try { diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index 1938e14727b036..464b30e18c0245 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -58,7 +58,7 @@ export function mono_wasm_new_root_buffer_from_pointer(offset: VoidPtr, capacity * Allocates a WasmRoot pointing to a root provided and controlled by external code. Typicaly on managed stack. * Releasing this root will not de-allocate the root space. You still need to call .release(). */ -export function mono_wasm_new_external_root(address: VoidPtr): WasmRoot { +export function mono_wasm_new_external_root(address: VoidPtr | MonoObjectRef): WasmRoot { let result: WasmExternalRoot; if (!address) diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 1125a16f73d109..27d91badad8a34 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -1,16 +1,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_root, WasmRoot } from "./roots"; +import { mono_wasm_new_root, WasmRoot, mono_wasm_new_external_root } from "./roots"; import { prevent_timer_throttling } from "./scheduling"; import { Queue } from "./queue"; import { PromiseControl, _create_cancelable_promise } from "./cancelable-promise"; import { _mono_array_root_to_js_array, _wrap_delegate_root_as_function } from "./cs-to-js"; import { mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle } from "./gc-handles"; -import { _wrap_js_thenable_as_task } from "./js-to-cs"; -import { wrap_error } from "./method-calls"; +import { _wrap_js_thenable_as_task_root } from "./js-to-cs"; +import { wrap_error, wrap_error_root } from "./method-calls"; import { conv_string_root } from "./strings"; -import { JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString } from "./types"; +import { JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString, MonoObjectRef } from "./types"; import { Module } from "./imports"; import { Int32Ptr } from "./types/emscripten"; @@ -29,14 +29,16 @@ let _text_encoder_utf8: TextEncoder | undefined = undefined; const ws_send_buffer_blocking_threshold = 65536; const emptyBuffer = new Uint8Array(); -export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArray, on_close: MonoObject, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr): MonoObject { +export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArray, on_close: MonoObject, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); const uri_root = mono_wasm_new_root(uri); const sub_root = mono_wasm_new_root(subProtocols); const on_close_root = mono_wasm_new_root(on_close); try { const js_uri = conv_string_root(uri_root); if (!js_uri) { - return wrap_error(is_exception, "ERR12: Invalid uri '" + uri_root.value + "'"); + wrap_error_root(is_exception, "ERR12: Invalid uri '" + uri_root.value + "'", result_root); + return; } const js_subs = _mono_array_root_to_js_array(sub_root); @@ -91,23 +93,23 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr const ws_js_handle = mono_wasm_get_js_handle(ws); Module.setValue(web_socket_js_handle, ws_js_handle, "i32"); - const { task_ptr, then_js_handle } = _wrap_js_thenable_as_task(promise); + const { then_js_handle } = _wrap_js_thenable_as_task_root(promise, result_root); // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC Module.setValue(thenable_js_handle, then_js_handle, "i32"); - - return task_ptr; } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, result_root); } finally { + result_root.release(); uri_root.release(); sub_root.release(); on_close_root.release(); } } -export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr): MonoObject { +export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); const buffer_root = mono_wasm_new_root(buffer_ptr); try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle); @@ -121,19 +123,22 @@ export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ const whole_buffer = _mono_wasm_web_socket_send_buffering(ws, buffer_root, offset, length, message_type, end_of_message); if (!end_of_message || !whole_buffer) { - return MonoObjectNull; // we are done buffering synchronously, no promise + result_root.clear(); // we are done buffering synchronously, no promise + return; } - return _mono_wasm_web_socket_send_and_wait(ws, whole_buffer, thenable_js_handle); + _mono_wasm_web_socket_send_and_wait(ws, whole_buffer, thenable_js_handle, result_address); } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, result_root); } finally { + result_root.release(); buffer_root.release(); } } -export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, response_ptr: MonoObject, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr): MonoObject { +export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, response_ptr: MonoObject, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); const buffer_root = mono_wasm_new_root(buffer_ptr); const response_root = mono_wasm_new_root(response_ptr); const release_buffer = () => { @@ -162,7 +167,8 @@ export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buff release_buffer(); Module.setValue(thenable_js_handle, 0, "i32"); - return MonoObjectNull; + result_root.clear(); + return; } const { promise, promise_control } = _create_cancelable_promise(release_buffer, release_buffer); const receive_promise_control = promise_control as ReceivePromiseControl; @@ -172,17 +178,20 @@ export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buff receive_promise_control.response_root = response_root; receive_promise_queue.enqueue(receive_promise_control); - const { task_ptr, then_js_handle } = _wrap_js_thenable_as_task(promise); + const { then_js_handle } = _wrap_js_thenable_as_task_root(promise, result_root); // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC Module.setValue(thenable_js_handle, then_js_handle, "i32"); - return task_ptr; } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, result_root); + } + finally { + result_root.release(); } } -export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: number, reason: MonoString, wait_for_close_received: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr): MonoObject { +export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: number, reason: MonoString, wait_for_close_received: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); const reason_root = mono_wasm_new_root(reason); try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle); @@ -190,7 +199,8 @@ export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: throw new Error("ERR19: Invalid JS object handle " + webSocket_js_handle); if (ws.readyState == WebSocket.CLOSED) { - return MonoObjectNull;// no promise + result_root.clear(); + return; } const js_reason = conv_string_root(reason_root); @@ -205,11 +215,11 @@ export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: ws.close(code); } - const { task_ptr, then_js_handle } = _wrap_js_thenable_as_task(promise); + const { then_js_handle } = _wrap_js_thenable_as_task_root(promise, result_root); // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC Module.setValue(thenable_js_handle, then_js_handle, "i32"); - return task_ptr; + return; } else { if (!mono_wasm_web_socket_close_warning) { @@ -222,18 +232,21 @@ export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: ws.close(code); } Module.setValue(thenable_js_handle, 0, "i32"); - return MonoObjectNull;// no promise + result_root.clear(); + return; } } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, result_root); } finally { + result_root.release(); reason_root.release(); } } -export function mono_wasm_web_socket_abort(webSocket_js_handle: JSHandle, is_exception: Int32Ptr): MonoObject { +export function mono_wasm_web_socket_abort(webSocket_js_handle: JSHandle, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle) as WebSocketExtension; if (!ws) @@ -258,61 +271,68 @@ export function mono_wasm_web_socket_abort(webSocket_js_handle: JSHandle, is_exc // this is different from Managed implementation ws.close(1000, "Connection was aborted."); - return MonoObjectNull; + result_root.clear(); } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, result_root); } -} - -function _mono_wasm_web_socket_send_and_wait(ws: WebSocketExtension, buffer: Uint8Array | string, thenable_js_handle: Int32Ptr): MonoObject { - // send and return promise - ws.send(buffer); - ws[wasm_ws_pending_send_buffer] = null; - - // if the remaining send buffer is small, we don't block so that the throughput doesn't suffer. - // Otherwise we block so that we apply some backpresure to the application sending large data. - // this is different from Managed implementation - if (ws.bufferedAmount < ws_send_buffer_blocking_threshold) { - return MonoObjectNull; // no promise + finally { + result_root.release(); } +} - // block the promise/task until the browser passed the buffer to OS - const { promise, promise_control } = _create_cancelable_promise(); - const pending = ws[wasm_ws_pending_send_promises]; - pending.push(promise_control); +function _mono_wasm_web_socket_send_and_wait(ws: WebSocketExtension, buffer: Uint8Array | string, thenable_js_handle: Int32Ptr, result_address: MonoObjectRef): void { + const result_root = mono_wasm_new_external_root(result_address); + try { + // send and return promise + ws.send(buffer); + ws[wasm_ws_pending_send_buffer] = null; - let nextDelay = 1; - const polling_check = () => { - // was it all sent yet ? - if (ws.bufferedAmount === 0) { - promise_control.resolve(null); - } - else if (ws.readyState != WebSocket.OPEN) { - // only reject if the data were not sent - // bufferedAmount does not reset to zero once the connection closes - promise_control.reject("InvalidState: The WebSocket is not connected."); - } - else if (!promise_control.isDone) { - globalThis.setTimeout(polling_check, nextDelay); - // exponentially longer delays, up to 1000ms - nextDelay = Math.min(nextDelay * 1.5, 1000); + // if the remaining send buffer is small, we don't block so that the throughput doesn't suffer. + // Otherwise we block so that we apply some backpresure to the application sending large data. + // this is different from Managed implementation + if (ws.bufferedAmount < ws_send_buffer_blocking_threshold) { + result_root.clear(); return; } - // remove from pending - const index = pending.indexOf(promise_control); - if (index > -1) { - pending.splice(index, 1); - } - }; - globalThis.setTimeout(polling_check, 0); + // block the promise/task until the browser passed the buffer to OS + const { promise, promise_control } = _create_cancelable_promise(); + const pending = ws[wasm_ws_pending_send_promises]; + pending.push(promise_control); + + let nextDelay = 1; + const polling_check = () => { + // was it all sent yet ? + if (ws.bufferedAmount === 0) { + promise_control.resolve(null); + } + else if (ws.readyState != WebSocket.OPEN) { + // only reject if the data were not sent + // bufferedAmount does not reset to zero once the connection closes + promise_control.reject("InvalidState: The WebSocket is not connected."); + } + else if (!promise_control.isDone) { + globalThis.setTimeout(polling_check, nextDelay); + // exponentially longer delays, up to 1000ms + nextDelay = Math.min(nextDelay * 1.5, 1000); + return; + } + // remove from pending + const index = pending.indexOf(promise_control); + if (index > -1) { + pending.splice(index, 1); + } + }; - const { task_ptr, then_js_handle } = _wrap_js_thenable_as_task(promise); - // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC - Module.setValue(thenable_js_handle, then_js_handle, "i32"); + globalThis.setTimeout(polling_check, 0); - return task_ptr; + const { then_js_handle } = _wrap_js_thenable_as_task_root(promise, result_root); + // task_ptr above is not rooted, we need to return it to mono without any intermediate mono call which could cause GC + Module.setValue(thenable_js_handle, then_js_handle, "i32"); + } finally { + result_root.release(); + } } function _mono_wasm_web_socket_on_message(ws: WebSocketExtension, event: MessageEvent) { From 463a680a1f611ec204a1cf427d3d95e6945e4702 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 3 Mar 2022 22:48:52 -0800 Subject: [PATCH 038/128] Checkpoint (broken) --- .../InteropServices/JavaScript/Runtime.JS.Owned.cs | 6 +++++- .../Runtime/InteropServices/JavaScript/Runtime.cs | 10 +++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index 35ce80b33d005b..25018e7a6eb02f 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -90,8 +90,12 @@ public static void TaskFromResultRef(object? obj, out object result) result = Task.FromResult(obj); } - public static void SetupJSContinuationRef(in Task task, JSObject continuationObj) + public static void SetupJSContinuationRef(in Task _task, JSObject continuationObj) { + // HACK: Attempting to use the in-param will produce CS1628, so we make a temporary copy + // on the stack that can be captured by our local functions below + var task = _task; + if (task.IsCompleted) Complete(); else diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index 69559795f4e473..95dc24cce1792f 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -336,7 +336,7 @@ public static void CancelPromise(int promiseJSHandle) public static Task WebSocketOpen(string uri, object[]? subProtocols, Delegate onClosed, out JSObject webSocket, out int promiseJSHandle) { - var res = Interop.Runtime.WebSocketOpen(uri, subProtocols, onClosed, out int webSocketJSHandle, out promiseJSHandle, out int exception); + Interop.Runtime.WebSocketOpen(uri, subProtocols, onClosed, out int webSocketJSHandle, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); webSocket = new JSObject((IntPtr)webSocketJSHandle); @@ -348,7 +348,7 @@ public static Task WebSocketOpen(string uri, object[]? subProtocols, Del { fixed (byte* messagePtr = buffer.Array) { - var res = Interop.Runtime.WebSocketSend(webSocket.JSHandle, (IntPtr)messagePtr, buffer.Offset, buffer.Count, messageType, endOfMessage, out promiseJSHandle, out int exception); + Interop.Runtime.WebSocketSend(webSocket.JSHandle, (IntPtr)messagePtr, buffer.Offset, buffer.Count, messageType, endOfMessage, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); @@ -366,7 +366,7 @@ public static Task WebSocketOpen(string uri, object[]? subProtocols, Del fixed (int* responsePtr = response) fixed (byte* bufferPtr = buffer.Array) { - var res = Interop.Runtime.WebSocketReceive(webSocket.JSHandle, (IntPtr)bufferPtr, buffer.Offset, buffer.Count, (IntPtr)responsePtr, out promiseJSHandle, out int exception); + Interop.Runtime.WebSocketReceive(webSocket.JSHandle, (IntPtr)bufferPtr, buffer.Offset, buffer.Count, (IntPtr)responsePtr, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); if (res == null) @@ -379,7 +379,7 @@ public static Task WebSocketOpen(string uri, object[]? subProtocols, Del public static Task? WebSocketClose(JSObject webSocket, int code, string? reason, bool waitForCloseReceived, out int promiseJSHandle) { - var res = Interop.Runtime.WebSocketClose(webSocket.JSHandle, code, reason, waitForCloseReceived, out promiseJSHandle, out int exception); + Interop.Runtime.WebSocketClose(webSocket.JSHandle, code, reason, waitForCloseReceived, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); @@ -392,7 +392,7 @@ public static Task WebSocketOpen(string uri, object[]? subProtocols, Del public static void WebSocketAbort(JSObject webSocket) { - var res = Interop.Runtime.WebSocketAbort(webSocket.JSHandle, out int exception); + Interop.Runtime.WebSocketAbort(webSocket.JSHandle, out int exception, out string res); if (exception != 0) throw new JSException(res); } From f950d2dc37fe408b39a238d71b6cc462f9634534 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 3 Mar 2022 23:32:25 -0800 Subject: [PATCH 039/128] Fix incorrect signatures --- src/mono/wasm/runtime/corebindings.ts | 4 ++-- src/mono/wasm/runtime/web-socket.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index fab90cc782a91b..fdcd7b3bf89f1d 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -24,8 +24,8 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_object_to_string_ref", "ObjectToStringRef", "m"], ["_get_date_value_ref", "GetDateValueRef", "m"], - ["_create_date_time_ref", "CreateDateTimeRef", "d!"], - ["_create_uri_ref", "CreateUriRef", "s!"], + ["_create_date_time_ref", "CreateDateTimeRef", "dm"], + ["_create_uri_ref", "CreateUriRef", "sm"], ["_is_simple_array_ref", "IsSimpleArrayRef", "m"], ]; diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 27d91badad8a34..55a3464aacbcea 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -8,9 +8,9 @@ import { PromiseControl, _create_cancelable_promise } from "./cancelable-promise import { _mono_array_root_to_js_array, _wrap_delegate_root_as_function } from "./cs-to-js"; import { mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle } from "./gc-handles"; import { _wrap_js_thenable_as_task_root } from "./js-to-cs"; -import { wrap_error, wrap_error_root } from "./method-calls"; +import { wrap_error_root } from "./method-calls"; import { conv_string_root } from "./strings"; -import { JSHandle, MonoArray, MonoObject, MonoObjectNull, MonoString, MonoObjectRef } from "./types"; +import { JSHandle, MonoArray, MonoObject, MonoString, MonoObjectRef } from "./types"; import { Module } from "./imports"; import { Int32Ptr } from "./types/emscripten"; From 767a559f783327108f064953649737844cee48f5 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 8 Mar 2022 00:27:40 -0800 Subject: [PATCH 040/128] Checkpoint --- src/mono/wasm/runtime/cs-to-js.ts | 2 +- src/mono/wasm/runtime/cwraps.ts | 27 +++++++++++++------------ src/mono/wasm/runtime/driver.c | 16 ++++++--------- src/mono/wasm/runtime/method-binding.ts | 10 --------- 4 files changed, 21 insertions(+), 34 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 5ad6752f948bfd..cfdfbaad4f1add 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -208,7 +208,7 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address); try { if (typeof result[delegate_invoke_symbol] === "undefined") { - result[delegate_invoke_symbol] = cwraps.mono_wasm_get_delegate_invoke(delegateRoot.value); + result[delegate_invoke_symbol] = cwraps.mono_wasm_get_delegate_invoke_ref(delegateRoot.address); if (!result[delegate_invoke_symbol]) { throw new Error("System.Delegate Invoke method can not be resolved."); } diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 4c2f7665131412..04b76adf7bd02e 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -55,14 +55,13 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_box_primitive_ref", "void", ["number", "number", "number", "number"]], ["mono_wasm_intern_string_ref", "void", ["number"]], ["mono_wasm_assembly_get_entry_point", "number", ["number"]], - ["mono_wasm_get_delegate_invoke", "number", ["number"]], + ["mono_wasm_get_delegate_invoke_ref", "number", ["number"]], ["mono_wasm_string_array_new_ref", "void", ["number", "number"]], ["mono_wasm_typed_array_new", "number", ["number", "number", "number", "number"]], ["mono_wasm_class_get_type", "number", ["number"]], ["mono_wasm_type_get_class", "number", ["number"]], ["mono_wasm_get_type_name", "string", ["number"]], ["mono_wasm_get_type_aqn", "string", ["number"]], - ["mono_wasm_unbox_rooted", "number", ["number"]], //DOTNET ["mono_wasm_string_from_js", "number", ["string"]], @@ -79,7 +78,6 @@ export interface t_Cwraps { // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; mono_wasm_deregister_root(addr: VoidPtr): void; - mono_wasm_string_get_data(string: MonoString, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; mono_wasm_string_get_data_ref(stringRef: MonoObjectRef, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; mono_wasm_set_is_debugger_attached(value: boolean): void; mono_wasm_send_dbg_command(id: number, command_set: number, command: number, data: VoidPtr, size: number): boolean; @@ -95,6 +93,9 @@ export interface t_Cwraps { mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void; mono_wasm_load_runtime(unused: string, debug_level: number): void; + // Deprecated + 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; @@ -103,20 +104,12 @@ export interface t_Cwraps { 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(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; mono_wasm_invoke_method_ref(method: MonoMethod, this_arg: MonoObjectRef, params: VoidPtr, out_exc: MonoObjectRef, out_result: MonoObjectRef): void; mono_wasm_string_get_utf8(str: MonoString): CharPtr; mono_wasm_string_from_utf16_ref(str: CharPtr, len: number, result: MonoObjectRef): void; mono_wasm_get_obj_type(str: MonoObject): number; mono_wasm_array_length(array: MonoArray): number; - // Deprecated - mono_wasm_obj_array_new(size: number): MonoArray; - // Deprecated - mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; - // Deprecated - mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; - 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; @@ -125,14 +118,22 @@ export interface t_Cwraps { mono_wasm_box_primitive_ref(klass: MonoClass, value: VoidPtr, value_size: number, result: MonoObjectRef): void; mono_wasm_intern_string_ref(strRef: MonoObjectRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; - mono_wasm_get_delegate_invoke(delegate: MonoObject): MonoMethod; mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; mono_wasm_typed_array_new(arr: VoidPtr, length: number, size: number, type: number): MonoArray; 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; - mono_wasm_unbox_rooted(obj: MonoObject): VoidPtr; + + // Deprecated + mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; + // Deprecated + mono_wasm_obj_array_new(size: number): MonoArray; + // Deprecated + mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; + // Deprecated + mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; //DOTNET mono_wasm_string_from_js(str: string): MonoString; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 164f34e99b00e6..a07a2e99f07889 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -651,9 +651,13 @@ mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int argument } EMSCRIPTEN_KEEPALIVE MonoMethod* -mono_wasm_get_delegate_invoke (MonoObject *delegate) +mono_wasm_get_delegate_invoke_ref (MonoObject **delegate) { - return mono_get_delegate_invoke(mono_object_get_class (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 @@ -1270,14 +1274,6 @@ mono_wasm_type_get_class (MonoType *type) return mono_type_get_class (type); } -EMSCRIPTEN_KEEPALIVE void * -mono_wasm_unbox_rooted (MonoObject *obj) -{ - if (!obj) - return NULL; - return mono_object_unbox (obj); -} - 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/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index b53df165c9e02c..048784dcd6ac38 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -217,7 +217,6 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args const closure: any = { Module, _malloc: Module._malloc, - mono_wasm_unbox_rooted: cwraps.mono_wasm_unbox_rooted, setI32, setU32, setF32, @@ -263,13 +262,6 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args body.push(`rootBuffer.set (${i}, ${valueKey});`); } - // HACK: needs_unbox indicates that we were passed a pointer to a managed object, and either - // it was already rooted by our caller or (needs_root = true) by us. Now we can unbox it and - // pass the raw address of its boxed value into the callee. - // FIXME: This isn't fully GC or thread safe - if (step.needs_unbox) - body.push(`${valueKey} = mono_wasm_unbox_rooted (${valueKey});`); - if (step.indirect) { const offsetText = `(indirectStart + ${indirectLocalOffset})`; @@ -595,7 +587,6 @@ export type Converter = { // (value: any, result_root: WasmRoot) convert_root?: Function; needs_root?: boolean; - needs_unbox?: boolean; indirect?: ConverterStepIndirects; size?: number; }[]; @@ -608,7 +599,6 @@ export type Converter = { key?: string; name?: string; needs_root?: boolean; - needs_unbox?: boolean; compiled_variadic_function?: Function | null; compiled_function?: Function | null; scratchRootBuffer?: WasmRootBuffer | null; From d94bbb1559f0d38613793bdd78598fc6fd7e0939 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 8 Mar 2022 01:28:35 -0800 Subject: [PATCH 041/128] Fix lint --- src/mono/wasm/runtime/method-calls.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 4582f4e7af5a93..853bca45681125 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -479,6 +479,7 @@ export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { return js_string_to_mono_string(res)!; } +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: WasmRoot): void { // FIXME result.value = wrap_error(is_exception, ex); From 0996c1d4d35d839cc83b2e4af6c6adabe49ed33b Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 8 Mar 2022 02:00:08 -0800 Subject: [PATCH 042/128] Add new 'R' signature char for 'ref object' --- .../JavaScript/Runtime.CS.Owned.cs | 4 ++-- .../JavaScript/Runtime.JS.Owned.cs | 2 +- src/mono/wasm/runtime/corebindings.ts | 4 ++-- src/mono/wasm/runtime/js-to-cs.ts | 2 +- src/mono/wasm/runtime/method-binding.ts | 24 +++++++++++++++---- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs index 89cd8baf56ac34..31862734f259a0 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs @@ -27,7 +27,7 @@ public static void GetCSOwnedObjectByJSHandleRef(int jsHandle, int shouldAddInfl result = null; } - public static int TryGetCSOwnedObjectJSHandleRef(ref object rawObj, int shouldAddInflight) + public static int TryGetCSOwnedObjectJSHandleRef(in object rawObj, int shouldAddInflight) { JSObject? jsObject = rawObj as JSObject; if (jsObject != null && shouldAddInflight != 0) @@ -37,7 +37,7 @@ public static int TryGetCSOwnedObjectJSHandleRef(ref object rawObj, int shouldAd return jsObject?.JSHandle ?? 0; } - public static int GetCSOwnedObjectJSHandleRef(ref JSObject jsObject, int shouldAddInflight) + public static int GetCSOwnedObjectJSHandleRef(in JSObject jsObject, int shouldAddInflight) { jsObject.AssertNotDisposed(); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index 25018e7a6eb02f..a3ee78ca9ac133 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -61,7 +61,7 @@ public static int CreateTaskSource() return GetJSOwnedObjectGCHandleRef(tcs); } - public static void SetTaskSourceResult(int tcsGCHandle, object result) + public static void SetTaskSourceResultRef(int tcsGCHandle, in object result) { GCHandle handle = (GCHandle)(IntPtr)tcsGCHandle; // this is JS owned Normal handle. We always have a Target diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index fdcd7b3bf89f1d..ae50a47c8413d2 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -16,7 +16,7 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_release_js_owned_object_by_gc_handle", "ReleaseJSOwnedObjectByGCHandle", "i"], ["_create_tcs", "CreateTaskSource", ""], - ["_set_tcs_result", "SetTaskSourceResult", "io"], + ["_set_tcs_result_ref", "SetTaskSourceResultRef", "iR"], ["_set_tcs_failure", "SetTaskSourceFailure", "is"], ["_get_tcs_task_ref", "GetTaskSourceTaskRef", "im"], ["_task_from_result_ref", "TaskFromResultRef", "om"], @@ -42,7 +42,7 @@ export interface t_CSwraps { _create_tcs(): GCHandle; // FIXME: We currently rely on marshaling to convert result types - _set_tcs_result(gcHandle: GCHandle, result: any): void + _set_tcs_result_ref(gcHandle: GCHandle, result: any): void _set_tcs_failure(gcHandle: GCHandle, result: string): void _get_tcs_task_ref(gcHandle: GCHandle, result: MonoObjectRef): void; // FIXME: We rely on marshaling for the value to be converted diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index e6bd452f74e6f8..933efbdb070973 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -231,7 +231,7 @@ export function _wrap_js_thenable_as_task_root(thenable: Promise, resultRoo // TODO optimization: return the tcs.Task on this same call instead of _get_tcs_task const tcs_gc_handle = corebindings._create_tcs(); thenable.then((result) => { - corebindings._set_tcs_result(tcs_gc_handle, result); + corebindings._set_tcs_result_ref(tcs_gc_handle, result); // let go of the thenable reference mono_wasm_release_cs_owned_object(thenable_js_handle); diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 048784dcd6ac38..ef557c68eb2e80 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -129,6 +129,8 @@ export function _create_primitive_converters(): void { // also as those are callback arguments and we don't have platform code which would release the in-flight reference on C# end result.set("o", { steps: [{ convert_root: _js_to_mono_obj_root.bind(BINDING, false) }], size: 0, needs_root: true }); result.set("u", { steps: [{ convert_root: _js_to_mono_uri_root.bind(BINDING, false) }], size: 0, needs_root: true }); + // ref object aka T&& + result.set("R", { steps: [{ convert_root: _js_to_mono_obj_root.bind(BINDING, false), byref: true }], size: 0, needs_root: true }); // result.set ('k', { steps: [{ convert: js_to_mono_enum.bind (this), indirect: 'i64'}], size: 8}); result.set("j", { steps: [{ convert: js_to_mono_enum.bind(BINDING), indirect: "i32" }], size: 8 }); @@ -242,14 +244,27 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args argumentNames.push(argKey); if (step.convert_root) { + body.push("if (!rootBuffer) throw new Error('no root buffer provided');"); // FIXME: Optimize this!!! if (!converter.scratchValueRoot) closure.scratchValueRoot = converter.scratchValueRoot = mono_wasm_new_root(); closure[closureKey] = step.convert_root; + // Convert the object and store the managed reference in our scratch root body.push(`${closureKey}(${argKey}, scratchValueRoot);`); - // FIXME: Not GC safe - body.push(`let ${valueKey} = scratchValueRoot.value;`); + // Next, copy that managed reference into the arguments root buffer. This is its new permanent home + // FIXME: It would be ideal if we could skip this step, perhaps by having an external root point into the arguments root buffer + body.push(`let address${i} = rootBuffer.get_address(${i});`); + body.push(`scratchValueRoot.copy_to_address(address${i});`); + // Now that it's copied into the root buffer we can either pass the address of that root to the callee, or, + // if we're feeling particularly GC unsafe and thread hazardous, pass the managed pointer directly. + if (step.byref) { + body.push(`let ${valueKey} = address${i};`); + } else { + // FIXME: This is not GC safe! The object could move between now and the method invocation, even though we have + // prevented it from being GCed by storing the pointer into a root buffer. + body.push(`let ${valueKey} = scratchValueRoot.value;`); + } } else if (step.convert) { closure[closureKey] = step.convert; body.push(`let ${valueKey} = ${closureKey}(${argKey}, method, ${i});`); @@ -257,7 +272,7 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args body.push(`let ${valueKey} = ${argKey};`); } - if (step.needs_root) { + if (step.needs_root && !step.convert_root) { body.push("if (!rootBuffer) throw new Error('no root buffer provided');"); body.push(`rootBuffer.set (${i}, ${valueKey});`); } @@ -578,7 +593,7 @@ export type ArgsMarshalString = "" | `${ArgsMarshal}${ArgsMarshal}${ArgsMarshal}${ArgsMarshal}${_ExtraArgsMarshalOperators}`; */ -type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "i64" +type ConverterStepIndirects = "u32" | "i32" | "float" | "double" | "i64" | "reference" export type Converter = { steps: { @@ -587,6 +602,7 @@ export type Converter = { // (value: any, result_root: WasmRoot) convert_root?: Function; needs_root?: boolean; + byref?: boolean; indirect?: ConverterStepIndirects; size?: number; }[]; From f4020b26a5dc9b19c30c670651a4357b839f634f Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 8 Mar 2022 02:04:59 -0800 Subject: [PATCH 043/128] Checkpoint --- .../Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs | 2 +- src/mono/wasm/runtime/corebindings.ts | 6 ++---- src/mono/wasm/runtime/method-binding.ts | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs index a3ee78ca9ac133..5854356d95c6f6 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.JS.Owned.cs @@ -85,7 +85,7 @@ public static void GetTaskSourceTaskRef(int tcsGCHandle, out object result) result = tcs.Task; } - public static void TaskFromResultRef(object? obj, out object result) + public static void TaskFromResultRef(in object? obj, out object result) { result = Task.FromResult(obj); } diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index ae50a47c8413d2..1782c52f4150d8 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.ts @@ -19,7 +19,7 @@ const fn_signatures: [jsname: string, csname: string, signature: string/*ArgsMar ["_set_tcs_result_ref", "SetTaskSourceResultRef", "iR"], ["_set_tcs_failure", "SetTaskSourceFailure", "is"], ["_get_tcs_task_ref", "GetTaskSourceTaskRef", "im"], - ["_task_from_result_ref", "TaskFromResultRef", "om"], + ["_task_from_result_ref", "TaskFromResultRef", "Rm"], ["_setup_js_cont_ref", "SetupJSContinuationRef", "mo"], ["_object_to_string_ref", "ObjectToStringRef", "m"], @@ -41,12 +41,10 @@ export interface t_CSwraps { _release_js_owned_object_by_gc_handle(gcHandle: GCHandle): void; _create_tcs(): GCHandle; - // FIXME: We currently rely on marshaling to convert result types _set_tcs_result_ref(gcHandle: GCHandle, result: any): void _set_tcs_failure(gcHandle: GCHandle, result: string): void _get_tcs_task_ref(gcHandle: GCHandle, result: MonoObjectRef): void; - // FIXME: We rely on marshaling for the value to be converted - _task_from_result_ref(value: MonoObject, result: MonoObjectRef): void; + _task_from_result_ref(value: any, result: MonoObjectRef): void; // FIXME: PromiseControl is a JS object so we can't pass an address directly _setup_js_cont_ref(task: MonoObjectRef, continuation: PromiseControl): void; diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index ef557c68eb2e80..8fd8848b128b23 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -303,7 +303,7 @@ export function _compile_converter_for_marshal_string(args_marshal: string/*Args body.push(`setU32(buffer + (${i} * 4), ${offsetText});`); indirectLocalOffset += step.size!; } else { - body.push(`setI32(buffer + (${i} * 4), ${valueKey});`); + body.push(`setU32(buffer + (${i} * 4), ${valueKey});`); indirectLocalOffset += 4; } body.push(""); From 503f4af99ee8bc9c6909be8334e0ebba666d244d Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 8 Mar 2022 02:19:17 -0800 Subject: [PATCH 044/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 4 +-- .../JavaScript/Runtime.CS.Owned.cs | 2 +- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 4 +-- src/mono/wasm/runtime/corebindings.c | 6 ++--- src/mono/wasm/runtime/cs-to-js.ts | 26 ++++++++++++------- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 8 +++--- src/mono/wasm/runtime/exports.ts | 4 +-- src/mono/wasm/runtime/gc-handles.ts | 5 ++-- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index ded0008684c708..1ee39f79695f32 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -30,9 +30,9 @@ internal static partial class Runtime internal static extern object GetGlobalObject(string? globalName, out int exceptionalResult); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object ReleaseCSOwnedObject(int jsHandle); + internal static extern void ReleaseCSOwnedObject(int jsHandle); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object CreateCSOwnedObject(string className, object[] parms, out int exceptionalResult); + internal static extern void CreateCSOwnedObjectRef(string className, object[] parms, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern object TypedArrayToArray(int jsHandle, out int exceptionalResult); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs index 31862734f259a0..475f773b39ef4e 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs @@ -105,7 +105,7 @@ internal static bool ReleaseCSOwnedObject(JSObject objToRelease) // TODO: Ref internal static IntPtr CreateCSOwnedObject(JSObject proxy, string typeName, params object[] parms) { - object res = Interop.Runtime.CreateCSOwnedObject(typeName, parms, out int exception); + Interop.Runtime.CreateCSOwnedObjectRef(typeName, parms, out int exception, out object res); if (exception != 0) throw new JSException((string)res); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index a2add7ec2fd680..96b89f48cee6de 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -12,7 +12,7 @@ const DotnetSupportLib = { $DOTNET__postset: ` let __dotnet_replacements = {readAsync, fetch: globalThis.fetch, require}; let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, requirePromise:Promise.resolve(require)}, + { isESM:false, isGlobal:ENVIRONMENT_IS_GLOBAL, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, ExitStatus, requirePromise:Promise.resolve(require)}, { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, __dotnet_replacements); readAsync = __dotnet_replacements.readAsync; @@ -48,7 +48,7 @@ const linked_functions = [ "mono_wasm_get_by_index", "mono_wasm_set_by_index", "mono_wasm_get_global_object", - "mono_wasm_create_cs_owned_object", + "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", "mono_wasm_typed_array_to_array", "mono_wasm_typed_array_copy_to", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index b7e4eda4c553eb..9f1206bc17d67a 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -16,8 +16,8 @@ extern MonoObject* mono_wasm_get_by_index (int js_handle, int property_index, in extern MonoObject* mono_wasm_set_object_property (int js_handle, MonoString *propertyName, MonoObject *value, int createIfNotExist, int hasOwnProperty, int *is_exception); extern MonoObject* mono_wasm_set_by_index (int js_handle, int property_index, MonoObject *value, int *is_exception); extern MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception); -extern void* mono_wasm_release_cs_owned_object (int js_handle); -extern MonoObject* mono_wasm_create_cs_owned_object (MonoString *core_name, MonoArray *args, int *is_exception); +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 MonoObject* mono_wasm_typed_array_to_array (int js_handle, int *is_exception); extern MonoObject* mono_wasm_typed_array_copy_to (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception); extern MonoObject* mono_wasm_typed_array_from (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception); @@ -40,7 +40,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::SetObjectProperty", mono_wasm_set_object_property); mono_add_internal_call ("Interop/Runtime::SetByIndex", mono_wasm_set_by_index); mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object); - mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObject", mono_wasm_create_cs_owned_object); + mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); mono_add_internal_call ("Interop/Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); mono_add_internal_call ("Interop/Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to); diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index cfdfbaad4f1add..e33e0f9635793a 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -1,19 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_root, WasmRoot } from "./roots"; +import { mono_wasm_new_root, WasmRoot, mono_wasm_new_external_root } from "./roots"; import { GCHandle, JSHandleDisposed, MarshalError, MarshalType, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, MonoString, - MonoType, MonoTypeNull + MonoType, MonoTypeNull, MonoObjectRef } from "./types"; import { runtimeHelpers } from "./imports"; import { conv_string_root } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; -import { mono_method_get_call_signature, call_method, wrap_error } from "./method-calls"; -import { _js_to_mono_obj_unsafe } from "./js-to-cs"; +import { mono_method_get_call_signature, call_method, wrap_error, wrap_error_root } from "./method-calls"; +import { _js_to_mono_obj_root } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; import { getU32, getI32, getF32, getF64 } from "./memory"; import { Int32Ptr, VoidPtr } from "./types/emscripten"; @@ -235,17 +235,21 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ return result; } -export function mono_wasm_create_cs_owned_object(core_name: MonoString, args: MonoArray, is_exception: Int32Ptr): MonoObject { - const argsRoot = mono_wasm_new_root(args), nameRoot = mono_wasm_new_root(core_name); +export function mono_wasm_create_cs_owned_object_ref(core_name: MonoString, args: MonoArray, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const argsRoot = mono_wasm_new_root(args), + nameRoot = mono_wasm_new_root(core_name), + resultRoot = mono_wasm_new_external_root(result_address); try { const js_name = conv_string_root(nameRoot); if (!js_name) { - return wrap_error(is_exception, "Invalid name @" + nameRoot.value); + wrap_error_root(is_exception, "Invalid name @" + nameRoot.value, resultRoot); + return; } const coreObj = (globalThis)[js_name]; if (coreObj === null || typeof coreObj === "undefined") { - return wrap_error(is_exception, "JavaScript host object '" + js_name + "' not found."); + wrap_error_root(is_exception, "JavaScript host object '" + js_name + "' not found.", resultRoot); + return; } try { @@ -268,11 +272,13 @@ export function mono_wasm_create_cs_owned_object(core_name: MonoString, args: Mo const js_handle = mono_wasm_get_js_handle(js_obj); // returns boxed js_handle int, because on exception we need to return String on same method signature // here we don't have anything to in-flight reference, as the JSObject doesn't exist yet - return _js_to_mono_obj_unsafe(false, js_handle); + _js_to_mono_obj_root(false, js_handle, resultRoot); } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, resultRoot); + return; } } finally { + resultRoot.release(); argsRoot.release(); nameRoot.release(); } diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 36f5b106a1f4f5..7ec7d184aa125c 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -8,7 +8,7 @@ const DotnetSupportLib = { $DOTNET: {}, // this line will be placed early on emscripten runtime creation, passing import and export objects into __dotnet_runtime IFFE // 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. + // 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. @@ -39,7 +39,7 @@ if (ENVIRONMENT_IS_NODE) { readAsync(wasmBinaryFile, function (response) { resolve(new Uint8Array(/** @type{!ArrayBuffer} */(response))) }, reject) }); } - + } catch (err) { return getBinary(wasmBinaryFile); @@ -49,7 +49,7 @@ if (ENVIRONMENT_IS_NODE) { } } let __dotnet_exportedAPI = __dotnet_runtime.__initializeImportsAndExports( - { isESM:true, isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, requirePromise:__dotnet_replacements.requirePromise }, + { isESM:true, isGlobal:false, isNode:ENVIRONMENT_IS_NODE, isShell:ENVIRONMENT_IS_SHELL, isWeb:ENVIRONMENT_IS_WEB, locateFile, quit_, ExitStatus, requirePromise:__dotnet_replacements.requirePromise }, { mono:MONO, binding:BINDING, internal:INTERNAL, module:Module }, __dotnet_replacements); readAsync = __dotnet_replacements.readAsync; @@ -85,7 +85,7 @@ const linked_functions = [ "mono_wasm_get_by_index", "mono_wasm_set_by_index", "mono_wasm_get_global_object", - "mono_wasm_create_cs_owned_object", + "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", "mono_wasm_typed_array_to_array", "mono_wasm_typed_array_copy_to", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index a34f65962f2a6d..ee3c18075d266b 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -38,7 +38,7 @@ import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu"; import { conv_string, conv_string_root, js_string_to_mono_string, mono_intern_string } from "./strings"; import { js_to_mono_obj, js_typed_array_to_array, mono_wasm_typed_array_to_array } from "./js-to-cs"; import { - mono_array_to_js_array, mono_wasm_create_cs_owned_object, unbox_mono_obj + mono_array_to_js_array, mono_wasm_create_cs_owned_object_ref, unbox_mono_obj } from "./cs-to-js"; import { call_static_method, mono_bind_static_method, mono_call_assembly_entry_point, @@ -293,7 +293,7 @@ export const __linker_exports: any = { mono_wasm_get_by_index, mono_wasm_set_by_index, mono_wasm_get_global_object, - mono_wasm_create_cs_owned_object, + mono_wasm_create_cs_owned_object_ref, mono_wasm_release_cs_owned_object, mono_wasm_typed_array_to_array, mono_wasm_typed_array_copy_to, diff --git a/src/mono/wasm/runtime/gc-handles.ts b/src/mono/wasm/runtime/gc-handles.ts index 2f335199f518d2..8ee1cb3fcc2a26 100644 --- a/src/mono/wasm/runtime/gc-handles.ts +++ b/src/mono/wasm/runtime/gc-handles.ts @@ -97,13 +97,13 @@ export function mono_wasm_get_js_handle(js_obj: any): JSHandle { return js_handle as JSHandle; } -export function mono_wasm_release_cs_owned_object(js_handle: JSHandle): any { +export function mono_wasm_release_cs_owned_object(js_handle: JSHandle): void { const obj = _cs_owned_objects_by_js_handle[js_handle]; if (typeof obj !== "undefined" && obj !== null) { // if this is the global object then do not // unregister it. if (globalThis === obj) - return obj; + return; if (typeof obj[cs_owned_js_handle_symbol] !== "undefined") { obj[cs_owned_js_handle_symbol] = undefined; @@ -112,5 +112,4 @@ export function mono_wasm_release_cs_owned_object(js_handle: JSHandle): any { _cs_owned_objects_by_js_handle[js_handle] = undefined; _js_handle_free_list.push(js_handle); } - return obj; } From 8f639ecb552ff7d715eb149014b2a475df6721bb Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 19:20:56 -0800 Subject: [PATCH 045/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 6 +- .../InteropServices/JavaScript/TypedArray.cs | 6 +- src/mono/wasm/runtime/buffers.ts | 72 +++++++++++++------ src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 6 +- src/mono/wasm/runtime/corebindings.c | 12 ++-- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 6 +- src/mono/wasm/runtime/exports.ts | 8 +-- 7 files changed, 71 insertions(+), 45 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index 1ee39f79695f32..b43a68a2ead923 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -36,11 +36,11 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern object TypedArrayToArray(int jsHandle, out int exceptionalResult); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object TypedArrayCopyTo(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult); + internal static extern void TypedArrayCopyToRef(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object TypedArrayFrom(int arrayPtr, int begin, int end, int bytesPerElement, int type, out int exceptionalResult); + internal static extern void TypedArrayFromRef(int arrayPtr, int begin, int end, int bytesPerElement, int type, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object TypedArrayCopyFrom(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult); + internal static extern void TypedArrayCopyFromRef(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern string? AddEventListener(int jsHandle, string name, int gcHandle, int optionsJsHandle); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs index 6a45c28216ac54..0355b1068764e0 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs @@ -188,7 +188,7 @@ public static unsafe T From(ReadOnlySpan span) ReadOnlySpan bytes = MemoryMarshal.AsBytes(span); fixed (byte* ptr = bytes) { - object res = Interop.Runtime.TypedArrayFrom((int)ptr, 0, span.Length, Unsafe.SizeOf(), (int)type, out int exception); + Interop.Runtime.TypedArrayFromRef((int)ptr, 0, span.Length, Unsafe.SizeOf(), (int)type, out int exception, out object res); if (exception != 0) throw new JSException((string)res); var r = (T)res; @@ -205,7 +205,7 @@ public unsafe int CopyTo(Span span) ReadOnlySpan bytes = MemoryMarshal.AsBytes(span); fixed (byte* ptr = bytes) { - object res = Interop.Runtime.TypedArrayCopyTo(JSHandle, (int)ptr, 0, span.Length, Unsafe.SizeOf(), out int exception); + Interop.Runtime.TypedArrayCopyToRef(JSHandle, (int)ptr, 0, span.Length, Unsafe.SizeOf(), out int exception, out object res); if (exception != 0) throw new JSException((string)res); return (int)res / Unsafe.SizeOf(); @@ -225,7 +225,7 @@ public unsafe int CopyFrom(ReadOnlySpan span) ReadOnlySpan bytes = MemoryMarshal.AsBytes(span); fixed (byte* ptr = bytes) { - object res = Interop.Runtime.TypedArrayCopyFrom(JSHandle, (int)ptr, 0, span.Length, Unsafe.SizeOf(), out int exception); + Interop.Runtime.TypedArrayCopyFromRef(JSHandle, (int)ptr, 0, span.Length, Unsafe.SizeOf(), out int exception, out object res); if (exception != 0) throw new JSException((string)res); return (int)res / Unsafe.SizeOf(); diff --git a/src/mono/wasm/runtime/buffers.ts b/src/mono/wasm/runtime/buffers.ts index 6aa725de23f910..46ab25f82774ee 100644 --- a/src/mono/wasm/runtime/buffers.ts +++ b/src/mono/wasm/runtime/buffers.ts @@ -1,12 +1,13 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { JSHandle, MonoArray, MonoObject, MonoString } from "./types"; +import { JSHandle, MonoArray, MonoObject, MonoString, MonoObjectRef } from "./types"; import { Module } from "./imports"; import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; -import { wrap_error } from "./method-calls"; -import { _js_to_mono_obj_unsafe } from "./js-to-cs"; +import { wrap_error_root } from "./method-calls"; +import { _js_to_mono_obj_root } from "./js-to-cs"; import { Int32Ptr, TypedArray, VoidPtr } from "./types/emscripten"; +import { mono_wasm_new_external_root } from "./roots"; // Creates a new typed array from pinned array address from pinned_array allocated on the heap to the typed array. // adress of managed pinned array -> copy from heap -> typed array memory @@ -134,33 +135,58 @@ function typedarray_copy_from(typed_array: TypedArray, pinned_array: MonoArray, } } -export function mono_wasm_typed_array_copy_to(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr): MonoObject { - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!js_obj) { - return wrap_error(is_exception, "ERR07: Invalid JS object handle '" + js_handle + "'"); +export function mono_wasm_typed_array_copy_to_ref(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const resultRoot = mono_wasm_new_external_root(result_address); + try { + const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); + if (!js_obj) { + wrap_error_root(is_exception, "ERR07: Invalid JS object handle '" + js_handle + "'", resultRoot); + return; + } + + const res = typedarray_copy_to(js_obj, pinned_array, begin, end, bytes_per_element); + // FIXME: We should just return an int + // returns num_of_bytes boxed + _js_to_mono_obj_root(false, res, resultRoot); + } catch (exc) { + wrap_error_root(is_exception, String(exc), resultRoot); + } finally { + resultRoot.release(); } - - const res = typedarray_copy_to(js_obj, pinned_array, begin, end, bytes_per_element); - // returns num_of_bytes boxed - return _js_to_mono_obj_unsafe(false, res); } // eslint-disable-next-line @typescript-eslint/no-unused-vars -export function mono_wasm_typed_array_from(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr): MonoObject { - const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type); - // returns JS typed array like Int8Array, to be wraped with JSObject proxy - return _js_to_mono_obj_unsafe(true, res); +export function mono_wasm_typed_array_from_ref(pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, type: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const resultRoot = mono_wasm_new_external_root(result_address); + try { + const res = typed_array_from(pinned_array, begin, end, bytes_per_element, type); + // returns JS typed array like Int8Array, to be wraped with JSObject proxy + _js_to_mono_obj_root(true, res, resultRoot); + } catch (exc) { + wrap_error_root(is_exception, String(exc), resultRoot); + } finally { + resultRoot.release(); + } } -export function mono_wasm_typed_array_copy_from(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr): MonoObject | MonoString { - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!js_obj) { - return wrap_error(is_exception, "ERR08: Invalid JS object handle '" + js_handle + "'"); +export function mono_wasm_typed_array_copy_from_ref(js_handle: JSHandle, pinned_array: MonoArray, begin: number, end: number, bytes_per_element: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const resultRoot = mono_wasm_new_external_root(result_address); + try { + const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); + if (!js_obj) { + wrap_error_root(is_exception, "ERR08: Invalid JS object handle '" + js_handle + "'", resultRoot); + return; + } + + const res = typedarray_copy_from(js_obj, pinned_array, begin, end, bytes_per_element); + // FIXME: We should just return an int + // returns num_of_bytes boxed + _js_to_mono_obj_root(false, res, resultRoot); + } catch (exc) { + wrap_error_root(is_exception, String(exc), resultRoot); + } finally { + resultRoot.release(); } - - const res = typedarray_copy_from(js_obj, pinned_array, begin, end, bytes_per_element); - // returns num_of_bytes boxed - return _js_to_mono_obj_unsafe(false, res); } export function has_backing_array_buffer(js_obj: TypedArray): boolean { diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 96b89f48cee6de..397e27097a9e79 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -51,9 +51,9 @@ const linked_functions = [ "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", "mono_wasm_typed_array_to_array", - "mono_wasm_typed_array_copy_to", - "mono_wasm_typed_array_from", - "mono_wasm_typed_array_copy_from", + "mono_wasm_typed_array_copy_to_ref", + "mono_wasm_typed_array_from_ref", + "mono_wasm_typed_array_copy_from_ref", "mono_wasm_add_event_listener", "mono_wasm_remove_event_listener", "mono_wasm_cancel_promise", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 9f1206bc17d67a..10702ebca762a0 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -19,9 +19,9 @@ extern MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is 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 MonoObject* mono_wasm_typed_array_to_array (int js_handle, int *is_exception); -extern MonoObject* mono_wasm_typed_array_copy_to (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception); -extern MonoObject* mono_wasm_typed_array_from (int ptr, int begin, int end, int bytes_per_element, int type, int *is_exception); -extern MonoObject* mono_wasm_typed_array_copy_from (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception); +extern void mono_wasm_typed_array_copy_to_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, 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_typed_array_copy_from_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception, MonoObject** result); extern MonoString* mono_wasm_add_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int optionsObjHandle); extern MonoString* mono_wasm_remove_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int capture); extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exception); @@ -43,9 +43,9 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); mono_add_internal_call ("Interop/Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); - mono_add_internal_call ("Interop/Runtime::TypedArrayCopyTo", mono_wasm_typed_array_copy_to); - mono_add_internal_call ("Interop/Runtime::TypedArrayFrom", mono_wasm_typed_array_from); - mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFrom", mono_wasm_typed_array_copy_from); + mono_add_internal_call ("Interop/Runtime::TypedArrayCopyToRef", mono_wasm_typed_array_copy_to_ref); + mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); + mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFromRef", mono_wasm_typed_array_copy_from_ref); mono_add_internal_call ("Interop/Runtime::CompileFunction", mono_wasm_compile_function); mono_add_internal_call ("Interop/Runtime::AddEventListener", mono_wasm_add_event_listener); mono_add_internal_call ("Interop/Runtime::RemoveEventListener", mono_wasm_remove_event_listener); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 7ec7d184aa125c..5aef404a95185a 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -88,9 +88,9 @@ const linked_functions = [ "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", "mono_wasm_typed_array_to_array", - "mono_wasm_typed_array_copy_to", - "mono_wasm_typed_array_from", - "mono_wasm_typed_array_copy_from", + "mono_wasm_typed_array_copy_to_ref", + "mono_wasm_typed_array_from_ref", + "mono_wasm_typed_array_copy_from_ref", "mono_wasm_add_event_listener", "mono_wasm_remove_event_listener", "mono_wasm_cancel_promise", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index ee3c18075d266b..043f8ea352fa30 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -49,7 +49,7 @@ import { mono_wasm_invoke_js_blazor, mono_wasm_invoke_js_with_args, mono_wasm_set_by_index, mono_wasm_set_object_property } from "./method-calls"; -import { mono_wasm_typed_array_copy_to, mono_wasm_typed_array_from, mono_wasm_typed_array_copy_from, mono_wasm_load_bytes_into_heap } from "./buffers"; +import { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_load_bytes_into_heap } from "./buffers"; import { mono_wasm_cancel_promise } from "./cancelable-promise"; import { mono_wasm_add_event_listener, mono_wasm_remove_event_listener } from "./event-listener"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; @@ -296,9 +296,9 @@ export const __linker_exports: any = { mono_wasm_create_cs_owned_object_ref, mono_wasm_release_cs_owned_object, mono_wasm_typed_array_to_array, - mono_wasm_typed_array_copy_to, - mono_wasm_typed_array_from, - mono_wasm_typed_array_copy_from, + mono_wasm_typed_array_copy_to_ref, + mono_wasm_typed_array_from_ref, + mono_wasm_typed_array_copy_from_ref, mono_wasm_add_event_listener, mono_wasm_remove_event_listener, mono_wasm_cancel_promise, From daefa4ab71ebbbdeecc9f19d1023454838579e65 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 19:26:58 -0800 Subject: [PATCH 046/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 2 +- .../InteropServices/JavaScript/TypedArray.cs | 2 +- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 2 +- src/mono/wasm/runtime/corebindings.c | 4 +-- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 +- src/mono/wasm/runtime/exports.ts | 4 +-- src/mono/wasm/runtime/js-to-cs.ts | 29 ++++++++++++------- 7 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index b43a68a2ead923..7fbdad37ff229e 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -34,7 +34,7 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void CreateCSOwnedObjectRef(string className, object[] parms, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object TypedArrayToArray(int jsHandle, out int exceptionalResult); + internal static extern void TypedArrayToArrayRef(int jsHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void TypedArrayCopyToRef(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs index 0355b1068764e0..e99b1c2f02606d 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs @@ -165,7 +165,7 @@ public U[] ToArray() { AssertNotDisposed(); - object res = Interop.Runtime.TypedArrayToArray(JSHandle, out int exception); + Interop.Runtime.TypedArrayToArrayRef(JSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 397e27097a9e79..5cd7d061b1b20f 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -50,7 +50,7 @@ const linked_functions = [ "mono_wasm_get_global_object", "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", - "mono_wasm_typed_array_to_array", + "mono_wasm_typed_array_to_array_ref", "mono_wasm_typed_array_copy_to_ref", "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 10702ebca762a0..be072410d13cbf 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -18,7 +18,7 @@ extern MonoObject* mono_wasm_set_by_index (int js_handle, int property_index, Mo extern MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception); 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 MonoObject* mono_wasm_typed_array_to_array (int js_handle, int *is_exception); +extern void mono_wasm_typed_array_to_array_ref (int js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_typed_array_copy_to_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, 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_typed_array_copy_from_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception, MonoObject** result); @@ -42,7 +42,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object); mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); - mono_add_internal_call ("Interop/Runtime::TypedArrayToArray", mono_wasm_typed_array_to_array); + mono_add_internal_call ("Interop/Runtime::TypedArrayToArrayRef", mono_wasm_typed_array_to_array_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayCopyToRef", mono_wasm_typed_array_copy_to_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFromRef", mono_wasm_typed_array_copy_from_ref); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 5aef404a95185a..3c1eac4bd3e7f3 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -87,7 +87,7 @@ const linked_functions = [ "mono_wasm_get_global_object", "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", - "mono_wasm_typed_array_to_array", + "mono_wasm_typed_array_to_array_ref", "mono_wasm_typed_array_copy_to_ref", "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 043f8ea352fa30..c85c37a3720d3d 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -36,7 +36,7 @@ import { import { mono_set_timeout, schedule_background_exec } from "./scheduling"; import { mono_wasm_load_icu_data, mono_wasm_get_icudt_name } from "./icu"; import { conv_string, conv_string_root, js_string_to_mono_string, mono_intern_string } from "./strings"; -import { js_to_mono_obj, js_typed_array_to_array, mono_wasm_typed_array_to_array } from "./js-to-cs"; +import { js_to_mono_obj, js_typed_array_to_array, mono_wasm_typed_array_to_array_ref } from "./js-to-cs"; import { mono_array_to_js_array, mono_wasm_create_cs_owned_object_ref, unbox_mono_obj } from "./cs-to-js"; @@ -295,7 +295,7 @@ export const __linker_exports: any = { mono_wasm_get_global_object, mono_wasm_create_cs_owned_object_ref, mono_wasm_release_cs_owned_object, - mono_wasm_typed_array_to_array, + mono_wasm_typed_array_to_array_ref, mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 933efbdb070973..5e90485a993358 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -10,12 +10,12 @@ import { } from "./gc-handles"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; -import { mono_wasm_new_root, mono_wasm_release_roots, WasmRoot } from "./roots"; -import { wrap_error } from "./method-calls"; +import { mono_wasm_new_root, mono_wasm_release_roots, WasmRoot, mono_wasm_new_external_root } from "./roots"; +import { wrap_error_root } from "./method-calls"; import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "./strings"; import { isThenable } from "./cancelable-promise"; import { has_backing_array_buffer } from "./buffers"; -import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, wasm_type_symbol, MonoClass } from "./types"; +import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, wasm_type_symbol, MonoClass, MonoObjectRef } from "./types"; import { setI32, setU32, setF64 } from "./memory"; import { Int32Ptr, TypedArray } from "./types/emscripten"; @@ -263,12 +263,21 @@ export function _wrap_js_thenable_as_task_root(thenable: Promise, resultRoo }; } -export function mono_wasm_typed_array_to_array(js_handle: JSHandle, is_exception: Int32Ptr): MonoArray | MonoString { - const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!js_obj) { - return wrap_error(is_exception, "ERR06: Invalid JS object handle '" + js_handle + "'"); - } +export function mono_wasm_typed_array_to_array_ref(js_handle: JSHandle, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const resultRoot = mono_wasm_new_external_root(result_address); + try { + const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); + if (!js_obj) { + wrap_error_root(is_exception, "ERR06: Invalid JS object handle '" + js_handle + "'", resultRoot); + return; + } - // returns pointer to C# array - return js_typed_array_to_array(js_obj); + // returns pointer to C# array + // FIXME: ref + resultRoot.value = js_typed_array_to_array(js_obj); + } catch (exc) { + wrap_error_root(is_exception, String(exc), resultRoot); + } finally { + resultRoot.release(); + } } From 05993d841d63c8ad152877ea1dcb4c2d8cb26fe1 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 19:38:17 -0800 Subject: [PATCH 047/128] Remove AddEventListener and RemoveEventListener Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 4 - .../InteropServices/JavaScript/JSObject.cs | 61 ----- .../JavaScript/JavaScriptTests.cs | 216 ------------------ src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 2 - src/mono/wasm/runtime/corebindings.c | 4 - src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 - src/mono/wasm/runtime/event-listener.ts | 87 +------ src/mono/wasm/runtime/exports.ts | 3 - 8 files changed, 1 insertion(+), 378 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index 7fbdad37ff229e..b13d01f38d687b 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -42,10 +42,6 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void TypedArrayCopyFromRef(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult, out object result); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern string? AddEventListener(int jsHandle, string name, int gcHandle, int optionsJsHandle); - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern string? RemoveEventListener(int jsHandle, string name, int gcHandle, bool capture); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketSend(int webSocketJSHandle, IntPtr messagePtr, int offset, int length, int messageType, bool endOfMessage, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs index c54f5266ed8b5f..c0a0e87d3c3774 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs @@ -45,67 +45,6 @@ public object Invoke(string method, params object?[] args) return res; } - public struct EventListenerOptions { - public bool Capture; - public bool Once; - public bool Passive; - public object? Signal; - } - - public int AddEventListener(string name, Action listener, EventListenerOptions? options = null) - { - AssertNotDisposed(); - - var optionsDict = options.HasValue - ? new JSObject() - : null; - - try { - if (options?.Signal != null) - throw new NotImplementedException("EventListenerOptions.Signal"); - - var jsfunc = Runtime.GetJSOwnedObjectGCHandleRef(listener); - // int exception; - if (options.HasValue) { - // TODO: Optimize this - var _options = options.Value; - optionsDict?.SetObjectProperty("capture", _options.Capture, true, true); - optionsDict?.SetObjectProperty("once", _options.Once, true, true); - optionsDict?.SetObjectProperty("passive", _options.Passive, true, true); - } - - // TODO: Pass options explicitly instead of using the object - // TODO: Handle errors - // We can't currently do this because adding any additional parameters or a return value causes - // a signature mismatch at runtime - var ret = Interop.Runtime.AddEventListener(JSHandle, name, jsfunc, optionsDict?.JSHandle ?? 0); - if (ret != null) - throw new JSException(ret); - return jsfunc; - } finally { - optionsDict?.Dispose(); - } - } - - public void RemoveEventListener(string name, Action? listener, EventListenerOptions? options = null) - { - AssertNotDisposed(); - - if (listener == null) - return; - var jsfunc = Runtime.GetJSOwnedObjectGCHandleRef(listener); - RemoveEventListener(name, jsfunc, options); - } - - public void RemoveEventListener(string name, int listenerGCHandle, EventListenerOptions? options = null) - { - AssertNotDisposed(); - - var ret = Interop.Runtime.RemoveEventListener(JSHandle, name, listenerGCHandle, options?.Capture ?? false); - if (ret != null) - throw new JSException(ret); - } - /// /// Returns the named property from the object, or throws a JSException on error. /// diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs index 7158c38899c13a..5ac6d8f904c6ff 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/tests/System/Runtime/InteropServices/JavaScript/JavaScriptTests.cs @@ -237,222 +237,6 @@ public static IEnumerable ToEnumerable(this JSObject iterrator) } } - private static JSObject SetupListenerTest () { - var factory = new Function(@"return { - listeners: [], - eventFactory:function(data){ - return { - data:data - }; - }, - addEventListener: function (name, listener, options) { - if (name === 'throwError') - throw new Error('throwError throwing'); - var capture = !options ? false : !!options.capture; - for (var i = 0; i < this.listeners.length; i++) { - var item = this.listeners[i]; - if (item[0] !== name) - continue; - var itemCapture = !item[2] ? false : !!item[2].capture; - if (itemCapture !== capture) - continue; - if (item[1] === listener) - return; - } - this.listeners.push([name, listener, options || null]); - }, - removeEventListener: function (name, listener, capture) { - for (var i = 0; i < this.listeners.length; i++) { - var item = this.listeners[i]; - if (item[0] !== name) - continue; - if (item[1] !== listener) - continue; - var itemCapture = !item[2] ? false : !!item[2].capture; - if (itemCapture !== !!capture) - continue; - this.listeners.splice(i, 1); - return; - } - }, - fireEvent: function (name, evt) { - this._fireEventImpl(name, true, evt); - this._fireEventImpl(name, false, evt); - }, - _fireEventImpl: function (name, capture, evt) { - for (var i = 0; i < this.listeners.length; i++) { - var item = this.listeners[i]; - if (item[0] !== name) - continue; - var itemCapture = !item[2] ? false : (item[2].capture || false); - if (itemCapture !== capture) - continue; - item[1].call(this, evt); - } - }, -}; -"); - return (JSObject)factory.Call(); - } - - [Fact] - public static void AddEventListenerWorks () { - var temp = new bool[2]; - var obj = SetupListenerTest(); - obj.AddEventListener("test", (JSObject envt) => { - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }); - var evnt0 = obj.Invoke("eventFactory", 0); - var evnt1 = obj.Invoke("eventFactory", 1); - obj.Invoke("fireEvent", "test", evnt0); - obj.Invoke("fireEvent", "test", evnt1); - Assert.True(temp[0]); - Assert.True(temp[1]); - } - - [Fact] - public static void EventsAreNotCollected() - { - const int attempts = 100; // we fire 100 events in a loop, to try that it's GC same - var temp = new bool[100]; - var obj = SetupListenerTest(); - obj.AddEventListener("test", (JSObject envt) => { - var data = (int)envt.GetObjectProperty("data"); - temp[data] = true; - }); - var evnt = obj.Invoke("eventFactory", 0); - for (int i = 0; i < attempts; i++) - { - var evnti = obj.Invoke("eventFactory", 0); - obj.Invoke("fireEvent", "test", evnt); - obj.Invoke("fireEvent", "test", evnti); - // we are trying to test that managed side doesn't lose strong reference to evnt instance - Runtime.InvokeJS("if (globalThis.gc) globalThis.gc();");// needs v8 flag --expose-gc - GC.Collect(); - } - } - - [Fact] - public static void AddEventListenerPassesOptions () { - var log = new List(); - var obj = SetupListenerTest(); - obj.AddEventListener("test", (JSObject envt) => { - log.Add("Capture"); - }, new JSObject.EventListenerOptions { Capture = true }); - obj.AddEventListener("test", (JSObject envt) => { - log.Add("Non-capture"); - }, new JSObject.EventListenerOptions { Capture = false }); - obj.Invoke("fireEvent", "test"); - Assert.Equal("Capture", log[0]); - Assert.Equal("Non-capture", log[1]); - } - - [Fact] - public static void AddEventListenerForwardsExceptions () { - var obj = SetupListenerTest(); - obj.AddEventListener("test", (JSObject envt) => { - throw new Exception("Test exception"); - }); - var exc = Assert.Throws(() => { - obj.Invoke("fireEvent", "test"); - }); - Assert.Contains("Test exception", exc.Message); - - exc = Assert.Throws(() => { - obj.AddEventListener("throwError", (JSObject envt) => { - throw new Exception("Should not be called"); - }); - }); - Assert.Contains("throwError throwing", exc.Message); - obj.Invoke("fireEvent", "throwError"); - } - - [Fact] - public static void RemovedEventListenerIsNotCalled () { - var obj = SetupListenerTest(); - Action del = (JSObject envt) => { - throw new Exception("Should not be called"); - }; - obj.AddEventListener("test", del); - Assert.Throws(() => { - obj.Invoke("fireEvent", "test"); - }); - - obj.RemoveEventListener("test", del); - obj.Invoke("fireEvent", "test"); - } - - [Fact] - public static void RegisterSameEventListener () { - var counter = new int[1]; - var obj = SetupListenerTest(); - Action del = (JSObject envt) => { - counter[0]++; - }; - - obj.AddEventListener("test1", del); - obj.AddEventListener("test2", del); - - obj.Invoke("fireEvent", "test1"); - Assert.Equal(1, counter[0]); - obj.Invoke("fireEvent", "test2"); - Assert.Equal(2, counter[0]); - - obj.RemoveEventListener("test1", del); - obj.Invoke("fireEvent", "test1"); - obj.Invoke("fireEvent", "test2"); - Assert.Equal(3, counter[0]); - - obj.RemoveEventListener("test2", del); - obj.Invoke("fireEvent", "test1"); - obj.Invoke("fireEvent", "test2"); - Assert.Equal(3, counter[0]); - } - - [Fact] - public static void UseAddEventListenerResultToRemove () { - var obj = SetupListenerTest(); - Action del = (JSObject envt) => { - throw new Exception("Should not be called"); - }; - var handle = obj.AddEventListener("test", del); - Assert.Throws(() => { - obj.Invoke("fireEvent", "test"); - }); - - obj.RemoveEventListener("test", handle); - obj.Invoke("fireEvent", "test"); - } - - [Fact] - public static void RegisterSameEventListenerToMultipleSources () { - var counter = new int[1]; - var a = SetupListenerTest(); - var b = SetupListenerTest(); - Action del = (JSObject envt) => { - counter[0]++; - }; - - a.AddEventListener("test", del); - b.AddEventListener("test", del); - - a.Invoke("fireEvent", "test"); - Assert.Equal(1, counter[0]); - b.Invoke("fireEvent", "test"); - Assert.Equal(2, counter[0]); - - a.RemoveEventListener("test", del); - a.Invoke("fireEvent", "test"); - b.Invoke("fireEvent", "test"); - Assert.Equal(3, counter[0]); - - b.RemoveEventListener("test", del); - a.Invoke("fireEvent", "test"); - b.Invoke("fireEvent", "test"); - Assert.Equal(3, counter[0]); - } - [Fact] public static void RoundtripCSDate() { diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 5cd7d061b1b20f..7d9e9e0ffff9fa 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -54,8 +54,6 @@ const linked_functions = [ "mono_wasm_typed_array_copy_to_ref", "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", - "mono_wasm_add_event_listener", - "mono_wasm_remove_event_listener", "mono_wasm_cancel_promise", "mono_wasm_web_socket_open", "mono_wasm_web_socket_send", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index be072410d13cbf..e150af57bf1d61 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -22,8 +22,6 @@ extern void mono_wasm_typed_array_to_array_ref (int js_handle, int *is_exception extern void mono_wasm_typed_array_copy_to_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, 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_typed_array_copy_from_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception, MonoObject** result); -extern MonoString* mono_wasm_add_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int optionsObjHandle); -extern MonoString* mono_wasm_remove_event_listener (int jsObjHandle, MonoString *name, int weakDelegateHandle, int capture); extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exception); extern void mono_wasm_web_socket_open (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception, MonoObject **result); @@ -47,8 +45,6 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFromRef", mono_wasm_typed_array_copy_from_ref); mono_add_internal_call ("Interop/Runtime::CompileFunction", mono_wasm_compile_function); - mono_add_internal_call ("Interop/Runtime::AddEventListener", mono_wasm_add_event_listener); - mono_add_internal_call ("Interop/Runtime::RemoveEventListener", mono_wasm_remove_event_listener); mono_add_internal_call ("Interop/Runtime::WebSocketOpen", mono_wasm_web_socket_open); mono_add_internal_call ("Interop/Runtime::WebSocketSend", mono_wasm_web_socket_send); mono_add_internal_call ("Interop/Runtime::WebSocketReceive", mono_wasm_web_socket_receive); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 3c1eac4bd3e7f3..5790489294b158 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -91,8 +91,6 @@ const linked_functions = [ "mono_wasm_typed_array_copy_to_ref", "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", - "mono_wasm_add_event_listener", - "mono_wasm_remove_event_listener", "mono_wasm_cancel_promise", "mono_wasm_web_socket_open", "mono_wasm_web_socket_send", diff --git a/src/mono/wasm/runtime/event-listener.ts b/src/mono/wasm/runtime/event-listener.ts index ad46e8e704fc3f..64fc88067e484b 100644 --- a/src/mono/wasm/runtime/event-listener.ts +++ b/src/mono/wasm/runtime/event-listener.ts @@ -1,89 +1,4 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_root } from "./roots"; -import { isChromium, prevent_timer_throttling } from "./scheduling"; -import { JSHandle, GCHandle, MonoString, MonoStringNull } from "./types"; -import { _wrap_delegate_gc_handle_as_function } from "./cs-to-js"; -import { mono_wasm_get_jsobj_from_js_handle, _js_owned_object_finalized, _lookup_js_owned_object, _use_finalization_registry } from "./gc-handles"; -import { wrap_error } from "./method-calls"; -import { conv_string_root } from "./strings"; - -const listener_registration_count_symbol = Symbol.for("wasm listener_registration_count"); - -export function mono_wasm_add_event_listener(js_handle: JSHandle, name: MonoString, listener_gc_handle: GCHandle, optionsHandle: JSHandle): MonoString { - const nameRoot = mono_wasm_new_root(name); - try { - const sName = conv_string_root(nameRoot); - - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!obj) - throw new Error("ERR09: Invalid JS object handle for '" + sName + "'"); - - const throttling = isChromium || obj.constructor.name !== "WebSocket" - ? undefined - : prevent_timer_throttling; - - const listener = _wrap_delegate_gc_handle_as_function(listener_gc_handle, throttling) as ListenerExtension; - if (!listener) - throw new Error("ERR10: Invalid listener gc_handle"); - - const options = optionsHandle - ? mono_wasm_get_jsobj_from_js_handle(optionsHandle) - : null; - - if (!_use_finalization_registry) { - // we are counting registrations because same delegate could be registered into multiple sources - listener[listener_registration_count_symbol] = listener[listener_registration_count_symbol] ? listener[listener_registration_count_symbol] + 1 : 1; - } - - if (options) - obj.addEventListener(sName, listener, options); - else - obj.addEventListener(sName, listener); - return MonoStringNull; - } catch (ex) { - return wrap_error(null, ex); - } finally { - nameRoot.release(); - } -} - -export function mono_wasm_remove_event_listener(js_handle: JSHandle, name: MonoString, listener_gc_handle: GCHandle, capture: boolean): MonoString { - const nameRoot = mono_wasm_new_root(name); - try { - - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!obj) - throw new Error("ERR11: Invalid JS object handle"); - const listener = _lookup_js_owned_object(listener_gc_handle) as ListenerExtension; - // Removing a nonexistent listener should not be treated as an error - if (!listener) - return MonoStringNull; - const sName = conv_string_root(nameRoot); - - obj.removeEventListener(sName, listener, !!capture); - // We do not manually remove the listener from the delegate registry here, - // because that same delegate may have been used as an event listener for - // other events or event targets. The GC will automatically clean it up - // and trigger the FinalizationRegistry handler if it's unused - - // When FinalizationRegistry is not supported by this browser, we cleanup manuall after unregistration - if (!_use_finalization_registry) { - listener[listener_registration_count_symbol]--; - if (listener[listener_registration_count_symbol] === 0) { - _js_owned_object_finalized(listener_gc_handle); - } - } - - return MonoStringNull; - } catch (ex) { - return wrap_error(null, ex); - } finally { - nameRoot.release(); - } -} - -type ListenerExtension = Function & { - [listener_registration_count_symbol]: number -} \ No newline at end of file +// TODO: Remove this whole file \ No newline at end of file diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index c85c37a3720d3d..8ab96c7d49885b 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -51,7 +51,6 @@ import { } from "./method-calls"; import { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_load_bytes_into_heap } from "./buffers"; import { mono_wasm_cancel_promise } from "./cancelable-promise"; -import { mono_wasm_add_event_listener, mono_wasm_remove_event_listener } from "./event-listener"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; import { mono_wasm_web_socket_open, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close, mono_wasm_web_socket_abort } from "./web-socket"; import cwraps from "./cwraps"; @@ -299,8 +298,6 @@ export const __linker_exports: any = { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, - mono_wasm_add_event_listener, - mono_wasm_remove_event_listener, mono_wasm_cancel_promise, mono_wasm_web_socket_open, mono_wasm_web_socket_send, From ae8d4e9c6e1d826d2efdab3a2ef1848700550482 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 20:12:31 -0800 Subject: [PATCH 048/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 10 +- .../InteropServices/JavaScript/Array.cs | 4 +- .../InteropServices/JavaScript/JSObject.cs | 6 +- .../InteropServices/JavaScript/TypedArray.cs | 4 +- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 8 +- src/mono/wasm/runtime/corebindings.c | 16 +-- src/mono/wasm/runtime/dotnet.d.ts | 4 +- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 8 +- src/mono/wasm/runtime/exports.ts | 12 +- src/mono/wasm/runtime/method-calls.ts | 111 +++++++++++------- src/mono/wasm/runtime/roots.ts | 14 +-- 11 files changed, 110 insertions(+), 87 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index b13d01f38d687b..ec8ee68fca88ae 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -18,14 +18,16 @@ internal static partial class Runtime internal static extern object CompileFunction(string str, out int exceptionalResult); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern object InvokeJSWithArgs(int jsHandle, string method, object?[] parms, out int exceptionalResult); + // FIXME: All of these signatures need to be object? in various places and not object, but the nullability + // warnings will take me hours and hours to fix so I'm not doing that right now since they're already broken [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object GetObjectProperty(int jsHandle, string propertyName, out int exceptionalResult); + internal static extern void GetObjectPropertyRef(int jsHandle, string propertyName, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object SetObjectProperty(int jsHandle, string propertyName, object value, bool createIfNotExists, bool hasOwnProperty, out int exceptionalResult); + internal static extern void SetObjectPropertyRef(int jsHandle, string propertyName, in object? value, bool createIfNotExists, bool hasOwnProperty, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object GetByIndex(int jsHandle, int index, out int exceptionalResult); + internal static extern void GetByIndexRef(int jsHandle, int index, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object SetByIndex(int jsHandle, int index, object? value, out int exceptionalResult); + internal static extern void SetByIndexRef(int jsHandle, int index, in object? value, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern object GetGlobalObject(string? globalName, out int exceptionalResult); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs index cd13b0c110ec22..37bb3669654484 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Array.cs @@ -83,7 +83,7 @@ public object this[int i] { AssertNotDisposed(); - object indexValue = Interop.Runtime.GetByIndex(JSHandle, i, out int exception); + Interop.Runtime.GetByIndexRef(JSHandle, i, out int exception, out object indexValue); if (exception != 0) throw new JSException((string)indexValue); @@ -94,7 +94,7 @@ public object this[int i] { AssertNotDisposed(); - object res = Interop.Runtime.SetByIndex(JSHandle, i, value, out int exception); + Interop.Runtime.SetByIndexRef(JSHandle, i, value, out int exception, out object res); if (exception != 0) throw new JSException((string)res); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs index c0a0e87d3c3774..94ad98b8830de2 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/JSObject.cs @@ -71,7 +71,7 @@ public object GetObjectProperty(string name) { AssertNotDisposed(); - object propertyValue = Interop.Runtime.GetObjectProperty(JSHandle, name, out int exception); + Interop.Runtime.GetObjectPropertyRef(JSHandle, name, out int exception, out object propertyValue); if (exception != 0) throw new JSException((string)propertyValue); Interop.Runtime.ReleaseInFlight(propertyValue); @@ -93,9 +93,9 @@ public void SetObjectProperty(string name, object value, bool createIfNotExists { AssertNotDisposed(); - Interop.Runtime.SetObjectProperty(JSHandle, name, value, createIfNotExists, hasOwnProperty, out int exception); + Interop.Runtime.SetObjectPropertyRef(JSHandle, name, in value, createIfNotExists, hasOwnProperty, out int exception, out object res); if (exception != 0) - throw new JSException($"Error setting {name} on (js-obj js '{JSHandle}')"); + throw new JSException($"Error setting {name} on (js-obj js '{JSHandle}'): {res}"); } /// diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs index e99b1c2f02606d..59d27aeeed5f32 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/TypedArray.cs @@ -133,7 +133,7 @@ public U? this[int i] { AssertNotDisposed(); - object jsValue = Interop.Runtime.GetByIndex(JSHandle, i, out int exception); + Interop.Runtime.GetByIndexRef(JSHandle, i, out int exception, out object jsValue); if (exception != 0) throw new JSException((string)jsValue); @@ -145,7 +145,7 @@ public U? this[int i] { AssertNotDisposed(); - object res = Interop.Runtime.SetByIndex(JSHandle, i, value, out int exception); + Interop.Runtime.SetByIndexRef(JSHandle, i, value, out int exception, out object res); if (exception != 0) throw new JSException((string)res); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 7d9e9e0ffff9fa..fb8b4584fe32ec 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -43,10 +43,10 @@ const linked_functions = [ // corebindings.c "mono_wasm_invoke_js_with_args", - "mono_wasm_get_object_property", - "mono_wasm_set_object_property", - "mono_wasm_get_by_index", - "mono_wasm_set_by_index", + "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", "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index e150af57bf1d61..447e86265a21f0 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -11,10 +11,10 @@ //JS funcs extern MonoObject* mono_wasm_invoke_js_with_args (int js_handle, MonoString *method, MonoArray *args, int *is_exception); -extern MonoObject* mono_wasm_get_object_property (int js_handle, MonoString *propertyName, int *is_exception); -extern MonoObject* mono_wasm_get_by_index (int js_handle, int property_index, int *is_exception); -extern MonoObject* mono_wasm_set_object_property (int js_handle, MonoString *propertyName, MonoObject *value, int createIfNotExist, int hasOwnProperty, int *is_exception); -extern MonoObject* mono_wasm_set_by_index (int js_handle, int property_index, MonoObject *value, int *is_exception); +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 MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception); 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); @@ -33,10 +33,10 @@ extern MonoObject* mono_wasm_compile_function (MonoString *str, int *is_exceptio void core_initialize_internals () { mono_add_internal_call ("Interop/Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args); - mono_add_internal_call ("Interop/Runtime::GetObjectProperty", mono_wasm_get_object_property); - mono_add_internal_call ("Interop/Runtime::GetByIndex", mono_wasm_get_by_index); - mono_add_internal_call ("Interop/Runtime::SetObjectProperty", mono_wasm_set_object_property); - mono_add_internal_call ("Interop/Runtime::SetByIndex", mono_wasm_set_by_index); + mono_add_internal_call ("Interop/Runtime::GetObjectPropertyRef", mono_wasm_get_object_property_ref); + mono_add_internal_call ("Interop/Runtime::GetByIndexRef", mono_wasm_get_by_index_ref); + mono_add_internal_call ("Interop/Runtime::SetObjectPropertyRef", mono_wasm_set_object_property_ref); + mono_add_internal_call ("Interop/Runtime::SetByIndexRef", mono_wasm_set_by_index_ref); mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object); mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index d388159c65dab8..82267dff700602 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -71,7 +71,7 @@ declare function mono_wasm_new_root_buffer(capacity: number, name?: string): Was * The result object has get() and set(value) methods, along with a .value property. * When you are done using the root you must call its .release() method. */ -declare function mono_wasm_new_root(value?: T | undefined): WasmRoot; +declare function mono_wasm_new_root(value?: T | undefined): WasmRoot; /** * Releases 1 or more root or root buffer objects. * Multiple objects may be passed on the argument list. @@ -101,7 +101,7 @@ declare class WasmRootBuffer { release(): void; toString(): string; } -interface WasmRoot { +interface WasmRoot { get_address(): MonoObjectRef; get_address_32(): number; get address(): MonoObjectRef; diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 5790489294b158..0c8ec072aaf889 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -80,10 +80,10 @@ const linked_functions = [ // corebindings.c "mono_wasm_invoke_js_with_args", - "mono_wasm_get_object_property", - "mono_wasm_set_object_property", - "mono_wasm_get_by_index", - "mono_wasm_set_by_index", + "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", "mono_wasm_create_cs_owned_object_ref", "mono_wasm_release_cs_owned_object", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 8ab96c7d49885b..ef06592dae1527 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -44,10 +44,10 @@ import { call_static_method, mono_bind_static_method, mono_call_assembly_entry_point, mono_method_resolve, mono_wasm_compile_function, - mono_wasm_get_by_index, mono_wasm_get_global_object, mono_wasm_get_object_property, + mono_wasm_get_by_index_ref, mono_wasm_get_global_object, mono_wasm_get_object_property_ref, mono_wasm_invoke_js, mono_wasm_invoke_js_blazor, - mono_wasm_invoke_js_with_args, mono_wasm_set_by_index, mono_wasm_set_object_property + mono_wasm_invoke_js_with_args, mono_wasm_set_by_index_ref, mono_wasm_set_object_property_ref } from "./method-calls"; import { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_load_bytes_into_heap } from "./buffers"; import { mono_wasm_cancel_promise } from "./cancelable-promise"; @@ -287,10 +287,10 @@ export const __linker_exports: any = { // also keep in sync with corebindings.c mono_wasm_invoke_js_with_args, - mono_wasm_get_object_property, - mono_wasm_set_object_property, - mono_wasm_get_by_index, - mono_wasm_set_by_index, + 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, mono_wasm_create_cs_owned_object_ref, mono_wasm_release_cs_owned_object, diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 853bca45681125..64e5f524b9e00b 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.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 { mono_wasm_new_root, mono_wasm_new_root_buffer, WasmRoot, WasmRootBuffer } from "./roots"; +import { mono_wasm_new_root, mono_wasm_new_root_buffer, WasmRoot, WasmRootBuffer, mono_wasm_new_external_root } from "./roots"; import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, coerceNull as coerceNull, @@ -10,7 +10,7 @@ import { import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports"; import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js"; import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; -import { js_array_to_mono_array, _box_js_bool, _js_to_mono_obj_unsafe } from "./js-to-cs"; +import { js_array_to_mono_array, _js_to_mono_obj_unsafe, _js_to_mono_obj_root } from "./js-to-cs"; import { mono_bind_method, Converter, _compile_converter_for_marshal_string, @@ -117,7 +117,6 @@ function _convert_exception_for_method_call(result: WasmRoot, except if (exception.value === MonoObjectNull) return null; - // FIXME: rooted const msg = conv_string_root(result); const err = new Error(msg!); //the convention is that invoke_method ToString () any outgoing exception // console.warn (`error ${msg} at location ${err.stack}); @@ -202,10 +201,12 @@ function _handle_exception_and_produce_result_for_call( ): any { _handle_exception_for_call(converter, token, buffer, resultRoot, exceptionRoot, argsRootBuffer); - let result: any = resultRoot.value; + let result: any; if (is_result_marshaled) result = _unbox_mono_obj_root(resultRoot); + else + result = resultRoot.value; _teardown_after_call(converter, token, buffer, resultRoot, exceptionRoot, argsRootBuffer); return result; @@ -221,14 +222,14 @@ export function _teardown_after_call( _release_buffer_from_method_call(converter, token, buffer); if (resultRoot) { - resultRoot.value = 0; + resultRoot.clear(); if ((token !== null) && (token.scratchResultRoot === null)) token.scratchResultRoot = resultRoot; else resultRoot.release(); } if (exceptionRoot) { - exceptionRoot.value = 0; + exceptionRoot.clear(); if ((token !== null) && (token.scratchExceptionRoot === null)) token.scratchExceptionRoot = exceptionRoot; else @@ -327,43 +328,48 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: } } -export function mono_wasm_get_object_property(js_handle: JSHandle, property_name: MonoString, is_exception: Int32Ptr): any { - const nameRoot = mono_wasm_new_root(property_name); +export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoString, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const nameRoot = mono_wasm_new_root(property_name), + resultRoot = mono_wasm_new_external_root(result_address); try { const js_name = conv_string_root(nameRoot); if (!js_name) { - return wrap_error(is_exception, "Invalid property name object '" + nameRoot.value + "'"); + wrap_error_root(is_exception, "Invalid property name object '" + nameRoot.value + "'", resultRoot); + return; } const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); if (!obj) { - return wrap_error(is_exception, "ERR01: Invalid JS object handle '" + js_handle + "' while geting '" + js_name + "'"); + wrap_error_root(is_exception, "ERR01: Invalid JS object handle '" + js_handle + "' while geting '" + js_name + "'", resultRoot); + return; } - try { - const m = obj[js_name]; - - return _js_to_mono_obj_unsafe(true, m); - } catch (ex) { - return wrap_error(is_exception, ex); - } + const m = obj[js_name]; + _js_to_mono_obj_root(true, m, resultRoot); + } catch (ex) { + wrap_error_root(is_exception, ex, resultRoot); } finally { + resultRoot.release(); nameRoot.release(); } } -export function mono_wasm_set_object_property(js_handle: JSHandle, property_name: MonoString, value: MonoObject, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr): MonoObject { - const valueRoot = mono_wasm_new_root(value), nameRoot = mono_wasm_new_root(property_name); +export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoString, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const valueRoot = mono_wasm_new_external_root(value), + nameRoot = mono_wasm_new_root(property_name), + resultRoot = mono_wasm_new_external_root(result_address); try { const property = conv_string_root(nameRoot); if (!property) { - return wrap_error(is_exception, "Invalid property name object '" + property_name + "'"); + wrap_error_root(is_exception, "Invalid property name object '" + property_name + "'", resultRoot); + return; } const js_obj = mono_wasm_get_jsobj_from_js_handle(js_handle); if (!js_obj) { - return wrap_error(is_exception, "ERR02: Invalid JS object handle '" + js_handle + "' while setting '" + property + "'"); + wrap_error_root(is_exception, "ERR02: Invalid JS object handle '" + js_handle + "' while setting '" + property + "'", resultRoot); + return; } let result = false; @@ -377,8 +383,10 @@ export function mono_wasm_set_object_property(js_handle: JSHandle, property_name else { result = false; if (!createIfNotExist) { - if (!Object.prototype.hasOwnProperty.call(js_obj, property)) - return _box_js_bool(false); + if (!Object.prototype.hasOwnProperty.call(js_obj, property)) { + _js_to_mono_obj_root(false, false, resultRoot); + return; + } } if (hasOwnProperty === true) { if (Object.prototype.hasOwnProperty.call(js_obj, property)) { @@ -391,44 +399,51 @@ export function mono_wasm_set_object_property(js_handle: JSHandle, property_name result = true; } } - return _box_js_bool(result); + _js_to_mono_obj_root(false, result, resultRoot); + } catch (ex) { + wrap_error_root(is_exception, ex, resultRoot); } finally { + resultRoot.release(); nameRoot.release(); valueRoot.release(); } } -export function mono_wasm_get_by_index(js_handle: JSHandle, property_index: number, is_exception: Int32Ptr): MonoObject { - const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); - if (!obj) { - return wrap_error(is_exception, "ERR03: Invalid JS object handle '" + js_handle + "' while getting [" + property_index + "]"); - } - +export function mono_wasm_get_by_index_ref(js_handle: JSHandle, property_index: number, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const resultRoot = mono_wasm_new_external_root(result_address); try { + const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); + if (!obj) { + wrap_error_root(is_exception, "ERR03: Invalid JS object handle '" + js_handle + "' while getting [" + property_index + "]", resultRoot); + return; + } + const m = obj[property_index]; - return _js_to_mono_obj_unsafe(true, m); + _js_to_mono_obj_root(true, m, resultRoot); } catch (ex) { - return wrap_error(is_exception, ex); + wrap_error_root(is_exception, ex, resultRoot); + } finally { + resultRoot.release(); } } -export function mono_wasm_set_by_index(js_handle: JSHandle, property_index: number, value: MonoObject, is_exception: Int32Ptr): MonoString | true { - const valueRoot = mono_wasm_new_root(value); +export function mono_wasm_set_by_index_ref(js_handle: JSHandle, property_index: number, value: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const valueRoot = mono_wasm_new_external_root(value), + resultRoot = mono_wasm_new_external_root(result_address); try { const obj = mono_wasm_get_jsobj_from_js_handle(js_handle); if (!obj) { - return wrap_error(is_exception, "ERR04: Invalid JS object handle '" + js_handle + "' while setting [" + property_index + "]"); + wrap_error_root(is_exception, "ERR04: Invalid JS object handle '" + js_handle + "' while setting [" + property_index + "]", resultRoot); + return; } const js_value = _unbox_mono_obj_root(valueRoot); - - try { - obj[property_index] = js_value; - return true;// TODO check - } catch (ex) { - return wrap_error(is_exception, ex); - } + obj[property_index] = js_value; + resultRoot.clear(); + } catch (ex) { + wrap_error_root(is_exception, ex, resultRoot); } finally { + resultRoot.release(); valueRoot.release(); } } @@ -459,7 +474,7 @@ export function mono_wasm_get_global_object(global_name: MonoString, is_exceptio } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { +function _wrap_error_flag(is_exception: Int32Ptr | null, ex: any): string { let res = "unknown exception"; if (ex) { res = ex.toString(); @@ -476,13 +491,19 @@ export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { if (is_exception) { Module.setValue(is_exception, 1, "i32"); } + return res; +} + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { + const res = _wrap_error_flag(is_exception, ex); return js_string_to_mono_string(res)!; } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: WasmRoot): void { - // FIXME - result.value = wrap_error(is_exception, ex); + const res = _wrap_error_flag(is_exception, ex); + js_string_to_mono_string_root(res, result); } export function mono_method_get_call_signature(method: MonoMethod, mono_obj?: MonoObject): string/*ArgsMarshalString*/ { diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index 464b30e18c0245..70028815fe2e2d 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -4,7 +4,7 @@ import cwraps from "./cwraps"; import { Module } from "./imports"; import { VoidPtr, ManagedPointer, NativePointer } from "./types/emscripten"; -import { MonoObjectRef, MonoObjectRefNull } from "./types"; +import { MonoObjectRef, MonoObjectRefNull, MonoObject } from "./types"; const maxScratchRoots = 8192; let _scratch_root_buffer: WasmRootBuffer | null = null; @@ -58,7 +58,7 @@ export function mono_wasm_new_root_buffer_from_pointer(offset: VoidPtr, capacity * Allocates a WasmRoot pointing to a root provided and controlled by external code. Typicaly on managed stack. * Releasing this root will not de-allocate the root space. You still need to call .release(). */ -export function mono_wasm_new_external_root(address: VoidPtr | MonoObjectRef): WasmRoot { +export function mono_wasm_new_external_root(address: VoidPtr | MonoObjectRef): WasmRoot { let result: WasmExternalRoot; if (!address) @@ -81,7 +81,7 @@ export function mono_wasm_new_external_root(value: T | undefined = undefined): WasmRoot { +export function mono_wasm_new_root(value: T | undefined = undefined): WasmRoot { let result: WasmRoot; if (_scratch_root_free_instances.length > 0) { @@ -111,7 +111,7 @@ export function mono_wasm_new_root(val * mono_wasm_new_roots([a, b, ...]) returns an array of new roots initialized with each element. * Each root must be released with its release method, or using the mono_wasm_release_roots API. */ -export function mono_wasm_new_roots(count_or_values: number | T[]): WasmRoot[] { +export function mono_wasm_new_roots(count_or_values: number | T[]): WasmRoot[] { let result; if (Array.isArray(count_or_values)) { @@ -266,7 +266,7 @@ export class WasmRootBuffer { } } -export interface WasmRoot { +export interface WasmRoot { get_address(): MonoObjectRef; get_address_32(): number; get address(): MonoObjectRef; @@ -284,7 +284,7 @@ export interface WasmRoot { toString(): string; } -class WasmJsOwnedRoot implements WasmRoot { +class WasmJsOwnedRoot implements WasmRoot { private __buffer: WasmRootBuffer; private __index: number; @@ -374,7 +374,7 @@ class WasmJsOwnedRoot implements WasmR } } -class WasmExternalRoot implements WasmRoot { +class WasmExternalRoot implements WasmRoot { private __external_address: MonoObjectRef = MonoObjectRefNull; private __external_address_32: number = 0; From dd9836b63b52f06a488604e06f782cb0dad9026a Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 20:28:57 -0800 Subject: [PATCH 049/128] Checkpoint --- .../src/Interop/Browser/Interop.Runtime.cs | 8 +++---- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 2 +- src/mono/wasm/runtime/corebindings.c | 8 +++---- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 +- src/mono/wasm/runtime/exports.ts | 4 ++-- src/mono/wasm/runtime/method-calls.ts | 21 ++++++++++++------- 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index ec8ee68fca88ae..cfedbdb1645d77 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -21,15 +21,15 @@ internal static partial class Runtime // FIXME: All of these signatures need to be object? in various places and not object, but the nullability // warnings will take me hours and hours to fix so I'm not doing that right now since they're already broken [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void GetObjectPropertyRef(int jsHandle, string propertyName, out int exceptionalResult, out object result); + internal static extern void GetObjectPropertyRef(int jsHandle, in string propertyName, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void SetObjectPropertyRef(int jsHandle, string propertyName, in object? value, bool createIfNotExists, bool hasOwnProperty, out int exceptionalResult, out object result); + internal static extern void SetObjectPropertyRef(int jsHandle, in string propertyName, in object? value, bool createIfNotExists, bool hasOwnProperty, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void GetByIndexRef(int jsHandle, int index, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void SetByIndexRef(int jsHandle, int index, in object? value, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern object GetGlobalObject(string? globalName, out int exceptionalResult); + internal static extern void GetGlobalObjectRef(in string? globalName, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void ReleaseCSOwnedObject(int jsHandle); @@ -82,7 +82,7 @@ public static string InvokeJS(string str) public static object GetGlobalObject(string? str = null) { int exception; - object jsObj = GetGlobalObject(str, out exception); + GetGlobalObjectRef(str, out exception, out object jsObj); if (exception != 0) throw new JSException($"Error obtaining a handle to global {str}"); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index fb8b4584fe32ec..78fb318ecea69f 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -47,7 +47,7 @@ const linked_functions = [ "mono_wasm_set_object_property_ref", "mono_wasm_get_by_index_ref", "mono_wasm_set_by_index_ref", - "mono_wasm_get_global_object", + "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", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 447e86265a21f0..4c970add26b522 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -11,11 +11,11 @@ //JS funcs extern MonoObject* mono_wasm_invoke_js_with_args (int js_handle, MonoString *method, MonoArray *args, int *is_exception); -extern void mono_wasm_get_object_property_ref (int js_handle, MonoString *propertyName, 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_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 MonoObject* mono_wasm_get_global_object (MonoString *global_name, int *is_exception); +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); @@ -37,7 +37,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::GetByIndexRef", mono_wasm_get_by_index_ref); mono_add_internal_call ("Interop/Runtime::SetObjectPropertyRef", mono_wasm_set_object_property_ref); mono_add_internal_call ("Interop/Runtime::SetByIndexRef", mono_wasm_set_by_index_ref); - mono_add_internal_call ("Interop/Runtime::GetGlobalObject", mono_wasm_get_global_object); + mono_add_internal_call ("Interop/Runtime::GetGlobalObjectRef", mono_wasm_get_global_object_ref); mono_add_internal_call ("Interop/Runtime::CreateCSOwnedObjectRef", mono_wasm_create_cs_owned_object_ref); mono_add_internal_call ("Interop/Runtime::ReleaseCSOwnedObject", mono_wasm_release_cs_owned_object); mono_add_internal_call ("Interop/Runtime::TypedArrayToArrayRef", mono_wasm_typed_array_to_array_ref); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 0c8ec072aaf889..86ff4037170a0f 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -84,7 +84,7 @@ const linked_functions = [ "mono_wasm_set_object_property_ref", "mono_wasm_get_by_index_ref", "mono_wasm_set_by_index_ref", - "mono_wasm_get_global_object", + "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", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index ef06592dae1527..9b15df6be3f8e2 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -44,7 +44,7 @@ import { call_static_method, mono_bind_static_method, mono_call_assembly_entry_point, mono_method_resolve, mono_wasm_compile_function, - mono_wasm_get_by_index_ref, mono_wasm_get_global_object, mono_wasm_get_object_property_ref, + mono_wasm_get_by_index_ref, mono_wasm_get_global_object_ref, mono_wasm_get_object_property_ref, mono_wasm_invoke_js, mono_wasm_invoke_js_blazor, mono_wasm_invoke_js_with_args, mono_wasm_set_by_index_ref, mono_wasm_set_object_property_ref @@ -291,7 +291,7 @@ export const __linker_exports: any = { mono_wasm_set_object_property_ref, mono_wasm_get_by_index_ref, mono_wasm_set_by_index_ref, - mono_wasm_get_global_object, + 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, diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 64e5f524b9e00b..7af5a4639696ff 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -328,8 +328,8 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: } } -export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoString, is_exception: Int32Ptr, result_address: MonoObjectRef): void { - const nameRoot = mono_wasm_new_root(property_name), +export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address); try { const js_name = conv_string_root(nameRoot); @@ -354,9 +354,9 @@ export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_ } } -export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoString, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoObjectRef, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const valueRoot = mono_wasm_new_external_root(value), - nameRoot = mono_wasm_new_root(property_name), + nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address); try { @@ -448,8 +448,9 @@ export function mono_wasm_set_by_index_ref(js_handle: JSHandle, property_index: } } -export function mono_wasm_get_global_object(global_name: MonoString, is_exception: Int32Ptr): MonoObject { - const nameRoot = mono_wasm_new_root(global_name); +export function mono_wasm_get_global_object_ref(global_name: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { + const nameRoot = mono_wasm_new_external_root(global_name), + resultRoot = mono_wasm_new_external_root(result_address); try { const js_name = conv_string_root(nameRoot); @@ -464,11 +465,15 @@ export function mono_wasm_get_global_object(global_name: MonoString, is_exceptio // TODO returning null may be useful when probing for browser features if (globalObj === null || typeof globalObj === undefined) { - return wrap_error(is_exception, "Global object '" + js_name + "' not found."); + wrap_error_root(is_exception, "Global object '" + js_name + "' not found.", resultRoot); + return; } - return _js_to_mono_obj_unsafe(true, globalObj); + _js_to_mono_obj_root(true, globalObj, resultRoot); + } catch (ex) { + wrap_error_root(is_exception, ex, resultRoot); } finally { + resultRoot.release(); nameRoot.release(); } } From da0011cb36c0e7fa10f29969dcb96647cd8328b0 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 20:48:05 -0800 Subject: [PATCH 050/128] Checkpoint --- .../Common/src/Interop/Browser/Interop.Runtime.cs | 2 +- src/mono/wasm/runtime/corebindings.c | 2 +- src/mono/wasm/runtime/cs-to-js.ts | 8 ++++---- src/mono/wasm/runtime/cwraps.ts | 6 +++--- src/mono/wasm/runtime/dotnet.d.ts | 6 +++--- src/mono/wasm/runtime/memory.ts | 2 +- src/mono/wasm/runtime/method-calls.ts | 9 +++++---- src/mono/wasm/runtime/roots.ts | 4 ++-- src/mono/wasm/runtime/types.ts | 13 +++++++++++-- 9 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index cfedbdb1645d77..511857be4eeb38 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -34,7 +34,7 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void ReleaseCSOwnedObject(int jsHandle); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void CreateCSOwnedObjectRef(string className, object[] parms, out int exceptionalResult, out object result); + internal static extern void CreateCSOwnedObjectRef(in string className, object[] parms, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void TypedArrayToArrayRef(int jsHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 4c970add26b522..5985db7f8aa0de 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -17,7 +17,7 @@ extern void mono_wasm_set_object_property_ref (int js_handle, MonoString **prope 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_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_copy_to_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, 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); diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index e33e0f9635793a..f3f984fc14b735 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -5,14 +5,14 @@ import { mono_wasm_new_root, WasmRoot, mono_wasm_new_external_root } from "./roo import { GCHandle, JSHandleDisposed, MarshalError, MarshalType, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, MonoString, - MonoType, MonoTypeNull, MonoObjectRef + MonoType, MonoTypeNull, MonoObjectRef, MonoStringRef } from "./types"; import { runtimeHelpers } from "./imports"; import { conv_string_root } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; -import { mono_method_get_call_signature, call_method, wrap_error, wrap_error_root } from "./method-calls"; +import { mono_method_get_call_signature, call_method, wrap_error_root } from "./method-calls"; import { _js_to_mono_obj_root } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; import { getU32, getI32, getF32, getF64 } from "./memory"; @@ -235,9 +235,9 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ return result; } -export function mono_wasm_create_cs_owned_object_ref(core_name: MonoString, args: MonoArray, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_create_cs_owned_object_ref(core_name: MonoStringRef, args: MonoArray, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const argsRoot = mono_wasm_new_root(args), - nameRoot = mono_wasm_new_root(core_name), + nameRoot = mono_wasm_new_external_root(core_name), resultRoot = mono_wasm_new_external_root(result_address); try { const js_name = conv_string_root(nameRoot); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 04b76adf7bd02e..0c501e8d320f6c 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -4,7 +4,7 @@ import { MonoArray, MonoAssembly, MonoClass, MonoMethod, MonoObject, MonoString, - MonoType, MonoObjectRef + MonoType, MonoObjectRef, MonoStringRef } from "./types"; import { Module } from "./imports"; import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr } from "./types/emscripten"; @@ -78,7 +78,7 @@ export interface t_Cwraps { // MONO mono_wasm_register_root(start: VoidPtr, size: number, name: string): number; mono_wasm_deregister_root(addr: VoidPtr): void; - mono_wasm_string_get_data_ref(stringRef: MonoObjectRef, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; + mono_wasm_string_get_data_ref(stringRef: MonoStringRef, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; mono_wasm_set_is_debugger_attached(value: boolean): void; mono_wasm_send_dbg_command(id: number, command_set: number, command: number, data: VoidPtr, size: number): boolean; mono_wasm_send_dbg_command_with_parms(id: number, command_set: number, command: number, data: VoidPtr, size: number, valtype: number, newvalue: string): boolean; @@ -116,7 +116,7 @@ export interface t_Cwraps { 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: MonoObjectRef): void; + mono_wasm_intern_string_ref(strRef: MonoStringRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; mono_wasm_typed_array_new(arr: VoidPtr, length: number, size: number, type: number): MonoArray; diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 82267dff700602..4975fd98213366 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -128,8 +128,8 @@ interface MonoString extends MonoObject { interface MonoArray extends MonoObject { __brand: "MonoArray"; } -interface MonoObjectRef extends NativePointer { - __brandMonoObject: "MonoObjectRef"; +interface MonoObjectRef extends ManagedPointer { + __brandMonoObjectRef: "MonoObjectRef"; } declare type MonoConfig = { isError: false; @@ -259,7 +259,7 @@ declare function mono_call_assembly_entry_point(assembly: string, args?: any[], declare function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr; -declare type _MemOffset = number | VoidPtr | NativePointer; +declare type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer; declare type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer; declare function setU8(offset: _MemOffset, value: number): void; declare function setU16(offset: _MemOffset, value: number): void; diff --git a/src/mono/wasm/runtime/memory.ts b/src/mono/wasm/runtime/memory.ts index c8760a0c7a994f..b61b379e87e8c5 100644 --- a/src/mono/wasm/runtime/memory.ts +++ b/src/mono/wasm/runtime/memory.ts @@ -37,7 +37,7 @@ export function _release_temp_frame(): void { alloca_offset = alloca_stack.pop(); } -type _MemOffset = number | VoidPtr | NativePointer; +type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer; type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer; export function setU8(offset: _MemOffset, value: number): void { diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 7af5a4639696ff..18b27ae957622a 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -5,7 +5,8 @@ import { mono_wasm_new_root, mono_wasm_new_root_buffer, WasmRoot, WasmRootBuffer import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, coerceNull as coerceNull, - VoidPtrNull, MonoStringNull, MonoObjectRef, MonoObjectRefNull + VoidPtrNull, MonoStringNull, MonoObjectRef, MonoObjectRefNull, + MonoStringRef } from "./types"; import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports"; import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js"; @@ -328,7 +329,7 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: } } -export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_name: MonoStringRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address); try { @@ -354,7 +355,7 @@ export function mono_wasm_get_object_property_ref(js_handle: JSHandle, property_ } } -export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoObjectRef, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_set_object_property_ref(js_handle: JSHandle, property_name: MonoStringRef, value: MonoObjectRef, createIfNotExist: boolean, hasOwnProperty: boolean, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const valueRoot = mono_wasm_new_external_root(value), nameRoot = mono_wasm_new_external_root(property_name), resultRoot = mono_wasm_new_external_root(result_address); @@ -448,7 +449,7 @@ export function mono_wasm_set_by_index_ref(js_handle: JSHandle, property_index: } } -export function mono_wasm_get_global_object_ref(global_name: MonoObjectRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_get_global_object_ref(global_name: MonoStringRef, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const nameRoot = mono_wasm_new_external_root(global_name), resultRoot = mono_wasm_new_external_root(result_address); try { diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts index 70028815fe2e2d..47693fcea2447b 100644 --- a/src/mono/wasm/runtime/roots.ts +++ b/src/mono/wasm/runtime/roots.ts @@ -378,11 +378,11 @@ class WasmExternalRoot implements WasmRoot { private __external_address: MonoObjectRef = MonoObjectRefNull; private __external_address_32: number = 0; - constructor(address: NativePointer) { + constructor(address: NativePointer | ManagedPointer) { this._set_address(address); } - _set_address(address: NativePointer): void { + _set_address(address: NativePointer | ManagedPointer): void { this.__external_address = address; this.__external_address_32 = address >>> 2; } diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index 2ddd6ed4ea0282..dffc588db97fec 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -16,6 +16,9 @@ export interface MonoObject extends ManagedPointer { export interface MonoString extends MonoObject { __brand: "MonoString" } +export interface MonoInternedString extends MonoString { + __brandString: "MonoInternedString" +} export interface MonoClass extends MonoObject { __brand: "MonoClass" } @@ -32,8 +35,13 @@ export interface MonoAssembly extends MonoObject { __brand: "MonoAssembly" } // Pointer to a MonoObject* (i.e. the address of a root) -export interface MonoObjectRef extends NativePointer { - __brandMonoObject: "MonoObjectRef" +export interface MonoObjectRef extends ManagedPointer { + __brandMonoObjectRef: "MonoObjectRef" +} +// This exists for signature clarity, we need it to be structurally equivalent +// so that anything requiring MonoObjectRef will work +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface MonoStringRef extends MonoObjectRef { } export const MonoMethodNull: MonoMethod = 0; export const MonoObjectNull: MonoObject = 0; @@ -43,6 +51,7 @@ export const MonoClassNull: MonoClass = 0; export const MonoTypeNull: MonoType = 0; export const MonoStringNull: MonoString = 0; export const MonoObjectRefNull: MonoObjectRef = 0; +export const MonoStringRefNull: MonoStringRef = 0; export const JSHandleDisposed: JSHandle = -1; export const JSHandleNull: JSHandle = 0; export const VoidPtrNull: VoidPtr = 0; From dbed6881f7e773096af75c92a51f6a1a4fd536d3 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 9 Mar 2022 21:53:19 -0800 Subject: [PATCH 051/128] eslint fixes --- src/mono/wasm/runtime/buffers.ts | 2 +- src/mono/wasm/runtime/corebindings.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/runtime/buffers.ts b/src/mono/wasm/runtime/buffers.ts index 46ab25f82774ee..8f42a57bcb3d62 100644 --- a/src/mono/wasm/runtime/buffers.ts +++ b/src/mono/wasm/runtime/buffers.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 { JSHandle, MonoArray, MonoObject, MonoString, MonoObjectRef } from "./types"; +import { JSHandle, MonoArray, MonoObject, MonoObjectRef } from "./types"; import { Module } from "./imports"; import { mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; import { wrap_error_root } from "./method-calls"; diff --git a/src/mono/wasm/runtime/corebindings.ts b/src/mono/wasm/runtime/corebindings.ts index 1782c52f4150d8..82be21ce2a2ade 100644 --- a/src/mono/wasm/runtime/corebindings.ts +++ b/src/mono/wasm/runtime/corebindings.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 { JSHandle, GCHandle, MonoObject, MonoObjectRef } from "./types"; +import { JSHandle, GCHandle, MonoObjectRef } from "./types"; import { PromiseControl } from "./cancelable-promise"; import { runtimeHelpers } from "./imports"; From 002f60dc3ffbbb48dd6e76f4b4da53301edc33e6 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 14 Mar 2022 12:55:53 -0700 Subject: [PATCH 052/128] Checkpoint --- src/mono/wasm/runtime/cwraps.ts | 3 ++- src/mono/wasm/runtime/js-to-cs.ts | 10 ++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 0c501e8d320f6c..470d9e6ec5be43 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -107,7 +107,6 @@ export interface t_Cwraps { mono_wasm_invoke_method_ref(method: MonoMethod, this_arg: MonoObjectRef, params: VoidPtr, out_exc: MonoObjectRef, out_result: MonoObjectRef): void; mono_wasm_string_get_utf8(str: MonoString): CharPtr; mono_wasm_string_from_utf16_ref(str: CharPtr, len: number, result: MonoObjectRef): void; - mono_wasm_get_obj_type(str: MonoObject): number; mono_wasm_array_length(array: MonoArray): number; mono_wasm_array_get_ref(array: MonoObjectRef, idx: number, result: MonoObjectRef): void; @@ -126,6 +125,8 @@ export interface t_Cwraps { mono_wasm_get_type_name(ty: MonoType): string; mono_wasm_get_type_aqn(ty: MonoType): string; + // Deprecated + mono_wasm_get_obj_type(str: MonoObject): number; // Deprecated mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; // Deprecated diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 5e90485a993358..db0dd89bd06184 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -93,8 +93,8 @@ export function _js_to_mono_obj_root(should_add_in_flight: boolean, js_obj: any, js_string_to_mono_string_interned_root(js_obj, result); return; case typeof js_obj === "boolean": - // FIXME - result.value = _box_js_bool(js_obj); + setI32(runtimeHelpers._box_buffer, js_obj ? 1 : 0); + cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4, result.address); return; case isThenable(js_obj) === true: { _wrap_js_thenable_as_task_root(js_obj, result); @@ -143,12 +143,6 @@ function _extract_mono_obj_root(should_add_in_flight: boolean, js_obj: any, resu } } -export function _box_js_bool(js_obj: boolean): MonoObject { - setI32(runtimeHelpers._box_buffer, js_obj ? 1 : 0); - cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4, runtimeHelpers._box_root.address); - return runtimeHelpers._box_root.value; -} - // https://github.com/Planeshifter/emscripten-examples/blob/master/01_PassingArrays/sum_post.js function js_typedarray_to_heap(typedArray: TypedArray) { const numBytes = typedArray.length * typedArray.BYTES_PER_ELEMENT; From c261e3421a29754b30d9c3e5e2423d81c6c0ffd1 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 14 Mar 2022 13:11:37 -0700 Subject: [PATCH 053/128] Update call_method signature to avoid passing raw object pointers --- src/mono/wasm/runtime/cs-to-js.ts | 4 +- src/mono/wasm/runtime/method-calls.ts | 65 ++++++++++++++------------- src/mono/wasm/runtime/web-socket.ts | 3 ++ 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index f3f984fc14b735..05c99b4980ea65 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -12,7 +12,7 @@ import { conv_string_root } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; -import { mono_method_get_call_signature, call_method, wrap_error_root } from "./method-calls"; +import { mono_method_get_call_signature, call_method_ref, wrap_error_root } from "./method-calls"; import { _js_to_mono_obj_root } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; import { getU32, getI32, getF32, getF64 } from "./memory"; @@ -193,7 +193,7 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ get_js_owned_object_by_gc_handle_ref(gc_handle, delegateRoot.address); try { // FIXME: Pass delegateRoot by-ref - const res = call_method(result[delegate_invoke_symbol], delegateRoot.value, result[delegate_invoke_signature_symbol], args); + const res = call_method_ref(result[delegate_invoke_symbol], delegateRoot, result[delegate_invoke_signature_symbol], args); if (after_listener_callback) { after_listener_callback(); } diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 18b27ae957622a..8c510f2de36110 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -124,7 +124,6 @@ function _convert_exception_for_method_call(result: WasmRoot, except return err; } - /* args_marshal is a string with one character per parameter that tells how to marshal it, here are the valid values: @@ -141,43 +140,45 @@ m: raw mono object. Don't use it unless you know what you're doing to suppress marshaling of the return value, place '!' at the end of args_marshal, i.e. 'ii!' instead of 'ii' */ -export function call_method(method: MonoMethod, this_arg: MonoObject | undefined, args_marshal: string/*ArgsMarshalString*/, args: ArrayLike): any { +export function call_method_ref(method: MonoMethod, this_arg: WasmRoot | MonoObjectRef | undefined, args_marshal: string/*ArgsMarshalString*/, args: ArrayLike): any { // HACK: Sometimes callers pass null or undefined, coerce it to 0 since that's what wasm expects - this_arg = coerceNull(this_arg); - const this_arg_root = this_arg ? mono_wasm_new_root(this_arg) : null; - const this_arg_ref = this_arg ? (this_arg_root).address : MonoObjectRefNull; - try { - // Detect someone accidentally passing the wrong type of value to method - if (typeof method !== "number") - throw new Error(`method must be an address in the native heap, but was '${method}'`); - if (!method) - throw new Error("no method specified"); + let this_arg_ref : MonoObjectRef | undefined = undefined; + if (typeof (this_arg) === "number") + this_arg_ref = this_arg; + else if (typeof (this_arg) === "object") + this_arg_ref = (this_arg).address; + else + this_arg_ref = coerceNull(this_arg); - const needs_converter = _verify_args_for_method_call(args_marshal, args); + // Detect someone accidentally passing the wrong type of value to method + if (typeof method !== "number") + throw new Error(`method must be an address in the native heap, but was '${method}'`); + if (!method) + throw new Error("no method specified"); + if (typeof (this_arg_ref) !== "number") + throw new Error(`this_arg must be a root instance, the address of a root, or undefined, but was ${this_arg}`); - let buffer = VoidPtrNull, converter = undefined, argsRootBuffer = undefined; - let is_result_marshaled = true; + const needs_converter = _verify_args_for_method_call(args_marshal, args); - // TODO: Only do this if the signature needs marshalling - _create_temp_frame(); + let buffer = VoidPtrNull, converter = undefined, argsRootBuffer = undefined; + let is_result_marshaled = true; - // check if the method signature needs argument mashalling - if (needs_converter) { - converter = _compile_converter_for_marshal_string(args_marshal); + // TODO: Only do this if the signature needs marshalling + _create_temp_frame(); - is_result_marshaled = _decide_if_result_is_marshaled(converter, args.length); + // check if the method signature needs argument mashalling + if (needs_converter) { + converter = _compile_converter_for_marshal_string(args_marshal); - argsRootBuffer = _get_args_root_buffer_for_method_call(converter, null); + is_result_marshaled = _decide_if_result_is_marshaled(converter, args.length); - const scratchBuffer = _get_buffer_for_method_call(converter, null); + argsRootBuffer = _get_args_root_buffer_for_method_call(converter, null); - buffer = converter.compiled_variadic_function!(scratchBuffer, argsRootBuffer, method, args); - } - return _call_method_with_converted_args(method, this_arg_ref, converter, null, buffer, is_result_marshaled, argsRootBuffer); - } finally { - if (this_arg_root) - this_arg_root.release(); + const scratchBuffer = _get_buffer_for_method_call(converter, null); + + buffer = converter.compiled_variadic_function!(scratchBuffer, argsRootBuffer, method, args); } + return _call_method_with_converted_args(method, this_arg_ref, converter, null, buffer, is_result_marshaled, argsRootBuffer); } @@ -244,7 +245,6 @@ function _call_method_with_converted_args( is_result_marshaled: boolean, argsRootBuffer?: WasmRootBuffer ): any { const resultRoot = mono_wasm_new_root(), exceptionRoot = mono_wasm_new_root(); - // TODO: Create new invoke_method variant that writes the result into resultRoot directly cwraps.mono_wasm_invoke_method_ref(method, this_arg_ref, buffer, exceptionRoot.address, resultRoot.address); return _handle_exception_and_produce_result_for_call(converter, token, buffer, resultRoot, exceptionRoot, argsRootBuffer, is_result_marshaled); } @@ -257,7 +257,7 @@ export function call_static_method(fqn: string, args: any[], signature: string/* if (typeof signature === "undefined") signature = mono_method_get_call_signature(method); - return call_method(method, undefined, signature, args); + return call_method_ref(method, undefined, signature, args); } export function mono_bind_static_method(fqn: string, signature?: string/*ArgsMarshalString*/): Function { @@ -288,7 +288,7 @@ export function mono_bind_assembly_entry_point(assembly: string, signature?: str return async function (...args: any[]) { if (args.length > 0 && Array.isArray(args[0])) args[0] = js_array_to_mono_array(args[0], true, false); - return call_method(method, undefined, signature!, args); + return call_method_ref(method, undefined, signature!, args); }; } @@ -512,10 +512,11 @@ export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: js_string_to_mono_string_root(res, result); } +// fixme: ref export function mono_method_get_call_signature(method: MonoMethod, mono_obj?: MonoObject): string/*ArgsMarshalString*/ { const instanceRoot = mono_wasm_new_root(mono_obj); try { - return call_method(runtimeHelpers.get_call_sig, undefined, "im", [method, instanceRoot.value]); + return call_method_ref(runtimeHelpers.get_call_sig, undefined, "im", [method, instanceRoot.value]); } finally { instanceRoot.release(); } diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 55a3464aacbcea..338220d00684dc 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -29,6 +29,7 @@ let _text_encoder_utf8: TextEncoder | undefined = undefined; const ws_send_buffer_blocking_threshold = 65536; const emptyBuffer = new Uint8Array(); +// fixme: ref export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArray, on_close: MonoObject, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); const uri_root = mono_wasm_new_root(uri); @@ -108,6 +109,7 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr } } +// fixme: ref export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); const buffer_root = mono_wasm_new_root(buffer_ptr); @@ -137,6 +139,7 @@ export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ } } +// fixme: ref export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, response_ptr: MonoObject, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); const buffer_root = mono_wasm_new_root(buffer_ptr); From faa94e970394cc0afdba4f435eeb3991e02b1652 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 14 Mar 2022 14:04:42 -0700 Subject: [PATCH 054/128] Ref-ify one websocket API and fix types and incorrect rooting of two others --- .../src/Interop/Browser/Interop.Runtime.cs | 3 +- .../InteropServices/JavaScript/Runtime.cs | 2 +- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 2 +- src/mono/wasm/runtime/corebindings.c | 4 +- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 +- src/mono/wasm/runtime/exports.ts | 4 +- src/mono/wasm/runtime/method-binding.ts | 8 +-- src/mono/wasm/runtime/web-socket.ts | 63 +++++++++---------- 8 files changed, 39 insertions(+), 49 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index 511857be4eeb38..e289dd6f3ab67e 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -44,12 +44,13 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void TypedArrayCopyFromRef(int jsHandle, int arrayPtr, int begin, int end, int bytesPerElement, out int exceptionalResult, out object result); + // FIXME: Why are these IntPtr? [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketSend(int webSocketJSHandle, IntPtr messagePtr, int offset, int length, int messageType, bool endOfMessage, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketReceive(int webSocketJSHandle, IntPtr bufferPtr, int offset, int length, IntPtr responsePtr, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void WebSocketOpen(string uri, object[]? subProtocols, Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult, out object result); + internal static extern void WebSocketOpenRef(string uri, object[]? subProtocols, in Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketAbort(int webSocketJSHandle, out int exceptionalResult, out string result); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index 95dc24cce1792f..075d22e1d4667e 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -336,7 +336,7 @@ public static void CancelPromise(int promiseJSHandle) public static Task WebSocketOpen(string uri, object[]? subProtocols, Delegate onClosed, out JSObject webSocket, out int promiseJSHandle) { - Interop.Runtime.WebSocketOpen(uri, subProtocols, onClosed, out int webSocketJSHandle, out promiseJSHandle, out int exception, out object res); + Interop.Runtime.WebSocketOpenRef(uri, subProtocols, onClosed, out int webSocketJSHandle, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); webSocket = new JSObject((IntPtr)webSocketJSHandle); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 78fb318ecea69f..cd8268dcb6aff6 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -55,7 +55,7 @@ const linked_functions = [ "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", "mono_wasm_cancel_promise", - "mono_wasm_web_socket_open", + "mono_wasm_web_socket_open_ref", "mono_wasm_web_socket_send", "mono_wasm_web_socket_receive", "mono_wasm_web_socket_close", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 5985db7f8aa0de..c38f3174be2396 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -23,7 +23,7 @@ extern void mono_wasm_typed_array_copy_to_ref (int js_handle, int ptr, int begin 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_typed_array_copy_from_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception, MonoObject** result); extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exception); -extern void mono_wasm_web_socket_open (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_open_ref (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_close (int webSocket_js_handle, int code, MonoString * reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); @@ -45,7 +45,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::TypedArrayFromRef", mono_wasm_typed_array_from_ref); mono_add_internal_call ("Interop/Runtime::TypedArrayCopyFromRef", mono_wasm_typed_array_copy_from_ref); mono_add_internal_call ("Interop/Runtime::CompileFunction", mono_wasm_compile_function); - mono_add_internal_call ("Interop/Runtime::WebSocketOpen", mono_wasm_web_socket_open); + mono_add_internal_call ("Interop/Runtime::WebSocketOpenRef", mono_wasm_web_socket_open_ref); mono_add_internal_call ("Interop/Runtime::WebSocketSend", mono_wasm_web_socket_send); mono_add_internal_call ("Interop/Runtime::WebSocketReceive", mono_wasm_web_socket_receive); mono_add_internal_call ("Interop/Runtime::WebSocketClose", mono_wasm_web_socket_close); diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 86ff4037170a0f..1c38b5afb73c5f 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -92,7 +92,7 @@ const linked_functions = [ "mono_wasm_typed_array_from_ref", "mono_wasm_typed_array_copy_from_ref", "mono_wasm_cancel_promise", - "mono_wasm_web_socket_open", + "mono_wasm_web_socket_open_ref", "mono_wasm_web_socket_send", "mono_wasm_web_socket_receive", "mono_wasm_web_socket_close", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 9b15df6be3f8e2..d7cbb6622c368b 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -52,7 +52,7 @@ import { import { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_load_bytes_into_heap } from "./buffers"; import { mono_wasm_cancel_promise } from "./cancelable-promise"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; -import { mono_wasm_web_socket_open, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close, mono_wasm_web_socket_abort } from "./web-socket"; +import { mono_wasm_web_socket_open_ref, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close, mono_wasm_web_socket_abort } from "./web-socket"; import cwraps from "./cwraps"; import { setI8, setI16, setI32, setI64, @@ -299,7 +299,7 @@ export const __linker_exports: any = { mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_cancel_promise, - mono_wasm_web_socket_open, + mono_wasm_web_socket_open_ref, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close, diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 8fd8848b128b23..a82404ff552203 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -389,11 +389,9 @@ export function _decide_if_result_is_marshaled(converter: Converter, argc: numbe } } -export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null, args_marshal: string/*ArgsMarshalString*/, friendly_name: string): Function { +export function mono_bind_method(method: MonoMethod, this_arg: null, args_marshal: string/*ArgsMarshalString*/, friendly_name: string): Function { if (typeof (args_marshal) !== "string") throw new Error("args_marshal argument invalid, expected string"); - this_arg = coerceNull(this_arg); - const this_arg_root = this_arg ? mono_wasm_new_root(this_arg) : null; let converter: Converter | null = null; if (typeof (args_marshal) === "string") { @@ -425,7 +423,6 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null _unbox_mono_obj_root_with_known_nonprimitive_type, invoke_method_ref: cwraps.mono_wasm_invoke_method_ref, method, - this_arg_root, token, unbox_buffer, unbox_buffer_size, @@ -498,8 +495,7 @@ export function mono_bind_method(method: MonoMethod, this_arg: MonoObject | null // The end result is that bound method invocations don't always allocate, so no more nursery GCs. Yay! -kg body.push( "", - // TODO: Create new invoke_method variant that writes the result into resultRoot directly - "invoke_method_ref (method, this_arg_root ? this_arg_root.address : 0, buffer, exceptionRoot.address, resultRoot.address);", + "invoke_method_ref (method, 0, buffer, exceptionRoot.address, resultRoot.address);", `_handle_exception_for_call (${converterKey}, token, buffer, resultRoot, exceptionRoot, argsRootBuffer);`, "", "let resultPtr = resultRoot.value, result = undefined;" diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 338220d00684dc..62b9841b73eb98 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -1,7 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -import { mono_wasm_new_root, WasmRoot, mono_wasm_new_external_root } from "./roots"; +import { mono_wasm_new_root, mono_wasm_new_external_root } from "./roots"; +import { setI32 } from "./memory"; import { prevent_timer_throttling } from "./scheduling"; import { Queue } from "./queue"; import { PromiseControl, _create_cancelable_promise } from "./cancelable-promise"; @@ -12,7 +13,7 @@ import { wrap_error_root } from "./method-calls"; import { conv_string_root } from "./strings"; import { JSHandle, MonoArray, MonoObject, MonoString, MonoObjectRef } from "./types"; import { Module } from "./imports"; -import { Int32Ptr } from "./types/emscripten"; +import { Int32Ptr, VoidPtr } from "./types/emscripten"; const wasm_ws_pending_send_buffer = Symbol.for("wasm ws_pending_send_buffer"); const wasm_ws_pending_send_buffer_offset = Symbol.for("wasm ws_pending_send_buffer_offset"); @@ -30,11 +31,12 @@ const ws_send_buffer_blocking_threshold = 65536; const emptyBuffer = new Uint8Array(); // fixme: ref -export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArray, on_close: MonoObject, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_web_socket_open_ref(uri: MonoString, subProtocols: MonoArray, on_close: MonoObjectRef, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); const uri_root = mono_wasm_new_root(uri); const sub_root = mono_wasm_new_root(subProtocols); - const on_close_root = mono_wasm_new_root(on_close); + const on_close_root = mono_wasm_new_root(); + on_close_root.copy_from_address(on_close); try { const js_uri = conv_string_root(uri_root); if (!js_uri) { @@ -80,10 +82,10 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr // send close to any pending receivers, to wake them const receive_promise_queue = ws[wasm_ws_pending_receive_promise_queue]; receive_promise_queue.drain((receive_promise_control) => { - const response_root = receive_promise_control.response_root; - Module.setValue(response_root.value + 0, 0, "i32");// count - Module.setValue(response_root.value + 4, 2, "i32");// type:close - Module.setValue(response_root.value + 8, 1, "i32");// end_of_message: true + const response_ptr = receive_promise_control.response_ptr; + setI32(response_ptr + 0, 0);// count + setI32(response_ptr + 4, 2);// type:close + setI32(response_ptr + 8, 1);// end_of_message: true receive_promise_control.resolve(null); }); }; @@ -110,9 +112,8 @@ export function mono_wasm_web_socket_open(uri: MonoString, subProtocols: MonoArr } // fixme: ref -export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: VoidPtr, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); - const buffer_root = mono_wasm_new_root(buffer_ptr); try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle); if (!ws) @@ -122,7 +123,7 @@ export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ throw new Error("InvalidState: The WebSocket is not connected."); } - const whole_buffer = _mono_wasm_web_socket_send_buffering(ws, buffer_root, offset, length, message_type, end_of_message); + const whole_buffer = _mono_wasm_web_socket_send_buffering(ws, buffer_ptr, offset, length, message_type, end_of_message); if (!end_of_message || !whole_buffer) { result_root.clear(); // we are done buffering synchronously, no promise @@ -135,19 +136,12 @@ export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ } finally { result_root.release(); - buffer_root.release(); } } // fixme: ref -export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: MonoObject, offset: number, length: number, response_ptr: MonoObject, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: VoidPtr, offset: number, length: number, response_ptr: VoidPtr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); - const buffer_root = mono_wasm_new_root(buffer_ptr); - const response_root = mono_wasm_new_root(response_ptr); - const release_buffer = () => { - buffer_root.release(); - response_root.release(); - }; try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle); @@ -166,19 +160,18 @@ export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buff throw new Error("ERR20: Invalid WS state");// assert } // finish synchronously - _mono_wasm_web_socket_receive_buffering(receive_event_queue, buffer_root, offset, length, response_root); - release_buffer(); + _mono_wasm_web_socket_receive_buffering(receive_event_queue, buffer_ptr, offset, length, response_ptr); Module.setValue(thenable_js_handle, 0, "i32"); result_root.clear(); return; } - const { promise, promise_control } = _create_cancelable_promise(release_buffer, release_buffer); + const { promise, promise_control } = _create_cancelable_promise(undefined, undefined); const receive_promise_control = promise_control as ReceivePromiseControl; - receive_promise_control.buffer_root = buffer_root; + receive_promise_control.buffer_ptr = buffer_ptr; receive_promise_control.buffer_offset = offset; receive_promise_control.buffer_length = length; - receive_promise_control.response_root = response_root; + receive_promise_control.response_ptr = response_ptr; receive_promise_queue.enqueue(receive_promise_control); const { then_js_handle } = _wrap_js_thenable_as_task_root(promise, result_root); @@ -371,19 +364,19 @@ function _mono_wasm_web_socket_on_message(ws: WebSocketExtension, event: Message while (promise_queue.getLength() && event_queue.getLength()) { const promise_control = promise_queue.dequeue()!; _mono_wasm_web_socket_receive_buffering(event_queue, - promise_control.buffer_root, promise_control.buffer_offset, promise_control.buffer_length, - promise_control.response_root); + promise_control.buffer_ptr, promise_control.buffer_offset, promise_control.buffer_length, + promise_control.response_ptr); promise_control.resolve(null); } prevent_timer_throttling(); } -function _mono_wasm_web_socket_receive_buffering(event_queue: Queue, buffer_root: WasmRoot, buffer_offset: number, buffer_length: number, response_root: WasmRoot) { +function _mono_wasm_web_socket_receive_buffering(event_queue: Queue, buffer_ptr: VoidPtr, buffer_offset: number, buffer_length: number, response_ptr: VoidPtr) { const event = event_queue.peek(); const count = Math.min(buffer_length, event.data.length - event.offset); if (count > 0) { - const targetView = Module.HEAPU8.subarray(buffer_root.value + buffer_offset, buffer_root.value + buffer_offset + buffer_length); + const targetView = Module.HEAPU8.subarray(buffer_ptr + buffer_offset, buffer_ptr + buffer_offset + buffer_length); const sourceView = event.data.subarray(event.offset, event.offset + count); targetView.set(sourceView, 0); event.offset += count; @@ -392,15 +385,15 @@ function _mono_wasm_web_socket_receive_buffering(event_queue: Queue, buffer if (end_of_message) { event_queue.dequeue(); } - Module.setValue(response_root.value + 0, count, "i32"); - Module.setValue(response_root.value + 4, event.type, "i32"); - Module.setValue(response_root.value + 8, end_of_message, "i32"); + setI32(response_ptr + 0, count); + setI32(response_ptr + 4, event.type); + setI32(response_ptr + 8, end_of_message); } -function _mono_wasm_web_socket_send_buffering(ws: WebSocketExtension, buffer_root: WasmRoot, buffer_offset: number, length: number, message_type: number, end_of_message: boolean): Uint8Array | string | null { +function _mono_wasm_web_socket_send_buffering(ws: WebSocketExtension, buffer_ptr: VoidPtr, buffer_offset: number, length: number, message_type: number, end_of_message: boolean): Uint8Array | string | null { let buffer = ws[wasm_ws_pending_send_buffer]; let offset = 0; - const message_ptr = buffer_root.value + buffer_offset; + const message_ptr = buffer_ptr + buffer_offset; if (buffer) { offset = ws[wasm_ws_pending_send_buffer_offset]; @@ -479,8 +472,8 @@ type WebSocketExtension = WebSocket & { } type ReceivePromiseControl = PromiseControl & { - response_root: WasmRoot - buffer_root: WasmRoot + response_ptr: VoidPtr + buffer_ptr: VoidPtr buffer_offset: number buffer_length: number } From ef58f32aeaf6e76fc820b4d3067c84ccc77f05df Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Mon, 14 Mar 2022 15:36:00 -0700 Subject: [PATCH 055/128] Checkpoint --- .../InteropServices/JavaScript/Runtime.cs | 2 +- src/mono/wasm/runtime/cs-to-js.ts | 4 ++-- src/mono/wasm/runtime/method-calls.ts | 18 ++++++++---------- src/mono/wasm/runtime/startup.ts | 7 ++++--- src/mono/wasm/runtime/types.ts | 4 +++- 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index 075d22e1d4667e..0b13a8454541f0 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -100,7 +100,7 @@ public enum MarshalError : int FIRST = BUFFER_TOO_SMALL } - public static string GetCallSignature(IntPtr _methodHandle, object? objForRuntimeType) + public static string GetCallSignatureRef(IntPtr _methodHandle, in object? objForRuntimeType) { var methodHandle = GetMethodHandleFromIntPtr(_methodHandle); diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 05c99b4980ea65..cf8c8d17ec1142 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -12,7 +12,7 @@ import { conv_string_root } from "./strings"; import corebindings from "./corebindings"; import cwraps from "./cwraps"; import { get_js_owned_object_by_gc_handle_ref, js_owned_gc_handle_symbol, mono_wasm_get_jsobj_from_js_handle, mono_wasm_get_js_handle, _js_owned_object_finalized, _js_owned_object_registry, _lookup_js_owned_object, _register_js_owned_object, _use_finalization_registry } from "./gc-handles"; -import { mono_method_get_call_signature, call_method_ref, wrap_error_root } from "./method-calls"; +import { mono_method_get_call_signature_ref, call_method_ref, wrap_error_root } from "./method-calls"; import { _js_to_mono_obj_root } from "./js-to-cs"; import { _are_promises_supported, _create_cancelable_promise } from "./cancelable-promise"; import { getU32, getI32, getF32, getF64 } from "./memory"; @@ -215,7 +215,7 @@ export function _wrap_delegate_gc_handle_as_function(gc_handle: GCHandle, after_ } if (typeof result[delegate_invoke_signature_symbol] === "undefined") { - result[delegate_invoke_signature_symbol] = mono_method_get_call_signature(result[delegate_invoke_symbol], delegateRoot.value); + result[delegate_invoke_signature_symbol] = mono_method_get_call_signature_ref(result[delegate_invoke_symbol], delegateRoot); } } finally { delegateRoot.release(); diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 8c510f2de36110..0f379e9b5c39bc 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -255,7 +255,7 @@ export function call_static_method(fqn: string, args: any[], signature: string/* const method = mono_method_resolve(fqn); if (typeof signature === "undefined") - signature = mono_method_get_call_signature(method); + signature = mono_method_get_call_signature_ref(method, undefined); return call_method_ref(method, undefined, signature, args); } @@ -266,7 +266,7 @@ export function mono_bind_static_method(fqn: string, signature?: string/*ArgsMar const method = mono_method_resolve(fqn); if (typeof signature === "undefined") - signature = mono_method_get_call_signature(method); + signature = mono_method_get_call_signature_ref(method, undefined); return mono_bind_method(method, null, signature!, fqn); } @@ -283,7 +283,7 @@ export function mono_bind_assembly_entry_point(assembly: string, signature?: str throw new Error("Could not find entry point for assembly: " + assembly); if (!signature) - signature = mono_method_get_call_signature(method); + signature = mono_method_get_call_signature_ref(method, undefined); return async function (...args: any[]) { if (args.length > 0 && Array.isArray(args[0])) @@ -513,13 +513,11 @@ export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: } // fixme: ref -export function mono_method_get_call_signature(method: MonoMethod, mono_obj?: MonoObject): string/*ArgsMarshalString*/ { - const instanceRoot = mono_wasm_new_root(mono_obj); - try { - return call_method_ref(runtimeHelpers.get_call_sig, undefined, "im", [method, instanceRoot.value]); - } finally { - instanceRoot.release(); - } +export function mono_method_get_call_signature_ref(method: MonoMethod, mono_obj?: WasmRoot): string/*ArgsMarshalString*/ { + return call_method_ref( + runtimeHelpers.get_call_sig_ref, undefined, "im", + [method, mono_obj ? mono_obj.address : runtimeHelpers._null_root.address] + ); } export function mono_method_resolve(fqn: string): MonoMethod { diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 5d5ed98117bae8..ea6dda4d2b3d1b 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -397,13 +397,14 @@ export function bindings_lazy_init(): void { if (!runtimeHelpers.wasm_runtime_class) throw "Can't find " + binding_fqn_class + " class"; - runtimeHelpers.get_call_sig = get_method("GetCallSignature"); - if (!runtimeHelpers.get_call_sig) - throw "Can't find GetCallSignature method"; + runtimeHelpers.get_call_sig_ref = get_method("GetCallSignatureRef"); + if (!runtimeHelpers.get_call_sig_ref) + throw "Can't find GetCallSignatureRef method"; _create_primitive_converters(); runtimeHelpers._box_root = mono_wasm_new_root(); + runtimeHelpers._null_root = mono_wasm_new_root(); } // Initializes the runtime and loads assemblies, debug information, and other files. diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts index dffc588db97fec..10257e4b9fe1f6 100644 --- a/src/mono/wasm/runtime/types.ts +++ b/src/mono/wasm/runtime/types.ts @@ -127,7 +127,7 @@ export const enum AssetBehaviours { } export type RuntimeHelpers = { - get_call_sig: MonoMethod; + get_call_sig_ref: MonoMethod; runtime_namespace: string; runtime_classname: string; wasm_runtime_class: MonoClass; @@ -139,6 +139,8 @@ export type RuntimeHelpers = { _box_buffer: VoidPtr; _unbox_buffer: VoidPtr; _box_root: any; + // A WasmRoot that is guaranteed to contain 0 + _null_root: any; _class_int32: MonoClass; _class_uint32: MonoClass; _class_double: MonoClass; From e864fa8cbd71494461aea787d85e22a3ce92d1a9 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 10:59:24 -0700 Subject: [PATCH 056/128] Deprecation metadata --- src/mono/wasm/runtime/cwraps.ts | 24 ++++++++++++++++++------ src/mono/wasm/runtime/exports.ts | 16 ++++++++++++---- src/mono/wasm/runtime/js-to-cs.ts | 4 +++- src/mono/wasm/runtime/method-calls.ts | 9 ++++++++- src/mono/wasm/runtime/strings.ts | 12 +++++++++--- 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 470d9e6ec5be43..e37f56df3e95b9 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -93,7 +93,9 @@ export interface t_Cwraps { mono_wasm_add_satellite_assembly(name: string, culture: string, data: VoidPtr, size: number): void; mono_wasm_load_runtime(unused: string, debug_level: number): void; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_string_get_data(string: MonoString, outChars: CharPtrPtr, outLengthBytes: Int32Ptr, outIsInterned: Int32Ptr): void; // BINDING @@ -125,15 +127,25 @@ export interface t_Cwraps { mono_wasm_get_type_name(ty: MonoType): string; mono_wasm_get_type_aqn(ty: MonoType): string; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_get_obj_type(str: MonoObject): number; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_invoke_method(method: MonoMethod, this_arg: MonoObject, params: VoidPtr, out_exc: MonoObjectRef): MonoObject; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_obj_array_new(size: number): MonoArray; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_array_get(array: MonoArray, idx: number): MonoObject; - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; //DOTNET diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index d7cbb6622c368b..ffb73caf9888f9 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -111,17 +111,25 @@ export type MONOType = typeof MONO; const BINDING = { //current "public" BINDING API - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_obj_array_new: cwraps.mono_wasm_obj_array_new, - // Deprecated + /** + * @deprecated Not GC or thread safe + */ mono_obj_array_set: cwraps.mono_wasm_obj_array_set, - // Deprecated + /** + * @deprecated Not GC or thread safe + */ js_string_to_mono_string, js_typed_array_to_array, js_to_mono_obj, mono_array_to_js_array, conv_string, - // Deprecated name + /** + * @deprecated Renamed to conv_string_root + */ conv_string_rooted: conv_string_root, conv_string_root, bind_static_method: mono_bind_static_method, diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index db0dd89bd06184..b225e60d61c0f2 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -48,7 +48,9 @@ export function js_to_mono_obj(js_obj: any): MonoObject { } } -// Deprecated +/** + * @deprecated Not GC or thread safe + */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function _js_to_mono_obj_unsafe(should_add_in_flight: boolean, js_obj: any): MonoObject { const temp = mono_wasm_new_root(); diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 0f379e9b5c39bc..a56c190e59612a 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -5,12 +5,14 @@ import { mono_wasm_new_root, mono_wasm_new_root_buffer, WasmRoot, WasmRootBuffer import { JSHandle, MonoArray, MonoMethod, MonoObject, MonoObjectNull, MonoString, coerceNull as coerceNull, - VoidPtrNull, MonoStringNull, MonoObjectRef, MonoObjectRefNull, + VoidPtrNull, MonoStringNull, MonoObjectRef, MonoStringRef } from "./types"; import { BINDING, INTERNAL, Module, MONO, runtimeHelpers } from "./imports"; import { _mono_array_root_to_js_array, _unbox_mono_obj_root } from "./cs-to-js"; import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "./gc-handles"; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore used by unsafe export import { js_array_to_mono_array, _js_to_mono_obj_unsafe, _js_to_mono_obj_root } from "./js-to-cs"; import { mono_bind_method, @@ -319,6 +321,9 @@ export function mono_wasm_invoke_js_with_args(js_handle: JSHandle, method_name: if (typeof m === "undefined") throw new Error("Method: '" + js_name + "' not found for: '" + Object.prototype.toString.call(obj) + "'"); const res = m.apply(obj, js_args); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore caller is unsafe also return _js_to_mono_obj_unsafe(true, res); } catch (ex) { return wrap_error(is_exception, ex); @@ -618,6 +623,8 @@ export function mono_wasm_compile_function(code: MonoString, is_exception: Int32 if (!res || typeof res !== "function") return wrap_error(is_exception, "Code must return an instance of a JavaScript function. Please use `return` statement to return a function."); Module.setValue(is_exception, 0, "i32"); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore caller is unsafe also return _js_to_mono_obj_unsafe(true, res); } catch (ex) { return wrap_error(is_exception, ex); diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 35b82206cbd414..9391151c67f043 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -226,7 +226,9 @@ export function js_string_to_mono_string_new_root(string: string, result: WasmRo Module._free(buffer); } -// Deprecated +/** + * @deprecated Not GC or thread safe + */ export function js_string_to_mono_string_interned(string: string | symbol): MonoString { const temp = mono_wasm_new_root(); try { @@ -237,7 +239,9 @@ export function js_string_to_mono_string_interned(string: string | symbol): Mono } } -// Deprecated +/** + * @deprecated Not GC or thread safe + */ export function js_string_to_mono_string(string: string): MonoString { const temp = mono_wasm_new_root(); try { @@ -248,7 +252,9 @@ export function js_string_to_mono_string(string: string): MonoString { } } -// Deprecated +/** + * @deprecated Not GC or thread safe + */ export function js_string_to_mono_string_new(string: string): MonoString { const temp = mono_wasm_new_root(); try { From 7a80489c08c0cb50900ead97062457ac8d1e7833 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 11:18:58 -0700 Subject: [PATCH 057/128] More ref --- .../src/Interop/Browser/Interop.Runtime.cs | 2 +- src/mono/wasm/runtime/corebindings.c | 2 +- src/mono/wasm/runtime/cwraps.ts | 6 ++++++ src/mono/wasm/runtime/dotnet.d.ts | 18 ++++++++++++++++++ src/mono/wasm/runtime/method-calls.ts | 3 +++ src/mono/wasm/runtime/strings.ts | 6 ++++++ src/mono/wasm/runtime/web-socket.ts | 7 +++---- 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index e289dd6f3ab67e..d3f9acf41ab938 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -50,7 +50,7 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketReceive(int webSocketJSHandle, IntPtr bufferPtr, int offset, int length, IntPtr responsePtr, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void WebSocketOpenRef(string uri, object[]? subProtocols, in Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult, out object result); + internal static extern void WebSocketOpenRef(in string uri, in object[]? subProtocols, in Delegate onClosed, out int webSocketJSHandle, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketAbort(int webSocketJSHandle, out int exceptionalResult, out string result); [MethodImplAttribute(MethodImplOptions.InternalCall)] diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index c38f3174be2396..3bf4a0746cc5c2 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -23,7 +23,7 @@ extern void mono_wasm_typed_array_copy_to_ref (int js_handle, int ptr, int begin 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_typed_array_copy_from_ref (int js_handle, int ptr, int begin, int end, int bytes_per_element, int *is_exception, MonoObject** result); extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exception); -extern void mono_wasm_web_socket_open_ref (MonoString *uri, MonoArray *subProtocols, MonoDelegate *on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_open_ref (MonoString **uri, MonoArray **subProtocols, MonoDelegate **on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_close (int webSocket_js_handle, int code, MonoString * reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index e37f56df3e95b9..a14d8b0869b110 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -107,6 +107,9 @@ export interface t_Cwraps { 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; @@ -149,6 +152,9 @@ export interface t_Cwraps { mono_wasm_obj_array_set(array: MonoArray, idx: number, obj: MonoObject): void; //DOTNET + /** + * @deprecated Not GC or thread safe + */ mono_wasm_string_from_js(str: string): MonoString; //INTERNAL diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 4975fd98213366..4e90bae840f0a4 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -244,8 +244,14 @@ declare function mono_wasm_load_config(configFilePath: string): Promise; declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean; +/** + * @deprecated Not GC or thread safe + */ declare function conv_string(mono_obj: MonoString): string | null; declare function conv_string_root(root: WasmRoot): string | null; +/** + * @deprecated Not GC or thread safe + */ declare function js_string_to_mono_string(string: string): MonoString; declare function js_to_mono_obj(js_obj: any): MonoObject; @@ -321,13 +327,25 @@ declare const MONO: { }; declare type MONOType = typeof MONO; declare const BINDING: { + /** + * @deprecated Not GC or thread safe + */ mono_obj_array_new: (size: number) => MonoArray; + /** + * @deprecated Not GC or thread safe + */ mono_obj_array_set: (array: MonoArray, idx: number, obj: MonoObject) => void; + /** + * @deprecated Not GC or thread safe + */ js_string_to_mono_string: typeof js_string_to_mono_string; js_typed_array_to_array: typeof js_typed_array_to_array; js_to_mono_obj: typeof js_to_mono_obj; mono_array_to_js_array: typeof mono_array_to_js_array; conv_string: typeof conv_string; + /** + * @deprecated Renamed to conv_string_root + */ conv_string_rooted: typeof conv_string_root; conv_string_root: typeof conv_string_root; bind_static_method: typeof mono_bind_static_method; diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index a56c190e59612a..fe2f1bf2eb9b36 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -505,6 +505,9 @@ function _wrap_error_flag(is_exception: Int32Ptr | null, ex: any): string { return res; } +/** + * @deprecated Not GC or thread safe + */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function wrap_error(is_exception: Int32Ptr | null, ex: any): MonoString { const res = _wrap_error_flag(is_exception, ex); diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index 9391151c67f043..76f0110a491b36 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.ts @@ -23,6 +23,9 @@ export class StringDecoder { } } + /** + * @deprecated Not GC or thread safe + */ copy(mono_string: MonoString): string | null { this.init_fields(); if (mono_string === MonoStringNull) @@ -100,6 +103,9 @@ let _interned_string_current_root_buffer_count = 0; export const string_decoder = new StringDecoder(); export const mono_wasm_empty_string = ""; +/** + * @deprecated Not GC or thread safe + */ export function conv_string(mono_obj: MonoString): string | null { return string_decoder.copy(mono_obj); } diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 62b9841b73eb98..aa4d4a06cce52b 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -30,11 +30,10 @@ let _text_encoder_utf8: TextEncoder | undefined = undefined; const ws_send_buffer_blocking_threshold = 65536; const emptyBuffer = new Uint8Array(); -// fixme: ref -export function mono_wasm_web_socket_open_ref(uri: MonoString, subProtocols: MonoArray, on_close: MonoObjectRef, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_web_socket_open_ref(uri_address: MonoObjectRef, subProtocols: MonoObjectRef, on_close: MonoObjectRef, web_socket_js_handle: Int32Ptr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); - const uri_root = mono_wasm_new_root(uri); - const sub_root = mono_wasm_new_root(subProtocols); + const uri_root = mono_wasm_new_external_root(uri_address); + const sub_root = mono_wasm_new_external_root(subProtocols); const on_close_root = mono_wasm_new_root(); on_close_root.copy_from_address(on_close); try { From 5563e014257b91bea958fcc0c4e576f333369c90 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 11:36:06 -0700 Subject: [PATCH 058/128] More ref --- src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs | 2 +- .../src/System/Runtime/InteropServices/JavaScript/Runtime.cs | 2 +- src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 2 +- src/mono/wasm/runtime/corebindings.c | 4 ++-- src/mono/wasm/runtime/es6/dotnet.es6.lib.js | 2 +- src/mono/wasm/runtime/exports.ts | 4 ++-- src/mono/wasm/runtime/web-socket.ts | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs index d3f9acf41ab938..a023bdcbf54d3b 100644 --- a/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs +++ b/src/libraries/Common/src/Interop/Browser/Interop.Runtime.cs @@ -54,7 +54,7 @@ internal static partial class Runtime [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern void WebSocketAbort(int webSocketJSHandle, out int exceptionalResult, out string result); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern void WebSocketClose(int webSocketJSHandle, int code, string? reason, bool waitForCloseReceived, out int promiseJSHandle, out int exceptionalResult, out object result); + internal static extern void WebSocketCloseRef(int webSocketJSHandle, int code, in string? reason, bool waitForCloseReceived, out int promiseJSHandle, out int exceptionalResult, out object result); [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern string CancelPromise(int promiseJSHandle, out int exceptionalResult); diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs index 0b13a8454541f0..2d9b1e355ce171 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.cs @@ -379,7 +379,7 @@ public static Task WebSocketOpen(string uri, object[]? subProtocols, Del public static Task? WebSocketClose(JSObject webSocket, int code, string? reason, bool waitForCloseReceived, out int promiseJSHandle) { - Interop.Runtime.WebSocketClose(webSocket.JSHandle, code, reason, waitForCloseReceived, out promiseJSHandle, out int exception, out object res); + Interop.Runtime.WebSocketCloseRef(webSocket.JSHandle, code, reason, waitForCloseReceived, out promiseJSHandle, out int exception, out object res); if (exception != 0) throw new JSException((string)res); diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index cd8268dcb6aff6..5946cdf6af6673 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -58,7 +58,7 @@ const linked_functions = [ "mono_wasm_web_socket_open_ref", "mono_wasm_web_socket_send", "mono_wasm_web_socket_receive", - "mono_wasm_web_socket_close", + "mono_wasm_web_socket_close_ref", "mono_wasm_web_socket_abort", "mono_wasm_compile_function", diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 3bf4a0746cc5c2..2ff78e26bc04e9 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -26,7 +26,7 @@ extern MonoString* mono_wasm_cancel_promise (int thenable_js_handle, int *is_exc extern void mono_wasm_web_socket_open_ref (MonoString **uri, MonoArray **subProtocols, MonoDelegate **on_close, int *web_socket_js_handle, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_send (int webSocket_js_handle, void* buffer_ptr, int offset, int length, int message_type, int end_of_message, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_receive (int webSocket_js_handle, void* buffer_ptr, int offset, int length, void* response_ptr, int *thenable_js_handle, int *is_exception, MonoObject **result); -extern void mono_wasm_web_socket_close (int webSocket_js_handle, int code, MonoString * reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); +extern void mono_wasm_web_socket_close_ref (int webSocket_js_handle, int code, MonoString **reason, int wait_for_close_received, int *thenable_js_handle, int *is_exception, MonoObject **result); extern void mono_wasm_web_socket_abort (int webSocket_js_handle, int *is_exception, MonoString **result); extern MonoObject* mono_wasm_compile_function (MonoString *str, int *is_exception); @@ -48,7 +48,7 @@ void core_initialize_internals () mono_add_internal_call ("Interop/Runtime::WebSocketOpenRef", mono_wasm_web_socket_open_ref); mono_add_internal_call ("Interop/Runtime::WebSocketSend", mono_wasm_web_socket_send); mono_add_internal_call ("Interop/Runtime::WebSocketReceive", mono_wasm_web_socket_receive); - mono_add_internal_call ("Interop/Runtime::WebSocketClose", mono_wasm_web_socket_close); + mono_add_internal_call ("Interop/Runtime::WebSocketCloseRef", mono_wasm_web_socket_close_ref); mono_add_internal_call ("Interop/Runtime::WebSocketAbort", mono_wasm_web_socket_abort); mono_add_internal_call ("Interop/Runtime::CancelPromise", mono_wasm_cancel_promise); } diff --git a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js index 1c38b5afb73c5f..77e32203281b05 100644 --- a/src/mono/wasm/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/wasm/runtime/es6/dotnet.es6.lib.js @@ -95,7 +95,7 @@ const linked_functions = [ "mono_wasm_web_socket_open_ref", "mono_wasm_web_socket_send", "mono_wasm_web_socket_receive", - "mono_wasm_web_socket_close", + "mono_wasm_web_socket_close_ref", "mono_wasm_web_socket_abort", "mono_wasm_compile_function", diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index ffb73caf9888f9..38fcd2a8e026d7 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -52,7 +52,7 @@ import { import { mono_wasm_typed_array_copy_to_ref, mono_wasm_typed_array_from_ref, mono_wasm_typed_array_copy_from_ref, mono_wasm_load_bytes_into_heap } from "./buffers"; import { mono_wasm_cancel_promise } from "./cancelable-promise"; import { mono_wasm_release_cs_owned_object } from "./gc-handles"; -import { mono_wasm_web_socket_open_ref, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close, mono_wasm_web_socket_abort } from "./web-socket"; +import { mono_wasm_web_socket_open_ref, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, mono_wasm_web_socket_close_ref, mono_wasm_web_socket_abort } from "./web-socket"; import cwraps from "./cwraps"; import { setI8, setI16, setI32, setI64, @@ -310,7 +310,7 @@ export const __linker_exports: any = { mono_wasm_web_socket_open_ref, mono_wasm_web_socket_send, mono_wasm_web_socket_receive, - mono_wasm_web_socket_close, + mono_wasm_web_socket_close_ref, mono_wasm_web_socket_abort, mono_wasm_compile_function, diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index aa4d4a06cce52b..3b3edf9b074b93 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -185,9 +185,9 @@ export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buff } } -export function mono_wasm_web_socket_close(webSocket_js_handle: JSHandle, code: number, reason: MonoString, wait_for_close_received: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { +export function mono_wasm_web_socket_close_ref(webSocket_js_handle: JSHandle, code: number, reason: MonoObjectRef, wait_for_close_received: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); - const reason_root = mono_wasm_new_root(reason); + const reason_root = mono_wasm_new_external_root(reason); try { const ws = mono_wasm_get_jsobj_from_js_handle(webSocket_js_handle); if (!ws) From 23bcf957c97254c8852e7abc0df9999ef42a6e4e Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 11:38:17 -0700 Subject: [PATCH 059/128] Remove outdated comments --- .../Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs | 2 -- src/mono/wasm/runtime/method-calls.ts | 1 - src/mono/wasm/runtime/web-socket.ts | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs index 475f773b39ef4e..76977a3d26fff8 100644 --- a/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs +++ b/src/libraries/System.Private.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Runtime.CS.Owned.cs @@ -89,7 +89,6 @@ public static void CreateCSOwnedProxyRef(IntPtr jsHandle, MappedType mappedType, #region used from C# side - // TODO: Ref internal static bool ReleaseCSOwnedObject(JSObject objToRelease) { objToRelease.AssertNotDisposed(); @@ -102,7 +101,6 @@ internal static bool ReleaseCSOwnedObject(JSObject objToRelease) return true; } - // TODO: Ref internal static IntPtr CreateCSOwnedObject(JSObject proxy, string typeName, params object[] parms) { Interop.Runtime.CreateCSOwnedObjectRef(typeName, parms, out int exception, out object res); diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index fe2f1bf2eb9b36..bc47d9fa2efbb0 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -520,7 +520,6 @@ export function wrap_error_root(is_exception: Int32Ptr | null, ex: any, result: js_string_to_mono_string_root(res, result); } -// fixme: ref export function mono_method_get_call_signature_ref(method: MonoMethod, mono_obj?: WasmRoot): string/*ArgsMarshalString*/ { return call_method_ref( runtimeHelpers.get_call_sig_ref, undefined, "im", diff --git a/src/mono/wasm/runtime/web-socket.ts b/src/mono/wasm/runtime/web-socket.ts index 3b3edf9b074b93..17f7ad1a0b75d7 100644 --- a/src/mono/wasm/runtime/web-socket.ts +++ b/src/mono/wasm/runtime/web-socket.ts @@ -110,7 +110,6 @@ export function mono_wasm_web_socket_open_ref(uri_address: MonoObjectRef, subPro } } -// fixme: ref export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ptr: VoidPtr, offset: number, length: number, message_type: number, end_of_message: boolean, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); try { @@ -138,7 +137,6 @@ export function mono_wasm_web_socket_send(webSocket_js_handle: JSHandle, buffer_ } } -// fixme: ref export function mono_wasm_web_socket_receive(webSocket_js_handle: JSHandle, buffer_ptr: VoidPtr, offset: number, length: number, response_ptr: VoidPtr, thenable_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void { const result_root = mono_wasm_new_external_root(result_address); From ba6f738e30c7a41c103d4e005e695bc33c071921 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 11:48:17 -0700 Subject: [PATCH 060/128] Convert typed_array_new to ref --- src/mono/wasm/runtime/corebindings.c | 7 ++++--- src/mono/wasm/runtime/cwraps.ts | 4 ++-- src/mono/wasm/runtime/dotnet.d.ts | 6 ++++++ src/mono/wasm/runtime/js-to-cs.ts | 23 +++++++++++++++++++---- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 2ff78e26bc04e9..9789b861c3c987 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -73,8 +73,8 @@ void core_initialize_internals () #define MARSHAL_ARRAY_FLOAT 17 #define MARSHAL_ARRAY_DOUBLE 18 -EMSCRIPTEN_KEEPALIVE MonoArray* -mono_wasm_typed_array_new (char *arr, int length, int size, int type) +EMSCRIPTEN_KEEPALIVE void +mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, MonoArray **result) { MonoClass *typeClass = mono_get_byte_class(); // default is Byte switch (type) { @@ -106,9 +106,10 @@ mono_wasm_typed_array_new (char *arr, int length, int size, int type) buffer = mono_array_new (mono_get_root_domain(), typeClass, length); memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); - return buffer; + mono_gc_wbarrier_generic_store_atomic(result, (MonoObject *)buffer); } +// TODO: Remove - no longer used? If not, convert to ref EMSCRIPTEN_KEEPALIVE int mono_wasm_unbox_enum (MonoObject *obj) { diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index a14d8b0869b110..cac4fc84debf20 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -57,7 +57,7 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_assembly_get_entry_point", "number", ["number"]], ["mono_wasm_get_delegate_invoke_ref", "number", ["number"]], ["mono_wasm_string_array_new_ref", "void", ["number", "number"]], - ["mono_wasm_typed_array_new", "number", ["number", "number", "number", "number"]], + ["mono_wasm_typed_array_new_ref", "void", ["number", "number", "number", "number", "number"]], ["mono_wasm_class_get_type", "number", ["number"]], ["mono_wasm_type_get_class", "number", ["number"]], ["mono_wasm_get_type_name", "string", ["number"]], @@ -123,7 +123,7 @@ export interface t_Cwraps { mono_wasm_intern_string_ref(strRef: MonoStringRef): void; mono_wasm_assembly_get_entry_point(assembly: MonoAssembly): MonoMethod; mono_wasm_string_array_new_ref(size: number, result: MonoObjectRef): void; - mono_wasm_typed_array_new(arr: VoidPtr, length: number, size: number, type: number): MonoArray; + 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; diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 4e90bae840f0a4..04657b8f818ad4 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -254,7 +254,13 @@ declare function conv_string_root(root: WasmRoot): string | null; */ declare function js_string_to_mono_string(string: string): MonoString; +/** + * @deprecated Not GC or thread safe. For blazor use only + */ declare function js_to_mono_obj(js_obj: any): MonoObject; +/** + * @deprecated Not GC or thread safe + */ declare function js_typed_array_to_array(js_obj: any): MonoArray; declare function unbox_mono_obj(mono_obj: MonoObject): any; diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index b225e60d61c0f2..2be28a07b8c2c7 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -37,6 +37,9 @@ export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, } // this is only used from Blazor +/** + * @deprecated Not GC or thread safe. For blazor use only + */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function js_to_mono_obj(js_obj: any): MonoObject { const temp = mono_wasm_new_root(); @@ -154,8 +157,7 @@ function js_typedarray_to_heap(typedArray: TypedArray) { return heapBytes; } -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types -export function js_typed_array_to_array(js_obj: any): MonoArray { +export function js_typed_array_to_array_ref(js_obj: any, result: WasmRoot): void { // JavaScript typed arrays are array-like objects and provide a mechanism for accessing // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays // split the implementation into buffers and views. A buffer (implemented by the ArrayBuffer object) @@ -167,15 +169,28 @@ export function js_typed_array_to_array(js_obj: any): MonoArray { if (has_backing_array_buffer(js_obj) && js_obj.BYTES_PER_ELEMENT) { const arrayType = js_obj[wasm_type_symbol]; const heapBytes = js_typedarray_to_heap(js_obj); - const bufferArray = cwraps.mono_wasm_typed_array_new(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType); + cwraps.mono_wasm_typed_array_new_ref(heapBytes.byteOffset, js_obj.length, js_obj.BYTES_PER_ELEMENT, arrayType, result.address); Module._free(heapBytes.byteOffset); - return bufferArray; } else { throw new Error("Object '" + js_obj + "' is not a typed array"); } } +/** + * @deprecated Not GC or thread safe + */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export function js_typed_array_to_array(js_obj: any): MonoArray { + const temp = mono_wasm_new_root(); + try { + js_typed_array_to_array_ref(js_obj, temp); + return temp.value; + } finally { + temp.release(); + } +} + // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/explicit-module-boundary-types export function js_to_mono_enum(js_obj: any, method: MonoMethod, parmIdx: number): number { if (typeof (js_obj) !== "number") From 2684213870685dd68cbada65bf9ee7bd1f21b88d Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 15 Mar 2022 12:53:47 -0700 Subject: [PATCH 061/128] Add volatile modifiers, satisfy eslint --- src/mono/wasm/runtime/corebindings.c | 8 ++-- src/mono/wasm/runtime/driver.c | 49 ++++++++++++++++++------- src/mono/wasm/runtime/js-to-cs.ts | 1 + src/mono/wasm/runtime/method-binding.ts | 2 +- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 9789b861c3c987..ee1425eb050937 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -76,7 +76,7 @@ void core_initialize_internals () EMSCRIPTEN_KEEPALIVE void mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, MonoArray **result) { - MonoClass *typeClass = mono_get_byte_class(); // default is Byte + MonoClass * volatile typeClass = mono_get_byte_class(); // default is Byte switch (type) { case MARSHAL_ARRAY_BYTE: typeClass = mono_get_sbyte_class(); @@ -101,7 +101,7 @@ mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, MonoAr break; } - MonoArray *buffer; + MonoArray * volatile buffer; buffer = mono_array_new (mono_get_root_domain(), typeClass, length); memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size); @@ -116,9 +116,9 @@ mono_wasm_unbox_enum (MonoObject *obj) if (!obj) return 0; - MonoType *type = mono_class_get_type (mono_object_get_class(obj)); + MonoType * volatile type = mono_class_get_type (mono_object_get_class(obj)); - void *ptr = mono_object_unbox (obj); + void * volatile ptr = mono_object_unbox (obj); switch (mono_type_get_type(mono_type_get_underlying_type (type))) { case MONO_TYPE_I1: case MONO_TYPE_U1: diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index a07a2e99f07889..9ff7695fc0adc8 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -677,9 +677,10 @@ mono_wasm_box_primitive_ref (MonoClass *klass, void *value, int value_size, Mono } EMSCRIPTEN_KEEPALIVE void -mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **out_exc, MonoObject **out_result) +mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void *params[], MonoObject **_out_exc, MonoObject **out_result) { - MonoObject* temp_exc = NULL; + MonoObject * volatile * out_exc = _out_exc; + MonoObject * volatile temp_exc = NULL; if (out_exc) *out_exc = NULL; else @@ -688,16 +689,16 @@ mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void MONO_ENTER_GC_UNSAFE; if (out_result) { *out_result = NULL; - mono_gc_wbarrier_generic_store_atomic(out_result, mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc)); + mono_gc_wbarrier_generic_store_atomic(out_result, mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, (MonoObject **)out_exc)); } else { - mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, out_exc); + mono_runtime_invoke (method, this_arg_in ? *this_arg_in : NULL, params, (MonoObject **)out_exc); } if (*out_exc && out_result) { - MonoObject *exc2 = NULL; - mono_gc_wbarrier_generic_store_atomic(out_result, (MonoObject*)mono_object_to_string (*out_exc, &exc2)); + MonoObject * volatile exc2 = NULL; + mono_gc_wbarrier_generic_store_atomic((void *)out_result, (MonoObject*)mono_object_to_string (*out_exc, (MonoObject **)&exc2)); if (exc2) - mono_gc_wbarrier_generic_store_atomic(out_result, (MonoObject*)mono_string_new (root_domain, "Exception Double Fault")); + mono_gc_wbarrier_generic_store_atomic((void *)out_result, (MonoObject*)mono_string_new (root_domain, "Exception Double Fault")); } MONO_EXIT_GC_UNSAFE; } @@ -706,8 +707,8 @@ mono_wasm_invoke_method_ref (MonoMethod *method, MonoObject **this_arg_in, void MonoObject* mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], MonoObject **out_exc) { - MonoObject* result = NULL; - mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, &result); + MonoObject * volatile result = NULL; + mono_wasm_invoke_method_ref (method, &this_arg, params, out_exc, (MonoObject **)&result); MonoMethodSignature *sig = mono_method_signature (method); MonoType *type = mono_signature_get_return_type (sig); @@ -838,7 +839,7 @@ void mono_wasm_ensure_classes_resolved () resolved_datetimeoffset_class = 1; } if (!uri_class && !resolved_uri_class) { - MonoException** exc = NULL; + MonoException ** volatile exc = NULL; uri_class = mono_get_uri_class(exc); resolved_uri_class = 1; } @@ -977,7 +978,7 @@ mono_wasm_get_obj_type (MonoObject *obj) } // This code runs inside a gc unsafe region -int _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (MonoObject *obj, void *result, int result_capacity) { +int _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (MonoObject * volatile obj, void *result, int result_capacity) { void **resultP = result; int *resultI = result; int64_t *resultL = result; @@ -1157,8 +1158,8 @@ mono_wasm_obj_array_new_ref (int size, MonoArray **result) EMSCRIPTEN_KEEPALIVE MonoArray* mono_wasm_obj_array_new (int size) { - MonoArray *result = NULL; - mono_wasm_obj_array_new_ref(size, &result); + MonoArray * volatile result = NULL; + mono_wasm_obj_array_new_ref(size, (MonoArray **)&result); return result; } @@ -1283,3 +1284,25 @@ 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 (MonoObject ** volatile destination, MonoObject * volatile source) { + mono_gc_wbarrier_generic_store_atomic(destination, source); +} + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_copy_managed_pointer (MonoObject ** volatile destination, MonoObject ** volatile source) { + mono_gc_wbarrier_generic_store_atomic(destination, *source); +} + +#ifdef ENABLE_AOT_PROFILER + +void mono_profiler_init_aot (const char *desc); + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_load_profiler_aot (const char *desc) +{ + mono_profiler_init_aot (desc); +} + +#endif diff --git a/src/mono/wasm/runtime/js-to-cs.ts b/src/mono/wasm/runtime/js-to-cs.ts index 2be28a07b8c2c7..0eabf74bbf7101 100644 --- a/src/mono/wasm/runtime/js-to-cs.ts +++ b/src/mono/wasm/runtime/js-to-cs.ts @@ -157,6 +157,7 @@ function js_typedarray_to_heap(typedArray: TypedArray) { return heapBytes; } +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function js_typed_array_to_array_ref(js_obj: any, result: WasmRoot): void { // JavaScript typed arrays are array-like objects and provide a mechanism for accessing // raw binary data. (...) To achieve maximum flexibility and efficiency, JavaScript typed arrays diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index a82404ff552203..6f4a39d2afb5e4 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { WasmRoot, WasmRootBuffer, mono_wasm_new_root } from "./roots"; -import { MonoClass, MonoMethod, MonoObject, coerceNull, VoidPtrNull, MonoType, MarshalType } from "./types"; +import { MonoClass, MonoMethod, MonoObject, VoidPtrNull, MonoType, MarshalType } from "./types"; import { BINDING, Module, runtimeHelpers } from "./imports"; import { js_to_mono_enum, _js_to_mono_obj_root, _js_to_mono_uri_root } from "./js-to-cs"; import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "./strings"; From a87cdbc3de0579b58037e579cd1997ccf460bf59 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 16 Mar 2022 08:15:08 -0700 Subject: [PATCH 062/128] Update src/mono/wasm/runtime/corebindings.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Aleksey Kliger (λgeek) --- src/mono/wasm/runtime/corebindings.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index ee1425eb050937..c91170e7997c4b 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -99,6 +99,9 @@ mono_wasm_typed_array_new_ref (char *arr, int length, int size, int type, MonoAr case MARSHAL_ARRAY_DOUBLE: typeClass = mono_get_double_class(); break; + default: + printf ("Invalid marshal type %d in mono_wasm_typed_array_new", type); + abort(); } MonoArray * volatile buffer; From 9f202779c54bf9f090c633577911e40766706afc Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Wed, 16 Mar 2022 21:22:57 -0400 Subject: [PATCH 063/128] Missing conflict --- src/mono/wasm/runtime/cwraps.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index cac4fc84debf20..709865dcbb469d 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -163,11 +163,8 @@ export interface t_Cwraps { mono_wasm_set_main_args(argc: number, argv: VoidPtr): void; mono_profiler_init_aot(desc: string): void; mono_wasm_exec_regression(verbose_level: number, image: string): number; -<<<<<<< HEAD -======= mono_wasm_write_managed_pointer_unsafe(destination: VoidPtr | MonoObjectRef, pointer: ManagedPointer): void; mono_wasm_copy_managed_pointer(destination: VoidPtr | MonoObjectRef, source: VoidPtr | MonoObjectRef): void; ->>>>>>> 4499a7cb781 (Checkpoint (strings are broken for some reason)) } const wrapped_c_functions: t_Cwraps = {}; From 2a5553a67db5ca5b4977ff227773bdb2a6762228 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 17 Mar 2022 10:29:18 -0400 Subject: [PATCH 064/128] Fix build, set coop gc, and always copy dotnet.worker.js when it's around for apps --- .../System.Private.CoreLib.Shared.projitems | 2 +- .../System.Private.CoreLib.csproj | 5 +- .../ThreadPoolBoundHandle.Browser.Mono.cs | 48 +------------------ src/mono/wasm/build/WasmApp.Native.targets | 1 + src/mono/wasm/build/WasmApp.targets | 2 + src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js | 24 +++++----- src/mono/wasm/runtime/cwraps.ts | 2 +- src/mono/wasm/runtime/driver.c | 4 ++ src/mono/wasm/wasm.proj | 1 + 9 files changed, 26 insertions(+), 63 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 1085355874aa08..245861a6d8c64a 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2305,7 +2305,7 @@ - + diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index bba4ac845bc41c..10d73f34375417 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -285,9 +285,10 @@ - - diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs index 4a738976a5e2a3..c1bcfa75b8c2f0 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs @@ -5,55 +5,11 @@ namespace System.Threading { - public sealed class ThreadPoolBoundHandle : IDisposable + public sealed partial class ThreadPoolBoundHandle : IDisposable { - public SafeHandle Handle => null!; - - private ThreadPoolBoundHandle() - { - } - - public static ThreadPoolBoundHandle BindHandle(SafeHandle handle!!) - { - if (handle.IsClosed || handle.IsInvalid) - throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle)); - - throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); - } - - [CLSCompliant(false)] - public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback!!, object? state, object? pinData) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); - } - - [CLSCompliant(false)] - public unsafe NativeOverlapped* UnsafeAllocateNativeOverlapped(IOCompletionCallback callback, object? state, object? pinData) => - AllocateNativeOverlapped(callback, state, pinData); - - [CLSCompliant(false)] - public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated) + private static ThreadPoolBoundHandle BindHandleCore(SafeHandle handle) { - if (preAllocated == null) - throw new ArgumentNullException(nameof(preAllocated)); - throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); } - - [CLSCompliant(false)] - public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped!!) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); - } - - [CLSCompliant(false)] - public static unsafe object? GetNativeOverlappedState(NativeOverlapped* overlapped!!) - { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); - } - - public void Dispose() - { - } } } diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index 6fd2c357b8aa25..352e438e5783fd 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -435,6 +435,7 @@ + diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 070195319d6b53..2e44cae56c6b19 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -260,6 +260,7 @@ icudt.dat <_HasDotnetWasm Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.wasm'">true + <_HasDotnetJsWorker Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.worker.js'">true <_HasDotnetJsSymbols Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js.symbols'">true <_HasDotnetJs Condition="'%(WasmNativeAsset.FileName)%(WasmNativeAsset.Extension)' == 'dotnet.js'">true @@ -268,6 +269,7 @@ + diff --git a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js index 96b89f48cee6de..5946cdf6af6673 100644 --- a/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js +++ b/src/mono/wasm/runtime/cjs/dotnet.cjs.lib.js @@ -43,24 +43,22 @@ const linked_functions = [ // corebindings.c "mono_wasm_invoke_js_with_args", - "mono_wasm_get_object_property", - "mono_wasm_set_object_property", - "mono_wasm_get_by_index", - "mono_wasm_set_by_index", - "mono_wasm_get_global_object", + "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", - "mono_wasm_typed_array_copy_to", - "mono_wasm_typed_array_from", - "mono_wasm_typed_array_copy_from", - "mono_wasm_add_event_listener", - "mono_wasm_remove_event_listener", + "mono_wasm_typed_array_to_array_ref", + "mono_wasm_typed_array_copy_to_ref", + "mono_wasm_typed_array_from_ref", + "mono_wasm_typed_array_copy_from_ref", "mono_wasm_cancel_promise", - "mono_wasm_web_socket_open", + "mono_wasm_web_socket_open_ref", "mono_wasm_web_socket_send", "mono_wasm_web_socket_receive", - "mono_wasm_web_socket_close", + "mono_wasm_web_socket_close_ref", "mono_wasm_web_socket_abort", "mono_wasm_compile_function", diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 498e1d07e814e8..d25f6eb8eed0f2 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -7,7 +7,7 @@ import { MonoType, MonoObjectRef, MonoStringRef } from "./types"; import { Module } from "./imports"; -import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr } from "./types/emscripten"; +import { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten"; const fn_signatures: [ident: string, returnType: string | null, argTypes?: string[], opts?: any][] = [ // MONO diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 59dd48e78939c1..3747695ceb985f 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -501,6 +501,10 @@ mono_wasm_load_runtime (const char *unused, int debug_level) mono_wasm_link_icu_shim (); #endif + // We should enable this as part of the wasm build later + monoeg_g_setenv ("MONO_THREADS_SUSPEND", "coop", 0); + monoeg_g_setenv ("MONO_SLEEP_ABORT_LIMIT", "250", 0); + monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 6ca29129bf7fd1..6b57bf109bf852 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -115,6 +115,7 @@ <_EmccLinkFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> + <_EmccLinkFlags Include="-s LLD_REPORT_UNDEFINED" /> <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> From 06da6968bc54469cf0c559194aba3f80a55ef5a7 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 17 Mar 2022 13:09:30 -0400 Subject: [PATCH 065/128] Disable sample profiler, add some functions that were missing from katelyn's PR. --- src/mono/mono/eventpipe/ep-rt-mono.h | 5 ++--- src/mono/mono/metadata/assembly.c | 2 ++ src/mono/mono/mini/mini-exceptions.c | 2 ++ src/mono/sample/wasm/browser/Program.cs | 4 ++++ src/mono/wasm/runtime/cwraps.ts | 2 ++ src/native/eventpipe/ep.c | 2 +- 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 4f3600ef0b89e2..9df830b624be7e 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -871,7 +871,6 @@ inline bool ep_rt_config_value_get_enable (void) { - /* bool enable = false; gchar *value = g_getenv ("DOTNET_EnableEventPipe"); if (!value) @@ -885,8 +884,8 @@ ep_rt_config_value_get_enable (void) } g_free (value); return enable; - */ - return true; + + //return true; } static diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index 3b89baefe2e53a..1d92bac7e34eab 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -1745,6 +1745,7 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena * purpose assembly loading mechanism. */ MonoImage *image = NULL; + MONO_ENTER_GC_UNSAFE; gboolean is_satellite = culture && culture [0] != 0; if (is_satellite) @@ -1756,6 +1757,7 @@ mono_assembly_open_from_bundle (MonoAssemblyLoadContext *alc, const char *filena mono_image_addref (image); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_ASSEMBLY, "Assembly Loader loaded assembly from bundle: '%s'.", filename); } + MONO_EXIT_GC_UNSAFE; return image; } diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index 0728c774fa5373..aaa543b11b9577 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -3284,6 +3284,8 @@ mono_thread_state_init (MonoThreadUnwindState *ctx) #if defined(MONO_CROSS_COMPILE) ctx->valid = FALSE; //A cross compiler doesn't need to suspend. +#elif defined(HOST_WASM) + MONO_INIT_CONTEXT_FROM_FUNC (&(ctx->ctx), mono_thread_state_init); #elif defined(HOST_WASI) // TODO: For WASI, we need to review how thread state is initialized #elif MONO_ARCH_HAS_MONO_CONTEXT diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser/Program.cs index c552b8ecf3673a..c03d77a310f3c9 100644 --- a/src/mono/sample/wasm/browser/Program.cs +++ b/src/mono/sample/wasm/browser/Program.cs @@ -37,11 +37,15 @@ public static void ThreadFuncTest() { Console.WriteLine("Hello from another thread"); + GC.Collect(); + for (int i = 0; i < 10; i++) { Console.WriteLine("Sleeping from another thread: " + i.ToString()); Thread.Sleep(0); } + + GC.Collect(); } } } diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index d25f6eb8eed0f2..16b8ed4d0e94bd 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -73,6 +73,8 @@ const fn_signatures: [ident: string, returnType: string | null, argTypes?: strin ["mono_wasm_enable_on_demand_gc", "void", ["number"]], ["mono_profiler_init_aot", "void", ["number"]], ["mono_wasm_exec_regression", "number", ["number", "string"]], + ["mono_wasm_write_managed_pointer_unsafe", "void", ["number", "number"]], + ["mono_wasm_copy_managed_pointer", "void", ["number", "number"]], ]; export interface t_Cwraps { diff --git a/src/native/eventpipe/ep.c b/src/native/eventpipe/ep.c index bdac36b3effe49..71358795d87572 100644 --- a/src/native/eventpipe/ep.c +++ b/src/native/eventpipe/ep.c @@ -1026,7 +1026,7 @@ ep_enable_2 ( ep_provider_config_init (&providers [0], ep_rt_utf8_string_dup (ep_config_get_public_provider_name_utf8 ()), 0x4c14fccbd, EP_EVENT_LEVEL_VERBOSE, NULL); ep_provider_config_init (&providers [1], ep_rt_utf8_string_dup (ep_config_get_private_provider_name_utf8 ()), 0x4002000b, EP_EVENT_LEVEL_VERBOSE, NULL); - ep_provider_config_init (&providers [2], ep_rt_utf8_string_dup (ep_config_get_sample_profiler_provider_name_utf8 ()), 0x0, EP_EVENT_LEVEL_VERBOSE, NULL); + //ep_provider_config_init (&providers [2], ep_rt_utf8_string_dup (ep_config_get_sample_profiler_provider_name_utf8 ()), 0x0, EP_EVENT_LEVEL_VERBOSE, NULL); } else { // Count number of providers to parse. while (*providers_config_to_parse != '\0') { From e4b05eb9e3423ee63ca345cbc3148adca4df9e3b Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Mon, 21 Mar 2022 13:29:40 -0400 Subject: [PATCH 066/128] Add safepoint around ep_rt_wait_event_set. Tweak sample to explicitly exit wasm in order to properly flush event to the nettrace file (w/ rundown events). --- src/mono/mono/eventpipe/ep-rt-mono.h | 7 ++++-- src/mono/mono/metadata/threads.c | 7 ++++++ src/mono/sample/wasm/browser/Program.cs | 14 +++++------- src/mono/sample/wasm/browser/main.js | 30 ++++++++++++++++++++----- src/mono/wasm/runtime/driver.c | 1 + 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 9df830b624be7e..f6ef78d210c8b5 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -871,6 +871,7 @@ inline bool ep_rt_config_value_get_enable (void) { + /* bool enable = false; gchar *value = g_getenv ("DOTNET_EnableEventPipe"); if (!value) @@ -884,8 +885,8 @@ ep_rt_config_value_get_enable (void) } g_free (value); return enable; - - //return true; + */ + return true; } static @@ -1101,9 +1102,11 @@ inline bool ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) { + MONO_ENTER_GC_UNSAFE; //TODO, replace with low level PAL implementation. EP_ASSERT (wait_event != NULL && wait_event->event != NULL); mono_w32event_set (wait_event->event); + MONO_EXIT_GC_UNSAFE; return true; } diff --git a/src/mono/mono/metadata/threads.c b/src/mono/mono/metadata/threads.c index cb695dc7d42e47..7ff44061af7fb9 100644 --- a/src/mono/mono/metadata/threads.c +++ b/src/mono/mono/metadata/threads.c @@ -963,7 +963,11 @@ mono_thread_detach_internal (MonoInternalThread *thread) #ifndef HOST_WIN32 add_exiting_thread (thread); + +// Skip on wasm until we figure out how to bring back the finalizer thread +#ifndef HOST_WASM mono_gc_finalize_notify (); +#endif #endif mono_gchandle_free_internal (thread->abort_state_handle); @@ -4517,7 +4521,10 @@ mono_threads_add_joinable_runtime_thread (MonoThreadInfo *thread_info) joinable_threads_unlock (); +// Skip on wasm until we bring back the finalizer thread +#ifndef HOST_WASM mono_gc_finalize_notify (); +#endif } } diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser/Program.cs index c03d77a310f3c9..f5234b4c386f5a 100644 --- a/src/mono/sample/wasm/browser/Program.cs +++ b/src/mono/sample/wasm/browser/Program.cs @@ -24,10 +24,11 @@ public static int TestMeaning() Thread t = new Thread(new ThreadStart(ThreadFuncTest)); t.Start(); - for (int i = 0; i < 4; i++) + for (int i = 0; i < 5; i++) { Console.WriteLine("Main Thread is doing stuff too... " + i.ToString()); - Thread.Sleep(0); + Thread.Sleep(100); + GC.Collect(); } return 42; @@ -37,15 +38,12 @@ public static void ThreadFuncTest() { Console.WriteLine("Hello from another thread"); - GC.Collect(); - - for (int i = 0; i < 10; i++) + for (int i = 0; i < 5; i++) { Console.WriteLine("Sleeping from another thread: " + i.ToString()); - Thread.Sleep(0); + Thread.Sleep(100); + GC.Collect(); } - - GC.Collect(); } } } diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js index ad9ac8df301068..ec70519b38d087 100644 --- a/src/mono/sample/wasm/browser/main.js +++ b/src/mono/sample/wasm/browser/main.js @@ -8,6 +8,15 @@ function wasm_exit(exit_code) { console.log(`WASM EXIT ${exit_code}`); } +function Uint8ToString(u8a){ + var CHUNK_SZ = 0x8000; + var c = []; + for (var i=0; i < u8a.length; i+=CHUNK_SZ) { + c.push(String.fromCharCode.apply(null, u8a.subarray(i, i+CHUNK_SZ))); + } + return c.join(""); +} + async function loadRuntime() { globalThis.exports = {}; await import("./dotnet.js"); @@ -15,8 +24,7 @@ async function loadRuntime() { } async function main() { - try { - const createDotnetRuntime = await loadRuntime(); + const createDotnetRuntime = await loadRuntime(); const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => { console.log('user code in createDotnetRuntime') return { @@ -28,20 +36,30 @@ async function main() { postRun: () => { console.log('user code Module.postRun') }, } }); - globalThis.__Module = Module; - globalThis.MONO = MONO; - console.log('after createDotnetRuntime') + globalThis.__Module = Module; + globalThis.MONO = MONO; + console.log('after createDotnetRuntime') + try { const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning"); const ret = testMeaning(); document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; console.debug(`ret: ${ret}`); + let exit_code = ret == 42 ? 0 : 1; + Module._mono_wasm_exit(exit_code); + wasm_exit(exit_code); } catch (err) { console.log(`WASM ERROR ${err}`); - wasm_exit(2) + + var b = Module.FS.readFile('/trace.nettrace'); + var bits = btoa((Uint8ToString(b))); + + window.open("data:application/octet-stream;base64," + bits); + + wasm_exit(2); } } diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 3747695ceb985f..0f9459f8ce16b4 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -1202,6 +1202,7 @@ mono_wasm_exec_regression (int verbose_level, char *image) EMSCRIPTEN_KEEPALIVE int mono_wasm_exit (int exit_code) { + mono_jit_cleanup (root_domain); exit (exit_code); } From 67c70ac2cd12c61f9a0b53d3f3dd1682ffa8e1e7 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 22 Mar 2022 15:08:48 -0400 Subject: [PATCH 067/128] [gc] Start the GC Finalizer thread on threaded WASM --- src/mono/mono/metadata/gc.c | 2 +- src/mono/mono/metadata/threads.c | 6 ------ src/mono/wasm/runtime/driver.c | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index 5144e40eeec431..c4fd668c7722b0 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -704,7 +704,7 @@ mono_gc_finalize_notify (void) #if defined(HOST_WASI) // TODO: Schedule the background job on WASI. Threads aren't yet supported in this build. -#elif defined(HOST_WASM) +#elif defined(HOST_WASM) && defined(DISABLE_THREADS) mono_threads_schedule_background_job (mono_runtime_do_background_work); #else mono_coop_sem_post (&finalizer_sem); diff --git a/src/mono/mono/metadata/threads.c b/src/mono/mono/metadata/threads.c index 7ff44061af7fb9..4240716fb24833 100644 --- a/src/mono/mono/metadata/threads.c +++ b/src/mono/mono/metadata/threads.c @@ -964,10 +964,7 @@ mono_thread_detach_internal (MonoInternalThread *thread) #ifndef HOST_WIN32 add_exiting_thread (thread); -// Skip on wasm until we figure out how to bring back the finalizer thread -#ifndef HOST_WASM mono_gc_finalize_notify (); -#endif #endif mono_gchandle_free_internal (thread->abort_state_handle); @@ -4521,10 +4518,7 @@ mono_threads_add_joinable_runtime_thread (MonoThreadInfo *thread_info) joinable_threads_unlock (); -// Skip on wasm until we bring back the finalizer thread -#ifndef HOST_WASM mono_gc_finalize_notify (); -#endif } } diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 0f9459f8ce16b4..c783dc4860f400 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -59,6 +59,8 @@ void mono_free (void*); int32_t mini_parse_debug_option (const char *option); char *mono_method_get_full_name (MonoMethod *method); +static void mono_wasm_init_finalizer_thread (void); + // ????????????? #define gpointer void* @@ -623,6 +625,10 @@ mono_wasm_load_runtime (const char *unused, int debug_level) mono_initialize_internals(); mono_thread_set_main (mono_thread_current ()); + + // TODO: we can probably delay starting the finalizer thread even longer - maybe from JS + // once we're done with loading and are about to begin running some managed code. + mono_wasm_init_finalizer_thread (); } EMSCRIPTEN_KEEPALIVE MonoAssembly* @@ -1315,3 +1321,11 @@ mono_wasm_load_profiler_aot (const char *desc) } #endif + +static void +mono_wasm_init_finalizer_thread (void) +{ +#ifdef __EMSCRIPTEN_PTHREADS__ + mono_gc_init_finalizer_thread (); +#endif +} From 0f6f5210fe25b245db70251c99f9cc19a9aeb474 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 22 Mar 2022 15:13:05 -0400 Subject: [PATCH 068/128] [mono] add GC Unsafe in mono_assembly_load; remove in EventPipe Remove GC Unsafe hack in ep_rt_wait_event_set --- src/mono/mono/eventpipe/ep-rt-mono.h | 2 -- src/mono/mono/metadata/assembly.c | 6 +++++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index f6ef78d210c8b5..4f3600ef0b89e2 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -1102,11 +1102,9 @@ inline bool ep_rt_wait_event_set (ep_rt_wait_event_handle_t *wait_event) { - MONO_ENTER_GC_UNSAFE; //TODO, replace with low level PAL implementation. EP_ASSERT (wait_event != NULL && wait_event->event != NULL); mono_w32event_set (wait_event->event); - MONO_EXIT_GC_UNSAFE; return true; } diff --git a/src/mono/mono/metadata/assembly.c b/src/mono/mono/metadata/assembly.c index 1d92bac7e34eab..10bb7ba581bf43 100644 --- a/src/mono/mono/metadata/assembly.c +++ b/src/mono/mono/metadata/assembly.c @@ -3060,11 +3060,15 @@ mono_assembly_load_full (MonoAssemblyName *aname, const char *basedir, MonoImage MonoAssembly* mono_assembly_load (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status) { + MonoAssembly *result = NULL; + MONO_ENTER_GC_UNSAFE; MonoAssemblyByNameRequest req; mono_assembly_request_prepare_byname (&req, mono_alc_get_default ()); req.requesting_assembly = NULL; req.basedir = basedir; - return mono_assembly_request_byname (aname, &req, status); + result = mono_assembly_request_byname (aname, &req, status); + MONO_EXIT_GC_UNSAFE; + return result; } /** From 5af1f5cfdde857bf532e60a366eaf1148f1469c5 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 6 Apr 2022 16:08:45 -0400 Subject: [PATCH 069/128] post-merge cleanup: delete duplicated definitions --- src/mono/wasm/runtime/driver.c | 42 ---------------------------------- 1 file changed, 42 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index ea79dbffde9e22..b0806e60e526cd 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -62,48 +62,6 @@ char *mono_method_get_full_name (MonoMethod *method); static void mono_wasm_init_finalizer_thread (void); -// ????????????? - -#define gpointer void* - -MONO_API MONO_RT_EXTERNAL_ONLY gpointer -mono_threads_enter_gc_unsafe_region (gpointer* stackdata); - -MONO_API MONO_RT_EXTERNAL_ONLY void -mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer* stackdata); - -MONO_API MONO_RT_EXTERNAL_ONLY void -mono_threads_assert_gc_unsafe_region (void); - -MONO_API MONO_RT_EXTERNAL_ONLY gpointer -mono_threads_enter_gc_safe_region (gpointer *stackdata); - -MONO_API MONO_RT_EXTERNAL_ONLY void -mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata); - -MONO_API void -mono_threads_assert_gc_safe_region (void); -#define MONO_ENTER_GC_UNSAFE \ - do { \ - gpointer __dummy; \ - gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__dummy) \ - -#define MONO_EXIT_GC_UNSAFE \ - mono_threads_exit_gc_unsafe_region (__gc_unsafe_cookie, &__dummy); \ - } while (0) - -#define MONO_ENTER_GC_SAFE \ - do { \ - gpointer __dummy; \ - gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__dummy) \ - -#define MONO_EXIT_GC_SAFE \ - mono_threads_exit_gc_safe_region (__gc_safe_cookie, &__dummy); \ - } while (0) - -// ????????????????? - - #define MARSHAL_TYPE_NULL 0 #define MARSHAL_TYPE_INT 1 #define MARSHAL_TYPE_FP64 2 From 7bbaf94642d6bb50fa3aa272fc461bf23b7e9580 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 6 Apr 2022 16:30:47 -0400 Subject: [PATCH 070/128] [sample] Env vars should be stringy --- src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj index e16a8821b7ef7c..f08687f3d59820 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -15,7 +15,7 @@ From 4174adc1d02b0510aa7222619a3d74f7a51a827b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 6 Apr 2022 16:31:13 -0400 Subject: [PATCH 071/128] updated dotnet.d.ts --- src/mono/wasm/runtime/dotnet.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts index 3e5083662d8601..0a4a8d48e8e7f6 100644 --- a/src/mono/wasm/runtime/dotnet.d.ts +++ b/src/mono/wasm/runtime/dotnet.d.ts @@ -382,6 +382,8 @@ declare const BINDING: { * @deprecated Renamed to conv_string_root */ conv_string_rooted: typeof conv_string_root; + mono_obj_array_new_ref: (size: number, result: MonoObjectRef) => void; + mono_obj_array_set_ref: (array: MonoObjectRef, idx: number, obj: MonoObjectRef) => void; js_string_to_mono_string_root: typeof js_string_to_mono_string_root; js_typed_array_to_array_root: typeof js_typed_array_to_array_root; js_to_mono_obj_root: typeof js_to_mono_obj_root; From 736a6105b53041d3075aed7bf00647f01725eb4d Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 23 Mar 2022 15:04:17 -0400 Subject: [PATCH 072/128] Add mono_threads_wasm_async_run_in_main_thread; do background work on main Don't start a finalizer thread Queue all background work to run on the main thread --- src/mono/mono/metadata/gc.c | 20 +++++++++-- src/mono/mono/utils/CMakeLists.txt | 1 + src/mono/mono/utils/mono-threads-wasm.c | 44 +++++++++++++++++++++++++ src/mono/mono/utils/mono-threads-wasm.h | 40 ++++++++++++++++++++++ src/mono/wasm/runtime/driver.c | 4 ++- src/mono/wasm/threads.md | 39 ++++++++++++++++++++++ 6 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 src/mono/mono/utils/mono-threads-wasm.h create mode 100644 src/mono/wasm/threads.md diff --git a/src/mono/mono/metadata/gc.c b/src/mono/mono/metadata/gc.c index c4fd668c7722b0..53f6ee260eea9d 100644 --- a/src/mono/mono/metadata/gc.c +++ b/src/mono/mono/metadata/gc.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifndef HOST_WIN32 #include #endif @@ -685,6 +686,21 @@ ves_icall_System_GCHandle_InternalSet (MonoGCHandle handle, MonoObjectHandle obj static MonoCoopSem finalizer_sem; static volatile gboolean finished; +#ifdef HOST_WASM + +static void +mono_wasm_gc_finalize_notify (void) +{ +#if 0 + /* use this if we are going to start the finalizer thread on wasm. */ + mono_coop_sem_post (&finalizer_sem); +#else + mono_threads_schedule_background_job (mono_runtime_do_background_work); +#endif +} + +#endif /* HOST_WASM */ + /* * mono_gc_finalize_notify: * @@ -704,8 +720,8 @@ mono_gc_finalize_notify (void) #if defined(HOST_WASI) // TODO: Schedule the background job on WASI. Threads aren't yet supported in this build. -#elif defined(HOST_WASM) && defined(DISABLE_THREADS) - mono_threads_schedule_background_job (mono_runtime_do_background_work); +#elif defined(HOST_WASM) + mono_wasm_gc_finalize_notify (); #else mono_coop_sem_post (&finalizer_sem); #endif diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index 8f7742b180aafe..a4a7c505a1c0c6 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -137,6 +137,7 @@ set(utils_common_sources mono-threads-android.c mono-threads-haiku.c mono-threads-aix.c + mono-threads-wasm.h mono-threads-wasm.c mono-threads-sunos.c mono-threads.h diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index 5afe2c4b361e5b..5bd3fd4737569e 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -13,8 +13,13 @@ #ifdef HOST_BROWSER +#include + #include #include +#ifndef DISABLE_THREADS +#include +#endif #define round_down(addr, val) ((void*)((addr) & ~((val) - 1))) @@ -322,11 +327,22 @@ mono_memory_barrier_process_wide (void) G_EXTERN_C extern void schedule_background_exec (void); +/* jobs is not protected by a mutex, only access from a single thread! */ static GSList *jobs; void mono_threads_schedule_background_job (background_job_cb cb) { +#ifndef DISABLE_THREADS + if (!mono_threads_wasm_is_browser_thread ()) { + fprintf(stdout, "worker %p queued job %p\n", (gpointer)pthread_self(), (gpointer) cb); + mono_threads_wasm_async_run_in_main_thread_vi ((void (*)(gpointer))mono_threads_schedule_background_job, cb); + return; + } +#endif + + fprintf(stdout, "main thread queued job %p\n", (gpointer) cb); + if (!jobs) schedule_background_exec (); @@ -342,6 +358,9 @@ G_EXTERN_C EMSCRIPTEN_KEEPALIVE void mono_background_exec (void) { +#ifndef DISABLE_THREADS + g_assert (mono_threads_wasm_is_browser_thread ()); +#endif GSList *j = jobs, *cur; jobs = NULL; @@ -352,6 +371,31 @@ mono_background_exec (void) g_slist_free (j); } +gboolean +mono_threads_platform_is_main_thread (void) +{ + return emscripten_is_main_runtime_thread (); +} + +gboolean +mono_threads_wasm_is_browser_thread (void) +{ + return emscripten_is_main_browser_thread (); +} + +void +mono_threads_wasm_async_run_in_main_thread (void (*func) (void)) +{ + emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_V, func); +} + +void +mono_threads_wasm_async_run_in_main_thread_vi (void (*func) (gpointer), gpointer user_data) +{ + emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_VI, func, user_data); +} + + #endif /* HOST_BROWSER */ #else diff --git a/src/mono/mono/utils/mono-threads-wasm.h b/src/mono/mono/utils/mono-threads-wasm.h new file mode 100644 index 00000000000000..c02ac84565259d --- /dev/null +++ b/src/mono/mono/utils/mono-threads-wasm.h @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +/** + * \file + * Low-level threading for Webassembly + */ + +#ifndef __MONO_THREADS_WASM_H__ +#define __MONO_THREADS_WASM_H__ + +#include + +#ifdef HOST_WASM + +/* + * declared in mono-threads.h + * + * gboolean + * mono_threads_platform_is_main_thread (void); + */ + +gboolean +mono_threads_wasm_is_browser_thread (void); + +/** + * Runs the given function asynchronously on the main thread. + * See emscripten/threading.h emscripten_async_run_in_main_runtime_thread + */ +void +mono_threads_wasm_async_run_in_main_thread (void (*func) (void)); + +/* + * Variant that takes an argument. Add more variants as needed. + */ +void +mono_threads_wasm_async_run_in_main_thread_vi (void (*func)(gpointer), gpointer user_data); + +#endif /* HOST_WASM*/ + +#endif /* __MONO_THREADS_WASM_H__ */ diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index b0806e60e526cd..01e12783ee6b7d 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -1345,7 +1345,9 @@ mono_wasm_load_profiler_aot (const char *desc) static void mono_wasm_init_finalizer_thread (void) { -#ifdef __EMSCRIPTEN_PTHREADS__ + // At this time we don't use a dedicated thread for finalization even if threading is enabled. + // Finalizers periodically run on the main thread +#if 0 mono_gc_init_finalizer_thread (); #endif } diff --git a/src/mono/wasm/threads.md b/src/mono/wasm/threads.md new file mode 100644 index 00000000000000..b836d2f2574780 --- /dev/null +++ b/src/mono/wasm/threads.md @@ -0,0 +1,39 @@ +# Threaded runtime # + +## Building ## + +Build with `/p:WasmEnableThreads=true` + +**TODO**: Have two options - one for limited threading support for the runtime internals, and another to fully enable threading for user apps. + + +## Preprocessor defines ## + +In `src/mono/mono`, `DISABLE_THREADS` is _not_ defined if threading is enabled. + +If `src/mono/mono`, `__EMSCRIPTEN_THREADS__` _is_ defined if threading is enabled. + +**TODO**: Add a define if threading is fully enabled for user apps. + +## Browser thread, main thread ## + +When the app starts, emscripten can optionally run `main` on a new worker instead of on the browser thread. + +Mono does _not_ use this at this time. + +## Running work on other threads ## + +Emscripten provides an API to queue up callbacks to run on the main thread, or on a particular +worker thread. See +[`emscripten/threading.h`](https://github.com/emscripten-core/emscripten/blob/main/system/include/emscripten/threading.h). + +Mono exposes these functions as `mono_threads_wasm_async_run_in_main_thread`, etc in +`mono/utils/mono-threads-wasm.h`. + +## Background tasks ## + +The runtime has a number of tasks that are scheduled with `mono_threads_schedule_background_job` +(pumping the threadpool task queue, running GC finalizers, etc). + +The background tasks will run on the main thread. Calling `mono_threads_schedule_background_job` on +a worker thread will use `async_run_in_main_thread` to queue up work for the main thread. From 8eb80115c05e22329687473f7bb3b075425cd392 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 8 Apr 2022 16:17:02 -0400 Subject: [PATCH 073/128] [mono] Fix non-threaded wasm build --- src/mono/mono.proj | 2 +- src/mono/mono/utils/mono-threads-wasm.c | 15 ++++++++++++--- src/mono/mono/utils/mono-threads-wasm.h | 2 ++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 8d3e3d302f879b..c170be0350a99e 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -321,7 +321,7 @@ <_MonoMinimal Condition="'$(Configuration)' == 'Release'">,debugger_agent,log_dest <_MonoMinimal Condition="'$(Configuration)' == 'Release' and '$(MonoEnableAssertMessages)' != 'true'">$(_MonoMinimal),assert_messages - <_MonoMinimal Condition="'$(WasmEnableThreads)' == ''">$(_MonoMinimal),threads + <_MonoMinimal Condition="'$(WasmEnableThreads)' != 'true'">$(_MonoMinimal),threads <_MonoCMakeArgs Include="-DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,interpreter,qcalls$(_MonoMinimal)"/> diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index 5bd3fd4737569e..deecbd91893856 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -374,27 +374,36 @@ mono_background_exec (void) gboolean mono_threads_platform_is_main_thread (void) { +#ifdef DISABLE_THREADS + return TRUE; +#else return emscripten_is_main_runtime_thread (); +#endif } gboolean mono_threads_wasm_is_browser_thread (void) { +#ifdef DISABLE_THREADS + return TRUE; +#else return emscripten_is_main_browser_thread (); +#endif } +#ifndef DISABLE_THREADS void mono_threads_wasm_async_run_in_main_thread (void (*func) (void)) { - emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_V, func); + emscripten_async_run_in_main_runtime_thread (EM_FUNC_SIG_V, func); } void mono_threads_wasm_async_run_in_main_thread_vi (void (*func) (gpointer), gpointer user_data) { - emscripten_async_run_in_main_runtime_thread(EM_FUNC_SIG_VI, func, user_data); + emscripten_async_run_in_main_runtime_thread (EM_FUNC_SIG_VI, func, user_data); } - +#endif /* DISABLE_THREADS */ #endif /* HOST_BROWSER */ diff --git a/src/mono/mono/utils/mono-threads-wasm.h b/src/mono/mono/utils/mono-threads-wasm.h index c02ac84565259d..ecad01a7ec6037 100644 --- a/src/mono/mono/utils/mono-threads-wasm.h +++ b/src/mono/mono/utils/mono-threads-wasm.h @@ -22,6 +22,7 @@ gboolean mono_threads_wasm_is_browser_thread (void); +#ifndef DISABLE_THREADS /** * Runs the given function asynchronously on the main thread. * See emscripten/threading.h emscripten_async_run_in_main_runtime_thread @@ -34,6 +35,7 @@ mono_threads_wasm_async_run_in_main_thread (void (*func) (void)); */ void mono_threads_wasm_async_run_in_main_thread_vi (void (*func)(gpointer), gpointer user_data); +#endif /* DISABLE_THREADS */ #endif /* HOST_WASM*/ From 6fe4374987abf6786e5cf22b9d17f0c10287672d Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 7 Apr 2022 12:16:40 -0400 Subject: [PATCH 074/128] Add a System.Threading.Thread.WebAssembly.Threading ref assembly --- .../src/System/Threading/Thread.cs | 21 +++++++--- .../Directory.Build.props | 8 ++++ ...eading.Thread.WebAssembly.Threading.csproj | 42 +++++++++++++++++++ .../ref/System.Threading.Thread.cs | 16 +++++-- .../ref/System.Threading.Thread.csproj | 6 ++- .../src/MatchingRefApiCompatBaseline.txt | 6 +++ .../src/System.Threading.Thread.csproj | 3 +- ...iCompatBaseline.NetCoreAppLatestStable.txt | 13 ------ src/libraries/oob-all.proj | 3 ++ .../System.Private.CoreLib.csproj | 2 + 10 files changed, 95 insertions(+), 25 deletions(-) create mode 100644 src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props create mode 100644 src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj create mode 100644 src/libraries/System.Threading.Thread/src/MatchingRefApiCompatBaseline.txt diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index 808d0c925c0d7d..259d1e8b289e98 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -145,7 +145,9 @@ public Thread(ParameterizedThreadStart start!!, int maxStackSize) Initialize(); } -// [UnsupportedOSPlatformGuard("browser")] +#if !FEATURE_WASM_THREADS + [UnsupportedOSPlatformGuard("browser")] +#endif internal static bool IsThreadStartSupported => true; /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. @@ -153,7 +155,9 @@ public Thread(ParameterizedThreadStart start!!, int maxStackSize) /// The thread has already been started. /// There is not enough memory available to start this thread. /// This thread was created using a delegate instead of a delegate. -// [UnsupportedOSPlatform("browser")] +#if !FEATURE_WASM_THREADS + [UnsupportedOSPlatform("browser")] +#endif public void Start(object? parameter) => Start(parameter, captureContext: true); /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. @@ -165,7 +169,9 @@ public Thread(ParameterizedThreadStart start!!, int maxStackSize) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// -// [UnsupportedOSPlatform("browser")] +#if !FEATURE_WASM_THREADS + [UnsupportedOSPlatform("browser")] +#endif public void UnsafeStart(object? parameter) => Start(parameter, captureContext: false); private void Start(object? parameter, bool captureContext) @@ -192,7 +198,9 @@ private void Start(object? parameter, bool captureContext) /// Causes the operating system to change the state of the current instance to . /// The thread has already been started. /// There is not enough memory available to start this thread. -// [UnsupportedOSPlatform("browser")] +#if !FEATURE_WASM_THREADS + [UnsupportedOSPlatform("browser")] +#endif public void Start() => Start(captureContext: true); /// Causes the operating system to change the state of the current instance to . @@ -202,7 +210,9 @@ private void Start(object? parameter, bool captureContext) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// -// [UnsupportedOSPlatform("browser")] +#if !FEATURE_WASM_THREADS + [UnsupportedOSPlatform("browser")] +#endif public void UnsafeStart() => Start(captureContext: false); private void Start(bool captureContext) @@ -219,7 +229,6 @@ private void Start(bool captureContext) StartCore(); } -//#endif private void RequireCurrentThread() { diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props b/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props new file mode 100644 index 00000000000000..152d73fbeb2a2c --- /dev/null +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props @@ -0,0 +1,8 @@ + + + + + false + Microsoft + + diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj new file mode 100644 index 00000000000000..073b59c6c07986 --- /dev/null +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -0,0 +1,42 @@ + + + System.Threading.Thread + true + true + + v4.0.30319 + + $(NoWarn);0809;0618;CS8614;CS3015;NU5131 + $(NetCoreAppCurrent) + enable + + + + ref + $(DefineConstants);FEATURE_WASM_THREADS + true + Exposes Threading APIs from System.Runtime for WebAssembly projects + $(MSBuildProjectName) + + + + + + + + + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + + diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs index f498c6b39b4eb1..d764627ce63651 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.cs @@ -89,16 +89,24 @@ public static void SetData(System.LocalDataStoreSlot slot, object? data) { } public static void Sleep(int millisecondsTimeout) { } public static void Sleep(System.TimeSpan timeout) { } public static void SpinWait(int iterations) { } - //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public void Start() { } - //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public void Start(object? parameter) { } [System.ObsoleteAttribute("Thread.Suspend has been deprecated. Use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.")] public void Suspend() { } public bool TrySetApartmentState(System.Threading.ApartmentState state) { throw null; } - //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public void UnsafeStart() { } - //[System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public void UnsafeStart(object? parameter) { } public static byte VolatileRead(ref byte address) { throw null; } public static double VolatileRead(ref double address) { throw null; } diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj index 8fd273891553d6..0305d28b75161e 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj @@ -2,6 +2,10 @@ $(NetCoreAppCurrent) enable + false + + + $(DefineConstants);FEATURE_WASM_THREADS @@ -12,4 +16,4 @@ - \ No newline at end of file + diff --git a/src/libraries/System.Threading.Thread/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Threading.Thread/src/MatchingRefApiCompatBaseline.txt new file mode 100644 index 00000000000000..33ad3c96ed62bb --- /dev/null +++ b/src/libraries/System.Threading.Thread/src/MatchingRefApiCompatBaseline.txt @@ -0,0 +1,6 @@ +Compat issues with assembly System.Threading.Thread: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. +Total Issues: 4 diff --git a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj index 5ecfe239de6f7a..75cbd78620a3ad 100644 --- a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj @@ -3,8 +3,9 @@ true $(NetCoreAppCurrent) enable + false - \ No newline at end of file + diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt index 0187df3ec3411b..15a0fb09b100d4 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt @@ -28,10 +28,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. @@ -95,10 +91,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. @@ -173,11 +165,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. -Compat issues with assembly System.Threading.Thread: -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. Compat issues with assembly System.Threading.ThreadPool: CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. diff --git a/src/libraries/oob-all.proj b/src/libraries/oob-all.proj index f84c5b40502513..d0541e098f63c3 100644 --- a/src/libraries/oob-all.proj +++ b/src/libraries/oob-all.proj @@ -8,6 +8,9 @@ + + true + true @@ -127,6 +128,7 @@ $(DefineConstants);FEATURE_MANAGED_ETW_CHANNELS $(DefineConstants);FEATURE_PERFTRACING $(DefineConstants);FEATURE_OBJCMARSHAL + $(DefineConstants);FEATURE_WASM_THREADS From 06ee494a0802851b2461d8efa538e92026e72e91 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 7 Apr 2022 16:46:50 -0400 Subject: [PATCH 075/128] Update the browser sample to use System.Threading.Thread.WebAssembly.Threading --- .../System.Threading.Thread.WebAssembly.Threading.csproj | 3 ++- src/mono/sample/wasm/Directory.Build.props | 5 +++++ src/mono/sample/wasm/browser/Program.cs | 2 ++ src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj | 6 ++++++ src/mono/wasm/build/WasmApp.InTree.props | 2 +- 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 073b59c6c07986..82dcd184b8c8ee 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -16,7 +16,8 @@ ref $(DefineConstants);FEATURE_WASM_THREADS - true + + true Exposes Threading APIs from System.Runtime for WebAssembly projects $(MSBuildProjectName) diff --git a/src/mono/sample/wasm/Directory.Build.props b/src/mono/sample/wasm/Directory.Build.props index 6fc27dc90d9ae7..5e059a9df77fe4 100644 --- a/src/mono/sample/wasm/Directory.Build.props +++ b/src/mono/sample/wasm/Directory.Build.props @@ -3,6 +3,7 @@ Release Exe + true @@ -26,4 +27,8 @@ + + + true + diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser/Program.cs index f5234b4c386f5a..8683f673d92ef1 100644 --- a/src/mono/sample/wasm/browser/Program.cs +++ b/src/mono/sample/wasm/browser/Program.cs @@ -5,6 +5,7 @@ using System.Runtime.CompilerServices; using System.Collections.Generic; using System.Threading; +using System.Runtime.Versioning; namespace Sample { @@ -16,6 +17,7 @@ public static void Main(string[] args) } [MethodImpl(MethodImplOptions.NoInlining)] + [SupportedOSPlatform("browser")] // ask the analyzer to warn if we use APIs not supported on browser-wasm public static int TestMeaning() { List myList = new List{ 1, 2, 3, 4 }; diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj index f08687f3d59820..9135c2c1c8fe15 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -24,5 +24,11 @@ <_SampleProject>Wasm.Browser.CJS.Sample.csproj + + + + + + diff --git a/src/mono/wasm/build/WasmApp.InTree.props b/src/mono/wasm/build/WasmApp.InTree.props index adabd009d9c401..81b2623b25d1de 100644 --- a/src/mono/wasm/build/WasmApp.InTree.props +++ b/src/mono/wasm/build/WasmApp.InTree.props @@ -5,7 +5,7 @@ AnyCPU false - $(NetCoreAppToolCurrent) + $(NetCoreAppCurrent) $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'emsdk')) false true From 07bf28f0da799e7d61dd0e2c22afd511878129aa Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 8 Apr 2022 16:19:02 -0400 Subject: [PATCH 076/128] what is oob-all for? don't add thread wasm ref assembly there Does System.Threading.Thread.WebAssembly.Threading need to be in any of the .proj files in src/libraries? --- src/libraries/oob-all.proj | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/libraries/oob-all.proj b/src/libraries/oob-all.proj index d0541e098f63c3..f84c5b40502513 100644 --- a/src/libraries/oob-all.proj +++ b/src/libraries/oob-all.proj @@ -8,9 +8,6 @@ - - true; +#else +#if FEATURE_WASM_THREADS internal static bool IsThreadStartSupported => true; +#else + internal static bool IsThreadStartSupported => false; +#endif +#endif + + private static void ThrowIfNoThreadStart() { + if (!IsThreadStartSupported) + throw new PlatformNotSupportedException(); + } /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. /// An object that contains data to be used by the method the thread executes. /// The thread has already been started. /// There is not enough memory available to start this thread. /// This thread was created using a delegate instead of a delegate. -#if !FEATURE_WASM_THREADS - [UnsupportedOSPlatform("browser")] -#endif public void Start(object? parameter) => Start(parameter, captureContext: true); /// Causes the operating system to change the state of the current instance to , and optionally supplies an object containing data to be used by the method the thread executes. @@ -169,13 +176,12 @@ public Thread(ParameterizedThreadStart start!!, int maxStackSize) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// -#if !FEATURE_WASM_THREADS - [UnsupportedOSPlatform("browser")] -#endif public void UnsafeStart(object? parameter) => Start(parameter, captureContext: false); private void Start(object? parameter, bool captureContext) { + ThrowIfNoThreadStart(); + StartHelper? startHelper = _startHelper; // In the case of a null startHelper (second call to start on same thread) @@ -198,9 +204,6 @@ private void Start(object? parameter, bool captureContext) /// Causes the operating system to change the state of the current instance to . /// The thread has already been started. /// There is not enough memory available to start this thread. -#if !FEATURE_WASM_THREADS - [UnsupportedOSPlatform("browser")] -#endif public void Start() => Start(captureContext: true); /// Causes the operating system to change the state of the current instance to . @@ -210,13 +213,11 @@ private void Start(object? parameter, bool captureContext) /// Unlike , which captures the current and uses that context to invoke the thread's delegate, /// explicitly avoids capturing the current context and flowing it to the invocation. /// -#if !FEATURE_WASM_THREADS - [UnsupportedOSPlatform("browser")] -#endif public void UnsafeStart() => Start(captureContext: false); private void Start(bool captureContext) { + ThrowIfNoThreadStart(); StartHelper? startHelper = _startHelper; // In the case of a null startHelper (second call to start on same thread) diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props b/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props index 152d73fbeb2a2c..a7613cae13b445 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props @@ -4,5 +4,6 @@ false Microsoft + true diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 82dcd184b8c8ee..53df0b11cbfcc5 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -3,8 +3,6 @@ System.Threading.Thread true true - - v4.0.30319 @@ -16,19 +14,20 @@ ref $(DefineConstants);FEATURE_WASM_THREADS - - true + true Exposes Threading APIs from System.Runtime for WebAssembly projects $(MSBuildProjectName) + true + true - - - - + + + + diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj new file mode 100644 index 00000000000000..5a18d5a9a7d19c --- /dev/null +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/libraries/System.Threading.Thread/src/ApiCompatBaseline.txt b/src/libraries/System.Threading.Thread/src/ApiCompatBaseline.txt new file mode 100644 index 00000000000000..33ad3c96ed62bb --- /dev/null +++ b/src/libraries/System.Threading.Thread/src/ApiCompatBaseline.txt @@ -0,0 +1,6 @@ +Compat issues with assembly System.Threading.Thread: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.Start(System.Object)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart()' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.Thread.UnsafeStart(System.Object)' in the contract but not the implementation. +Total Issues: 4 diff --git a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj index 75cbd78620a3ad..88a40c4dda0103 100644 --- a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj @@ -3,7 +3,7 @@ true $(NetCoreAppCurrent) enable - false + false From 7844a910ab827214b2edd48085cf7ad207209ae9 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 8 Apr 2022 16:43:45 -0400 Subject: [PATCH 078/128] only turn on analyzers for the browser sample not all wasm samples --- src/mono/sample/wasm/Directory.Build.props | 5 ----- src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mono/sample/wasm/Directory.Build.props b/src/mono/sample/wasm/Directory.Build.props index 5e059a9df77fe4..6fc27dc90d9ae7 100644 --- a/src/mono/sample/wasm/Directory.Build.props +++ b/src/mono/sample/wasm/Directory.Build.props @@ -3,7 +3,6 @@ Release Exe - true @@ -27,8 +26,4 @@ - - - true - diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj index 9135c2c1c8fe15..f783c28a3f3837 100644 --- a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -24,6 +24,11 @@ <_SampleProject>Wasm.Browser.CJS.Sample.csproj + + + true + + From 5cd594b5559926535880e2161c24455814ebf728 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 11 Apr 2022 15:43:11 -0400 Subject: [PATCH 079/128] Make a single Microsoft.NET.WebAssembly.Threading nupkg that holds all the special ref assemblies --- .../Directory.Build.props | 9 +++++ .../Microsoft.NET.WebAssembly.Threading.proj | 34 +++++++++++++++++++ ...eading.Thread.WebAssembly.Threading.csproj | 5 +-- 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props create mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props b/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props new file mode 100644 index 00000000000000..ec628faa24a205 --- /dev/null +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + false + Microsoft + true + + diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj new file mode 100644 index 00000000000000..0021ce93ede424 --- /dev/null +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -0,0 +1,34 @@ + + + $(NetCoreAppCurrent) + Exposes Threading APIs for WebAssembly projects + $(MSBuildProjectName) + true + false + none + false + true + true + true + $(NoWarn);NU5131 + + ref + + + + + + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + + + diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 53df0b11cbfcc5..8217ba208e32bb 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -14,10 +14,7 @@ ref $(DefineConstants);FEATURE_WASM_THREADS - true - Exposes Threading APIs from System.Runtime for WebAssembly projects - $(MSBuildProjectName) - true + false true From 75166a0ebbc3a15468122e3efc53a440b1bb603a Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 11 Apr 2022 16:51:23 -0400 Subject: [PATCH 080/128] works: sample has ProjectReference to the Microsoft.NET.WebAssembly.Threading.proj --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 9 +++++++-- .../sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 0021ce93ede424..ecf9fb5ca1d3fb 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -10,14 +10,19 @@ true true true - $(NoWarn);NU5131 + + $(NoWarn);NU5128;NU5131 ref + + false + false + true - + - + From 3967d2c3377d5b494fd7ddd28a3fb590b7f21db3 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 12 Apr 2022 14:36:03 -0400 Subject: [PATCH 081/128] Add System.Threading.ThreadPool.WebAssembly.Threading ref assembly --- .../Microsoft.NET.WebAssembly.Threading.proj | 1 + ...ng.ThreadPool.WebAssembly.Threading.csproj | 37 +++++++++++++++++++ ...ng.ThreadPool.WebAssembly.Threading.csproj | 8 ++++ .../ref/System.Threading.ThreadPool.cs | 28 +++++++++++++- .../ref/System.Threading.ThreadPool.csproj | 4 ++ 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj create mode 100644 src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index ecf9fb5ca1d3fb..25e4adf5314a57 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -23,6 +23,7 @@ + + + System.Threading.ThreadPool + true + true + + $(NoWarn);0809;0618;CS8614;CS3015;NU5131 + $(NetCoreAppCurrent) + enable + + + + ref + $(DefineConstants);FEATURE_WASM_THREADS + false + true + + + + + + + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + + diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj new file mode 100644 index 00000000000000..5a18d5a9a7d19c --- /dev/null +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs index 5b3ea771b18ab3..20ca9318b980c4 100644 --- a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs +++ b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.cs @@ -10,7 +10,9 @@ public partial interface IThreadPoolWorkItem { void Execute(); } - +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public sealed partial class RegisteredWaitHandle : System.MarshalByRefObject { internal RegisteredWaitHandle() { } @@ -32,10 +34,22 @@ public static partial class ThreadPool public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack) { throw null; } public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack, object? state) { throw null; } public static bool QueueUserWorkItem(System.Action callBack, TState state, bool preferLocal) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, System.TimeSpan timeout, bool executeOnlyOnce) { throw null; } [System.CLSCompliantAttribute(false)] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { throw null; } public static bool SetMinThreads(int workerThreads, int completionPortThreads) { throw null; } @@ -45,10 +59,22 @@ public static partial class ThreadPool public static bool UnsafeQueueUserWorkItem(System.Threading.IThreadPoolWorkItem callBack, bool preferLocal) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Threading.WaitCallback callBack, object? state) { throw null; } public static bool UnsafeQueueUserWorkItem(System.Action callBack, TState state, bool preferLocal) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, System.TimeSpan timeout, bool executeOnlyOnce) { throw null; } [System.CLSCompliantAttribute(false)] +#if !FEATURE_WASM_THREADS + [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] +#endif public static System.Threading.RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object? state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; } } public delegate void WaitCallback(object? state); diff --git a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj index 6d53cf798f5985..d7330bfe72150e 100644 --- a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj +++ b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj @@ -3,6 +3,10 @@ true $(NetCoreAppCurrent) enable + false + + + $(DefineConstants);FEATURE_WASM_THREADS From a21b1acd3d4da3d7e95500c15f723c8ccc28b85c Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 12 Apr 2022 15:20:24 -0400 Subject: [PATCH 082/128] ThreadPool: throw PNSE if no thread start --- .../src/System/Threading/RegisteredWaitHandle.Portable.cs | 1 + .../System.Private.CoreLib/src/System/Threading/Thread.cs | 2 +- .../src/System/Threading/ThreadPool.Portable.cs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs index b3adb85c2ce21d..de31539b74b0fa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/RegisteredWaitHandle.Portable.cs @@ -15,6 +15,7 @@ public sealed partial class RegisteredWaitHandle : MarshalByRefObject internal RegisteredWaitHandle(WaitHandle waitHandle, _ThreadPoolWaitOrTimerCallback callbackHelper, int millisecondsTimeout, bool repeating) { + Thread.ThrowIfNoThreadStart(); Handle = waitHandle.SafeWaitHandle; Callback = callbackHelper; TimeoutDurationMs = millisecondsTimeout; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs index f433cb0c7a6d18..1b8d9e62ef80e6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Thread.cs @@ -155,7 +155,7 @@ public Thread(ParameterizedThreadStart start!!, int maxStackSize) #endif #endif - private static void ThrowIfNoThreadStart() { + internal static void ThrowIfNoThreadStart() { if (!IsThreadStartSupported) throw new PlatformNotSupportedException(); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs index b85726bbc0ea7d..af4fb503cd8ea5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Portable.cs @@ -104,6 +104,7 @@ private static RegisteredWaitHandle RegisterWaitForSingleObject( bool executeOnlyOnce, bool flowExecutionContext) { + Thread.ThrowIfNoThreadStart(); RegisteredWaitHandle registeredHandle = new RegisteredWaitHandle( waitObject, new _ThreadPoolWaitOrTimerCallback(callBack, state, flowExecutionContext), From 204dbfb9136370d36d8169a8d06759abbac75831 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 12 Apr 2022 16:06:10 -0400 Subject: [PATCH 083/128] Update wasm threads.md --- src/mono/wasm/threads.md | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/threads.md b/src/mono/wasm/threads.md index b836d2f2574780..ff0c3c164464e4 100644 --- a/src/mono/wasm/threads.md +++ b/src/mono/wasm/threads.md @@ -6,14 +6,43 @@ Build with `/p:WasmEnableThreads=true` **TODO**: Have two options - one for limited threading support for the runtime internals, and another to fully enable threading for user apps. +## Libraries feature defines ## -## Preprocessor defines ## +We use the `FeatureWasmThreads` property in the libraries projects to conditionallyie define +`FEATURE_WASM_THREADS` which is used to affect how the libraries are built for the multi-threaded +runtime. + +**TODO** add a separate feature property for WebAssembly EventPipe diagnostics. + +### Ref asssemblies ### + +For ref assemblies that have APIs that are related to threading, we use +`[UnsupportedOSPlatform("browser")]` under a `FEATURE_WASM_THREADS` define to mark APIs that are not +supported with the single-threaded runtime. Each such ref assembly (for example +`System.Threading.Thread`) is defined in two places: `src/libraries/System.Threading.Thread/ref` for +the single-threaded ref assemblies, and +`src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/` for the multi-threaded ref +assemblies. By default users compile against the single-threaded ref assemblies, but by adding a +`PackageReference` to `Microsoft.NET.WebAssembly.Threading`, they get the multi-threaded ref +assemblies. + +### Implementation assemblies ### + +The implementation (in `System.Private.CoreLib`) we check +`System.Threading.Thread.IsThreadStartSupported` or call +`System.Threading.Thread.ThrowIfNoThreadStart()` to guard code paths that depends on +multi-threading. The property is a boolean constant that will allow the IL trimmer or the +JIT/interpreter/AOT to drop the multi-threaded implementation in the single-threaded CoreLib. + +The implementation should not use `[UnsupportedOSPlatform("browser")]` + +## Native runtime preprocessor defines ## In `src/mono/mono`, `DISABLE_THREADS` is _not_ defined if threading is enabled. -If `src/mono/mono`, `__EMSCRIPTEN_THREADS__` _is_ defined if threading is enabled. +If `src/mono/wasm`, `__EMSCRIPTEN_THREADS__` _is_ defined if threading is enabled. -**TODO**: Add a define if threading is fully enabled for user apps. +**TODO**: Add a define if threading is only enabled internally, not for user apps. ## Browser thread, main thread ## From b02fd66c0d56e6a405256a9a3b0040b1b8fa5f8c Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 12 Apr 2022 16:47:21 -0400 Subject: [PATCH 084/128] apicompat: correct warnings for System.Threading.ThreadPool --- .../Directory.Build.props | 9 ++++++ .../src/ApiCompatBaseline.txt | 11 ++++++++ .../src/MatchingRefApiCompatBaseline.txt | 11 ++++++++ ...iCompatBaseline.NetCoreAppLatestStable.txt | 28 ------------------- 4 files changed, 31 insertions(+), 28 deletions(-) create mode 100644 src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props create mode 100644 src/libraries/System.Threading.ThreadPool/src/ApiCompatBaseline.txt create mode 100644 src/libraries/System.Threading.ThreadPool/src/MatchingRefApiCompatBaseline.txt diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props new file mode 100644 index 00000000000000..a7613cae13b445 --- /dev/null +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + false + Microsoft + true + + diff --git a/src/libraries/System.Threading.ThreadPool/src/ApiCompatBaseline.txt b/src/libraries/System.Threading.ThreadPool/src/ApiCompatBaseline.txt new file mode 100644 index 00000000000000..3dfbafeadd916d --- /dev/null +++ b/src/libraries/System.Threading.ThreadPool/src/ApiCompatBaseline.txt @@ -0,0 +1,11 @@ +Compat issues with assembly System.Threading.ThreadPool: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +Total Issues: 9 diff --git a/src/libraries/System.Threading.ThreadPool/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Threading.ThreadPool/src/MatchingRefApiCompatBaseline.txt new file mode 100644 index 00000000000000..3dfbafeadd916d --- /dev/null +++ b/src/libraries/System.Threading.ThreadPool/src/MatchingRefApiCompatBaseline.txt @@ -0,0 +1,11 @@ +Compat issues with assembly System.Threading.ThreadPool: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. +Total Issues: 9 diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt index 15a0fb09b100d4..c7a904785291be 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt @@ -27,15 +27,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. Compat issues with assembly netstandard: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -90,15 +81,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. Compat issues with assembly System: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -165,16 +147,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RSASignaturePadding' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.SignatureDescription' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. -Compat issues with assembly System.Threading.ThreadPool: -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.RegisteredWaitHandle' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.RegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int32, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.Int64, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.TimeSpan, System.Boolean)' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Threading.ThreadPool.UnsafeRegisterWaitForSingleObject(System.Threading.WaitHandle, System.Threading.WaitOrTimerCallback, System.Object, System.UInt32, System.Boolean)' in the contract but not the implementation. Compat issues with assembly System.Security.Cryptography.X509Certificates: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. Total Issues: 136 From 8417c7f1750697dca487dc156102939b1924fa76 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 09:55:04 -0400 Subject: [PATCH 085/128] Add dotnet.worker.js to the runtime pack; update PlatformManifestFileEntry --- .../pkg/sfx/Microsoft.NETCore.App/Directory.Build.props | 1 + src/mono/wasm/wasm.proj | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props index 7c749265591ac3..297aa1591aa897 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -211,6 +211,7 @@ + diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 45746fc50c2d66..66750a1bb90b8d 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -265,6 +265,11 @@ DestinationFolder="$(MicrosoftNetCoreAppRuntimePackNativeDir)" SkipUnchangedFiles="true" /> + + From 5c52e7d58e7ad7d478d211b6e57bc094c10ed966 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 09:55:46 -0400 Subject: [PATCH 086/128] [wasm] startup: detect Blazor dotnet.[version].[hash].js location Blazor injects a `` element into the header when it boots; detect it and extract the URL of the script. This is needed by Emscripten's dotnet.worker.js to run WorkerGlobalScope.importScripts --- src/mono/wasm/runtime/startup.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index a3b08a00aa5e3b..8eeeb7a7507618 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -35,10 +35,17 @@ export function configure_emscripten_startup(module: DotnetModule, exportedAPI: (typeof (globalThis.document) === "object") && (typeof (globalThis.document.createElement) === "function") ) { + // blazor injects a module preload link element for dotnet.[version].[sha].js + let x = Array.from (document.head.getElementsByTagName('link')).filter(elt => elt.rel !== undefined && elt.rel == 'modulepreload' && elt.href !== undefined && elt.href.indexOf('dotnet') != -1 && elt.href.indexOf ('.js') != -1); + if (x.length == 1) { + console.log("determined url of main script to be " + x[0].href); + (module)["mainScriptUrlOrBlob"] = x[0].href; + } else { const temp = globalThis.document.createElement("a"); temp.href = "dotnet.js"; console.log("determined url of main script to be " + temp.href); (module)["mainScriptUrlOrBlob"] = temp.href; + } } else console.log("could not determine url of main script for workers"); From 0b3755c05fa275cfa6799539818f0ab10662460e Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 09:58:50 -0400 Subject: [PATCH 087/128] one more fix to Microsoft.NET.WebAssembly.Threading Seems to be necessary in order for the resulting .nupkg not to reference non-existent nugets for the ProjectReferences --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 25e4adf5314a57..bf42dde4755906 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -21,11 +21,17 @@ - - - + + + + + + + + + From 1a3cddc5ff41c9f20f499669baedb47581301a91 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 10:31:26 -0400 Subject: [PATCH 088/128] rename sample to browser-mt-eventpipe --- src/mono/sample/wasm/{browser => browser-mt-eventpipe}/Makefile | 0 src/mono/sample/wasm/{browser => browser-mt-eventpipe}/Program.cs | 0 .../Wasm.Browser.CJS.Sample.csproj | 0 src/mono/sample/wasm/{browser => browser-mt-eventpipe}/index.html | 0 src/mono/sample/wasm/{browser => browser-mt-eventpipe}/main.js | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/mono/sample/wasm/{browser => browser-mt-eventpipe}/Makefile (100%) rename src/mono/sample/wasm/{browser => browser-mt-eventpipe}/Program.cs (100%) rename src/mono/sample/wasm/{browser => browser-mt-eventpipe}/Wasm.Browser.CJS.Sample.csproj (100%) rename src/mono/sample/wasm/{browser => browser-mt-eventpipe}/index.html (100%) rename src/mono/sample/wasm/{browser => browser-mt-eventpipe}/main.js (100%) diff --git a/src/mono/sample/wasm/browser/Makefile b/src/mono/sample/wasm/browser-mt-eventpipe/Makefile similarity index 100% rename from src/mono/sample/wasm/browser/Makefile rename to src/mono/sample/wasm/browser-mt-eventpipe/Makefile diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser-mt-eventpipe/Program.cs similarity index 100% rename from src/mono/sample/wasm/browser/Program.cs rename to src/mono/sample/wasm/browser-mt-eventpipe/Program.cs diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj similarity index 100% rename from src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj rename to src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj diff --git a/src/mono/sample/wasm/browser/index.html b/src/mono/sample/wasm/browser-mt-eventpipe/index.html similarity index 100% rename from src/mono/sample/wasm/browser/index.html rename to src/mono/sample/wasm/browser-mt-eventpipe/index.html diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser-mt-eventpipe/main.js similarity index 100% rename from src/mono/sample/wasm/browser/main.js rename to src/mono/sample/wasm/browser-mt-eventpipe/main.js From b6bc2bcb176fdae7efbf399c99ec5ccd209637e2 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 10:35:02 -0400 Subject: [PATCH 089/128] bring back unmodified browser sample The multithreading sample is browser-mt-eventpipe --- src/mono/sample/wasm/browser/Makefile | 11 +++++ src/mono/sample/wasm/browser/Program.cs | 22 +++++++++ .../browser/Wasm.Browser.CJS.Sample.csproj | 23 ++++++++++ src/mono/sample/wasm/browser/index.html | 19 ++++++++ src/mono/sample/wasm/browser/main.js | 46 +++++++++++++++++++ 5 files changed, 121 insertions(+) create mode 100644 src/mono/sample/wasm/browser/Makefile create mode 100644 src/mono/sample/wasm/browser/Program.cs create mode 100644 src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj create mode 100644 src/mono/sample/wasm/browser/index.html create mode 100644 src/mono/sample/wasm/browser/main.js diff --git a/src/mono/sample/wasm/browser/Makefile b/src/mono/sample/wasm/browser/Makefile new file mode 100644 index 00000000000000..7a6b17c4787bc4 --- /dev/null +++ b/src/mono/sample/wasm/browser/Makefile @@ -0,0 +1,11 @@ +TOP=../../../../.. + +include ../wasm.mk + +ifneq ($(AOT),) +override MSBUILD_ARGS+=/p:RunAOTCompilation=true +endif + +PROJECT_NAME=Wasm.Browser.CJS.Sample.csproj + +run: run-browser diff --git a/src/mono/sample/wasm/browser/Program.cs b/src/mono/sample/wasm/browser/Program.cs new file mode 100644 index 00000000000000..743f481896fcb5 --- /dev/null +++ b/src/mono/sample/wasm/browser/Program.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +namespace Sample +{ + public class Test + { + public static void Main(string[] args) + { + Console.WriteLine ("Hello, World!"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int TestMeaning() + { + return 42; + } + } +} diff --git a/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj new file mode 100644 index 00000000000000..d836a8539a8ecb --- /dev/null +++ b/src/mono/sample/wasm/browser/Wasm.Browser.CJS.Sample.csproj @@ -0,0 +1,23 @@ + + + true + main.js + true + embedded + 1 + false + + true + $(ExecXHarnessCmd) wasm test-browser --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- $(MSBuildProjectName).dll + + + + + + + + <_SampleProject>Wasm.Browser.CJS.Sample.csproj + + + + diff --git a/src/mono/sample/wasm/browser/index.html b/src/mono/sample/wasm/browser/index.html new file mode 100644 index 00000000000000..765d8ccede0849 --- /dev/null +++ b/src/mono/sample/wasm/browser/index.html @@ -0,0 +1,19 @@ + + + + + + + Sample CJS + + + + + + + Answer to the Ultimate Question of Life, the Universe, and Everything is : + + + + + \ No newline at end of file diff --git a/src/mono/sample/wasm/browser/main.js b/src/mono/sample/wasm/browser/main.js new file mode 100644 index 00000000000000..e50bf9daebf00d --- /dev/null +++ b/src/mono/sample/wasm/browser/main.js @@ -0,0 +1,46 @@ +function wasm_exit(exit_code) { + /* Set result in a tests_done element, to be read by xharness in runonly CI test */ + const tests_done_elem = document.createElement("label"); + tests_done_elem.id = "tests_done"; + tests_done_elem.innerHTML = exit_code.toString(); + document.body.appendChild(tests_done_elem); + + console.log(`WASM EXIT ${exit_code}`); +} + +async function loadRuntime() { + globalThis.exports = {}; + await import("./dotnet.js"); + return globalThis.exports.createDotnetRuntime; +} + +async function main() { + try { + const createDotnetRuntime = await loadRuntime(); + const { MONO, BINDING, Module, RuntimeBuildInfo } = await createDotnetRuntime(() => { + console.log('user code in createDotnetRuntime') + return { + disableDotnet6Compatibility: true, + configSrc: "./mono-config.json", + preInit: () => { console.log('user code Module.preInit') }, + preRun: () => { console.log('user code Module.preRun') }, + onRuntimeInitialized: () => { console.log('user code Module.onRuntimeInitialized') }, + postRun: () => { console.log('user code Module.postRun') }, + } + }); + console.log('after createDotnetRuntime') + + const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning"); + const ret = testMeaning(); + document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; + + console.debug(`ret: ${ret}`); + let exit_code = ret == 42 ? 0 : 1; + wasm_exit(exit_code); + } catch (err) { + console.log(`WASM ERROR ${err}`); + wasm_exit(2) + } +} + +main(); \ No newline at end of file From 4dd92a8a34d4d2a07ed79d66b410e19673672bcf Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 12:02:05 -0400 Subject: [PATCH 090/128] update browser-mt-eventpipe sample to use ref assembly refs Referencing the rollup Microsoft.NET.WebAssembly.Threading.proj doesn't work (it ends up bundling the ref assemblies into the publish dir and breaking the app) --- .../wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj index a9393bb7828a0d..87b1795d61b35b 100644 --- a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj +++ b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj @@ -31,8 +31,10 @@ + - + + From 873d70f37cc1708dc79d149417a796e09d911eb0 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 13:36:52 -0400 Subject: [PATCH 091/128] Use correct ifdef in AppContext.AnyOS.cs --- .../System.Private.CoreLib/src/System/AppContext.AnyOS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs index edf22600425729..9fdaf0e9181128 100644 --- a/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs +++ b/src/libraries/System.Private.CoreLib/src/System/AppContext.AnyOS.cs @@ -12,7 +12,7 @@ namespace System { public static partial class AppContext { -#if INCLUDE_ME_ +#if !TARGET_BROWSER [UnconditionalSuppressMessage("SingleFile", "IL3000: Avoid accessing Assembly file path when publishing as a single file", Justification = "Single File apps should always set APP_CONTEXT_BASE_DIRECTORY therefore code handles Assembly.Location equals null")] private static string GetBaseDirectoryCore() From bc16fdde885d210e798c3d0f32bc9f8413d3bccb Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 15:03:26 -0400 Subject: [PATCH 092/128] [build] support WasmEnableThreads and WasmEnablePerfTracing These toplevel options either turn on multi-threading in general, or turn on multithreading only for eventpipe internals. For libraries these define `FeatureWasmThreads` and `FeatureWasmPerfTracing` properties and the `FEATURE_WASM_THREADS` and `FEATURE_WASM_PERFTRACING` compiler constants. For the native code, they control `DISABLE_THREADS` and `DISABLE_WASM_USER_THREADS` cmake and preprocessor settings. --- .../System.Private.CoreLib.csproj | 6 +++-- src/mono/mono.proj | 19 +++++++++----- src/mono/wasm/runtime/CMakeLists.txt | 5 ++++ src/mono/wasm/runtime/wasm-config.h.in | 13 ++++++++++ src/mono/wasm/threads.md | 26 ++++++++++++++----- src/mono/wasm/wasm.proj | 22 +++++++++++----- 6 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 src/mono/wasm/runtime/wasm-config.h.in diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 4c782be3477ffc..d8ae2c396572e4 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -118,9 +118,10 @@ true true true - true - true true + true + true + true @@ -129,6 +130,7 @@ $(DefineConstants);FEATURE_PERFTRACING $(DefineConstants);FEATURE_OBJCMARSHAL $(DefineConstants);FEATURE_WASM_THREADS + $(DefineConstants);FEATURE_WASM_PERFTRACING diff --git a/src/mono/mono.proj b/src/mono/mono.proj index c170be0350a99e..83c32e6df65cc5 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -9,6 +9,8 @@ - MonoAOTLLVMDir - [optional] the directory where LLVM is located, for an AOT-only Mono - MonoVerboseBuild - enable verbose build - MonoThreadSuspend - coop,hybrid,preemptive - default thread suspend mode + - MonoWasmThreads - build runtime with threading support for wasm + - MonoWasmThreadsNoUser - build runtime with threading support for wasm, but with only internal utility threads (MonoWasmThreads must be defined too) --> @@ -50,6 +52,8 @@ <_CompilerTargetArch Condition="'$(RealTargetArchitecture)' != ''">$(RealTargetArchitecture) $([MSBuild]::NormalizeDirectory('$(RepositoryEngineeringDir)', 'common')) $([MSBuild]::NormalizePath('$(RepositoryEngineeringCommonDir)', 'cross', 'toolchain.cmake')) + true + true @@ -321,7 +325,8 @@ <_MonoMinimal Condition="'$(Configuration)' == 'Release'">,debugger_agent,log_dest <_MonoMinimal Condition="'$(Configuration)' == 'Release' and '$(MonoEnableAssertMessages)' != 'true'">$(_MonoMinimal),assert_messages - <_MonoMinimal Condition="'$(WasmEnableThreads)' != 'true'">$(_MonoMinimal),threads + <_MonoMinimal Condition="'$(MonoWasmThreads)' != 'true'">$(_MonoMinimal),threads + <_MonoMinimal Condition="'$(MonoWasmThreadsNoUser)' == 'true'">$(_MonoMinimal),wasm_user_threads <_MonoCMakeArgs Include="-DENABLE_MINIMAL=jit,sgen_major_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,sgen_debug_helpers,sgen_binary_protocol,logging,interpreter,qcalls$(_MonoMinimal)"/> @@ -331,14 +336,14 @@ <_MonoCMakeArgs Include="-DENABLE_LAZY_GC_THREAD_CREATION=1"/> <_MonoCMakeArgs Include="-DENABLE_LLVM_RUNTIME=1"/> <_MonoCFLAGS Include="-fexceptions"/> - <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-pthread"/> - <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-pthread"/> + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> <_MonoCXXFLAGS Include="-fexceptions"/> - <_MonoCXXFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-pthread"/> - <_MonoCXXFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> - <_MonoCFLAGS Condition="'$(WasmEnableThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include'))$(EscapedQuoteW)"/> + <_MonoCXXFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-pthread"/> + <_MonoCXXFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="-D_GNU_SOURCE=1" /> + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' == 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'include'))$(EscapedQuoteW)"/> - <_MonoCFLAGS Condition="'$(WasmEnableThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/> + <_MonoCFLAGS Condition="'$(MonoWasmThreads)' != 'true'" Include="$(EscapedQuoteW)-I$([MSBuild]::NormalizePath('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'include'))$(EscapedQuoteW)"/> diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index dfd9e0d8c01dda..e1bc88ce41e74c 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.14.5) 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) + set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(dotnet corebindings.c driver.c pinvoke.c) @@ -33,3 +36,5 @@ set_target_properties(dotnet PROPERTIES if(CMAKE_BUILD_TYPE STREQUAL "Release") add_custom_command(TARGET dotnet POST_BUILD COMMAND ${EMSDK_PATH}/upstream/bin/wasm-opt --enable-exception-handling --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.wasm -o ${NATIVE_BIN_DIR}/dotnet.wasm) endif() + +configure_file(wasm-config.h.in wasm-config.h) diff --git a/src/mono/wasm/runtime/wasm-config.h.in b/src/mono/wasm/runtime/wasm-config.h.in new file mode 100644 index 00000000000000..c5650ed200b45b --- /dev/null +++ b/src/mono/wasm/runtime/wasm-config.h.in @@ -0,0 +1,13 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +#ifndef __MONO_WASM_CONFIG_H__ +#define __MONO_WASM_CONFIG_H__ + +/* Support for threads is disabled */ +#cmakedefine DISABLE_THREADS + +/* Support for starting user threads is disabled */ +#cmakedefine DISABLE_WASM_USER_THREADS + +#endif/*__MONO_WASM_CONFIG_H__*/ diff --git a/src/mono/wasm/threads.md b/src/mono/wasm/threads.md index ff0c3c164464e4..afda117cb74593 100644 --- a/src/mono/wasm/threads.md +++ b/src/mono/wasm/threads.md @@ -2,17 +2,22 @@ ## Building ## -Build with `/p:WasmEnableThreads=true` +Build with `/p:WasmEnableThreads=true` to enable support for multi-threading. -**TODO**: Have two options - one for limited threading support for the runtime internals, and another to fully enable threading for user apps. +Build with `/p:WasmEnablePerfTracing=true` to enable support for EventPipe diagnostics - this enabled threading, but only for "internal" utility threads. User code is not allowed to start threads. + +Do not combine these options, just turn on one or the other. ## Libraries feature defines ## -We use the `FeatureWasmThreads` property in the libraries projects to conditionallyie define +We use the `FeatureWasmThreads` property in the libraries projects to conditionally define `FEATURE_WASM_THREADS` which is used to affect how the libraries are built for the multi-threaded runtime. -**TODO** add a separate feature property for WebAssembly EventPipe diagnostics. +We use the `FeatureWasmPerfTracing` property in the libraries projects to +conditionally define `FEATURE_WASM_PERFTRACING` which is used to affect how the +libraries are built for a runtime that is single-threaded for users, but +internally can use multithreading for EventPipe diagnostics. ### Ref asssemblies ### @@ -36,13 +41,20 @@ JIT/interpreter/AOT to drop the multi-threaded implementation in the single-thre The implementation should not use `[UnsupportedOSPlatform("browser")]` +**TODO** For `FeatureWasmPerfTracing`, the implementation should check *some +runtime contant* and throw PNSE if diagnostics are not enabled. + ## Native runtime preprocessor defines ## -In `src/mono/mono`, `DISABLE_THREADS` is _not_ defined if threading is enabled. +In `src/mono/mono` and `src/mono/wasm` `DISABLE_THREADS` is defined for single-threaded builds (same +as mono's existing `-DENABLE_MINIMAL=threads` option). In multi-threaded builds, `DISABLE_THREADS` +is _not_ defined. -If `src/mono/wasm`, `__EMSCRIPTEN_THREADS__` _is_ defined if threading is enabled. +For `WasmEnablePerfTracing`, `DISABLE_THREADS` is undefined (ie threading is enabled), but starting +user threads is not supported and `DISABLE_WASM_USER_THREADS` is defined (ie there is a +`-DENABLE_MINIMAL=wasm-user-threads` option) -**TODO**: Add a define if threading is only enabled internally, not for user apps. +Additionally, `__EMSCRIPTEN_THREADS__` is defined by emscripten if threading is enabled. ## Browser thread, main thread ## diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 66750a1bb90b8d..00fa9248157ba5 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -6,8 +6,16 @@ browser-wasm $([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'native', '$(NetCoreAppCurrent)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)')) - $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) - $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) + + + + true + true + + + + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm', 'native', 'lib')) + $([MSBuild]::NormalizeDirectory('$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)', 'runtimes', 'browser-wasm-threads', 'native', 'lib')) false false emcc @@ -131,9 +139,9 @@ <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> <_EmccLinkFlags Include="-s EXPORTED_RUNTIME_METHODS="['FS','print','ccall','cwrap','setValue','getValue','UTF8ToString','UTF8ArrayToString','FS_createPath','FS_createDataFile','removeRunDependency','addRunDependency', 'FS_readFile']"" /> - <_EmccCommonFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-s USE_PTHREADS=1" /> - <_EmccLinkFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-Wno-pthreads-mem-growth" /> - <_EmccLinkFlags Condition="'$(WasmEnableThreads)' == 'true'" Include="-s PTHREAD_POOL_SIZE=2" /> + <_EmccCommonFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-s USE_PTHREADS=1" /> + <_EmccLinkFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-Wno-pthreads-mem-growth" /> + <_EmccLinkFlags Condition="'$(MonoWasmThreads)' == 'true'" Include="-s PTHREAD_POOL_SIZE=2" /> <_EmccLinkFlags Include="-s EXPORTED_FUNCTIONS=$(_DefaultExportedFunctions)" Condition="'$(_DefaultExportedFunctions)' != ''" /> <_EmccLinkFlags Include="--source-map-base http://example.com" /> <_EmccLinkFlags Include="-s STRICT_JS=1" /> @@ -183,7 +191,7 @@ $(CMakeConfigurationEmccFlags) -O2 - $(CMakeConfigurationLinkFlags) -Wno-pthreads-mem-growth + $(CMakeConfigurationLinkFlags) -Wno-pthreads-mem-growth $(CMakeConfigurationLinkFlags) --emit-symbol-map -DEMSDK_PATH="$(EMSDK_PATH.TrimEnd('\/'))" @@ -197,6 +205,8 @@ $(CMakeBuildRuntimeConfigureCmd) -DICU_LIB_DIR="$(ICULibDir.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/'))" + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) From 352405d2966e10783b72ac16ce632a3d23c44e27 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 15:31:11 -0400 Subject: [PATCH 093/128] Only add the portable threadpool on wasm if threading is enabled --- .../System.Private.CoreLib/System.Private.CoreLib.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index d8ae2c396572e4..1e98b23120616b 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -114,12 +114,12 @@ $(DefineConstants);MONO_FEATURE_SRE true + true + true true true true - true - true - true + true true true From 990f097b752d081f2c5243cc3edf8d42436f6d6a Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 15:38:54 -0400 Subject: [PATCH 094/128] rename browser-mt-eventpipe csproj and main assembly Give it a unique name distinct from Wasm.Browser.CJS.Sample.csproj --- src/mono/sample/wasm/browser-mt-eventpipe/Makefile | 2 +- ...CJS.Sample.csproj => Wasm.Browser.ThreadsEP.Sample.csproj} | 0 src/mono/sample/wasm/browser-mt-eventpipe/main.js | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/mono/sample/wasm/browser-mt-eventpipe/{Wasm.Browser.CJS.Sample.csproj => Wasm.Browser.ThreadsEP.Sample.csproj} (100%) diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/Makefile b/src/mono/sample/wasm/browser-mt-eventpipe/Makefile index 7a6b17c4787bc4..8fddd8371b830e 100644 --- a/src/mono/sample/wasm/browser-mt-eventpipe/Makefile +++ b/src/mono/sample/wasm/browser-mt-eventpipe/Makefile @@ -6,6 +6,6 @@ ifneq ($(AOT),) override MSBUILD_ARGS+=/p:RunAOTCompilation=true endif -PROJECT_NAME=Wasm.Browser.CJS.Sample.csproj +PROJECT_NAME=Wasm.Browser.ThreadsEP.Sample.csproj run: run-browser diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj similarity index 100% rename from src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.CJS.Sample.csproj rename to src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/main.js b/src/mono/sample/wasm/browser-mt-eventpipe/main.js index ec70519b38d087..ba5a4075fe7c40 100644 --- a/src/mono/sample/wasm/browser-mt-eventpipe/main.js +++ b/src/mono/sample/wasm/browser-mt-eventpipe/main.js @@ -41,7 +41,7 @@ async function main() { console.log('after createDotnetRuntime') try { - const testMeaning = BINDING.bind_static_method("[Wasm.Browser.CJS.Sample] Sample.Test:TestMeaning"); + const testMeaning = BINDING.bind_static_method("[Wasm.Browser.ThreadsEP.Sample] Sample.Test:TestMeaning"); const ret = testMeaning(); document.getElementById("out").innerHTML = `${ret} as computed on dotnet ver ${RuntimeBuildInfo.ProductVersion}`; @@ -63,4 +63,4 @@ async function main() { } } -setTimeout(main, 10000); \ No newline at end of file +setTimeout(main, 10000); From ba9a9a60d97e3ae77aff645dfcf6f2678e0af930 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 16:11:14 -0400 Subject: [PATCH 095/128] fix /p:WasmEnableThreads=false build after merge --- .../System.Private.CoreLib.Shared.projitems | 2 +- .../System.Private.CoreLib.csproj | 6 ++--- .../System/Threading/Thread.Browser.Mono.cs | 25 ------------------- .../ThreadPoolBoundHandle.Browser.Mono.cs | 3 +++ src/mono/mono/utils/mono-threads-wasm.c | 2 -- src/mono/wasm/build/WasmApp.targets | 2 +- src/mono/wasm/runtime/driver.c | 2 ++ src/mono/wasm/wasm.proj | 4 +-- 8 files changed, 12 insertions(+), 34 deletions(-) delete mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/Thread.Browser.Mono.cs diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 529648bb37032c..c95637f6214be9 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2343,7 +2343,7 @@ - + diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 1e98b23120616b..13ce243d2301ec 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -291,10 +291,10 @@ - diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Browser.Mono.cs deleted file mode 100644 index 435a155c4ed164..00000000000000 --- a/src/mono/System.Private.CoreLib/src/System/Threading/Thread.Browser.Mono.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.Versioning; - -namespace System.Threading -{ - public partial class Thread - { - [UnsupportedOSPlatformGuard("browser")] - internal static bool IsThreadStartSupported => false; - - [UnsupportedOSPlatform("browser")] - public void Start() => throw new PlatformNotSupportedException(); - - [UnsupportedOSPlatform("browser")] - public void Start(object parameter) => throw new PlatformNotSupportedException(); - - [UnsupportedOSPlatform("browser")] - public void UnsafeStart() => throw new PlatformNotSupportedException(); - - [UnsupportedOSPlatform("browser")] - public void UnsafeStart(object parameter) => throw new PlatformNotSupportedException(); - } -} diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs index c1bcfa75b8c2f0..543ecacfb660e8 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs @@ -11,5 +11,8 @@ private static ThreadPoolBoundHandle BindHandleCore(SafeHandle handle) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); } + public void Dispose() + { + } } } diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index deecbd91893856..9be5c759ee2a81 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -123,7 +123,6 @@ mono_native_thread_id_get (void) #ifdef __EMSCRIPTEN_PTHREADS__ return pthread_self (); #else - g_assert_not_reached (); return (MonoNativeThreadId)1; #endif } @@ -134,7 +133,6 @@ mono_native_thread_os_id_get (void) #ifdef __EMSCRIPTEN_PTHREADS__ return (guint64)pthread_self (); #else - g_assert_not_reached (); return 1; #endif } diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 2e44cae56c6b19..cf8b18508cd7a4 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -269,7 +269,7 @@ - + diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index ac22e0cc7d1133..0304381369756e 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -467,8 +467,10 @@ mono_wasm_load_runtime (const char *unused, int debug_level) #endif // We should enable this as part of the wasm build later +#ifndef DISABLE_THREADS monoeg_g_setenv ("MONO_THREADS_SUSPEND", "coop", 0); monoeg_g_setenv ("MONO_SLEEP_ABORT_LIMIT", "250", 0); +#endif monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 00fa9248157ba5..7c0c42973ebaf3 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -205,8 +205,8 @@ $(CMakeBuildRuntimeConfigureCmd) -DICU_LIB_DIR="$(ICULibDir.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DMONO_ARTIFACTS_DIR="$(MonoArtifactsPath.TrimEnd('\/'))" $(CMakeBuildRuntimeConfigureCmd) -DNATIVE_BIN_DIR="$(NativeBinDir.TrimEnd('\/'))" - $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS - $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_THREADS=1 + $(CMakeBuildRuntimeConfigureCmd) -DDISABLE_WASM_USER_THREADS=1 $(CMakeBuildRuntimeConfigureCmd) $(CMakeConfigurationEmsdkPath) call "$(RepositoryEngineeringDir)native\init-vs-env.cmd" && call "$([MSBuild]::NormalizePath('$(EMSDK_PATH)', 'emsdk_env.bat'))" && $(CMakeBuildRuntimeConfigureCmd) From 16621b817bb508f68dc9dc521006fad66025c1d3 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 17:02:58 -0400 Subject: [PATCH 096/128] now fix the WasmEnableThreads=true build --- .../src/System.Private.CoreLib.Shared.projitems | 2 +- .../src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index c95637f6214be9..cc652815ca4208 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -2343,7 +2343,7 @@ - + diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs index 543ecacfb660e8..4f943918a0443c 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs @@ -11,8 +11,10 @@ private static ThreadPoolBoundHandle BindHandleCore(SafeHandle handle) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); } +#if !FEATURE_WASM_THREADS public void Dispose() { } +#endif } } From 3f616f91d8eea9c89858c8bc18c5c97f3c53e6c8 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 18 Apr 2022 17:34:45 -0400 Subject: [PATCH 097/128] we need two ThreadPoolBoundHandle implementation stubs one for PortableThreadPool when threads are enabled, one for single-threaded wasm --- .../System.Private.CoreLib.csproj | 5 +- .../ThreadPoolBoundHandle.Browser.Mono.cs | 47 +++++++++++++++++-- ...eadPoolBoundHandle.Browser.Threads.Mono.cs | 15 ++++++ 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index 13ce243d2301ec..7b5eb5e5f08970 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -290,9 +290,12 @@ - + + + + diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs index 4f943918a0443c..4a738976a5e2a3 100644 --- a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Mono.cs @@ -5,16 +5,55 @@ namespace System.Threading { - public sealed partial class ThreadPoolBoundHandle : IDisposable + public sealed class ThreadPoolBoundHandle : IDisposable { - private static ThreadPoolBoundHandle BindHandleCore(SafeHandle handle) + public SafeHandle Handle => null!; + + private ThreadPoolBoundHandle() + { + } + + public static ThreadPoolBoundHandle BindHandle(SafeHandle handle!!) + { + if (handle.IsClosed || handle.IsInvalid) + throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle)); + + throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); + } + + [CLSCompliant(false)] + public unsafe NativeOverlapped* AllocateNativeOverlapped(IOCompletionCallback callback!!, object? state, object? pinData) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); + } + + [CLSCompliant(false)] + public unsafe NativeOverlapped* UnsafeAllocateNativeOverlapped(IOCompletionCallback callback, object? state, object? pinData) => + AllocateNativeOverlapped(callback, state, pinData); + + [CLSCompliant(false)] + public unsafe NativeOverlapped* AllocateNativeOverlapped(PreAllocatedOverlapped preAllocated) + { + if (preAllocated == null) + throw new ArgumentNullException(nameof(preAllocated)); + + throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); + } + + [CLSCompliant(false)] + public unsafe void FreeNativeOverlapped(NativeOverlapped* overlapped!!) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); + } + + [CLSCompliant(false)] + public static unsafe object? GetNativeOverlappedState(NativeOverlapped* overlapped!!) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); } -#if !FEATURE_WASM_THREADS + public void Dispose() { } -#endif } } diff --git a/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs new file mode 100644 index 00000000000000..c1bcfa75b8c2f0 --- /dev/null +++ b/src/mono/System.Private.CoreLib/src/System/Threading/ThreadPoolBoundHandle.Browser.Threads.Mono.cs @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +namespace System.Threading +{ + public sealed partial class ThreadPoolBoundHandle : IDisposable + { + private static ThreadPoolBoundHandle BindHandleCore(SafeHandle handle) + { + throw new PlatformNotSupportedException(SR.PlatformNotSupported_OverlappedIO); + } + } +} From 1c3724a432295971872599d1179a3c7d888d4b9f Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 14:19:04 -0400 Subject: [PATCH 098/128] Add a System.Diagnostics.Tracing ref assembly gated by FeatureWasmPerfTracing --- .../Microsoft.NET.WebAssembly.Threading.proj | 1 + .../Directory.Build.props | 9 +++++ ...ics.Tracing.WebAssembly.PerfTracing.csproj | 33 +++++++++++++++++++ .../System.Diagnostics.Tracing.Counters.cs | 15 +++++++++ .../ref/System.Diagnostics.Tracing.csproj | 4 +++ .../src/ApiCompatBaseline.txt | 7 ++++ .../src/MatchingRefApiCompatBaseline.txt | 7 +++- ...iCompatBaseline.NetCoreAppLatestStable.txt | 5 --- .../Wasm.Browser.ThreadsEP.Sample.csproj | 1 + 9 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props create mode 100644 src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj create mode 100644 src/libraries/System.Diagnostics.Tracing/src/ApiCompatBaseline.txt diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index bf42dde4755906..bf9f8d9c935484 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -23,6 +23,7 @@ + diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props new file mode 100644 index 00000000000000..2589cb58682917 --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props @@ -0,0 +1,9 @@ + + + + + false + Microsoft + true + + diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj new file mode 100644 index 00000000000000..d540a638313a0d --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -0,0 +1,33 @@ + + + System.Diagnostics.Tracing + true + $(NetCoreAppCurrent) + enable + true + + + + ref + $(DefineConstants);FEATURE_WASM_PERFTRACING + false + true + + + + + + + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + + diff --git a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs index 2e1cce9f780a48..79a8e9ddd909ca 100644 --- a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs +++ b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.Counters.cs @@ -3,6 +3,9 @@ namespace System.Diagnostics.Tracing { +#if !FEATURE_WASM_PERFTRACING + [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] +#endif public abstract partial class DiagnosticCounter : System.IDisposable { internal DiagnosticCounter() { } @@ -13,11 +16,17 @@ internal DiagnosticCounter() { } public void AddMetadata(string key, string? value) { } public void Dispose() { } } +#if !FEATURE_WASM_PERFTRACING + [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] +#endif public partial class PollingCounter : System.Diagnostics.Tracing.DiagnosticCounter { public PollingCounter(string name, System.Diagnostics.Tracing.EventSource eventSource, System.Func metricProvider) { } public override string ToString() { throw null; } } +#if !FEATURE_WASM_PERFTRACING + [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] +#endif public partial class IncrementingEventCounter : System.Diagnostics.Tracing.DiagnosticCounter { public IncrementingEventCounter(string name, System.Diagnostics.Tracing.EventSource eventSource) { } @@ -25,12 +34,18 @@ public IncrementingEventCounter(string name, System.Diagnostics.Tracing.EventSou public void Increment(double increment = 1) { } public override string ToString() { throw null; } } +#if !FEATURE_WASM_PERFTRACING + [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] +#endif public partial class IncrementingPollingCounter : System.Diagnostics.Tracing.DiagnosticCounter { public IncrementingPollingCounter(string name, System.Diagnostics.Tracing.EventSource eventSource, System.Func totalValueProvider) { } public System.TimeSpan DisplayRateTimeScale { get { throw null; } set { } } public override string ToString() { throw null; } } +#if !FEATURE_WASM_PERFTRACING + [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] +#endif public partial class EventCounter : System.Diagnostics.Tracing.DiagnosticCounter { public EventCounter(string name, System.Diagnostics.Tracing.EventSource eventSource) { } diff --git a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj index b59d58aabfd2d6..39f5564a1b8f25 100644 --- a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj @@ -3,6 +3,10 @@ true $(NetCoreAppCurrent) enable + false + + + $(DefineConstants);FEATURE_WASM_PERFTRACING diff --git a/src/libraries/System.Diagnostics.Tracing/src/ApiCompatBaseline.txt b/src/libraries/System.Diagnostics.Tracing/src/ApiCompatBaseline.txt new file mode 100644 index 00000000000000..6c542177701265 --- /dev/null +++ b/src/libraries/System.Diagnostics.Tracing/src/ApiCompatBaseline.txt @@ -0,0 +1,7 @@ +Compat issues with assembly System.Diagnostics.Tracing: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.DiagnosticCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.EventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingEventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingPollingCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.PollingCounter' in the contract but not the implementation. +Total Issues: 4 diff --git a/src/libraries/System.Diagnostics.Tracing/src/MatchingRefApiCompatBaseline.txt b/src/libraries/System.Diagnostics.Tracing/src/MatchingRefApiCompatBaseline.txt index 754bf028a45ad8..d5f2617641ea37 100644 --- a/src/libraries/System.Diagnostics.Tracing/src/MatchingRefApiCompatBaseline.txt +++ b/src/libraries/System.Diagnostics.Tracing/src/MatchingRefApiCompatBaseline.txt @@ -1,6 +1,11 @@ Compat issues with assembly System.Diagnostics.Tracing: +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.DiagnosticCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.EventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingEventCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingPollingCounter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.PollingCounter' in the contract but not the implementation. MembersMustExist : Member 'protected void System.Diagnostics.Tracing.EventCounter.Flush()' does not exist in the reference but it does exist in the implementation. CannotMakeTypeAbstract : Type 'System.Diagnostics.Tracing.EventListener' is abstract in the reference but is not abstract in the implementation. CannotMakeMoreVisible : Visibility of member 'System.Diagnostics.Tracing.EventListener..ctor()' is 'protected' in the reference but 'public' in the implementation. CannotMakeMoreVisible : Visibility of member 'System.Diagnostics.Tracing.EventListener.EventSourceIndex(System.Diagnostics.Tracing.EventSource)' is 'protected' in the reference but 'public' in the implementation. -Total Issues: 4 +Total Issues: 8 diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt index c7a904785291be..f17d7d57d32a99 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt @@ -30,11 +30,6 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo Compat issues with assembly netstandard: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.DiagnosticCounter' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.EventCounter' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingEventCounter' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.IncrementingPollingCounter' in the contract but not the implementation. -CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Diagnostics.Tracing.PollingCounter' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(System.Span)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.CompilerServices.IsReadOnlyAttribute' exists on 'System.Numerics.Vector.CopyTo(T[])' in the contract but not the implementation. diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj index 87b1795d61b35b..8439bc84333c3c 100644 --- a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj +++ b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj @@ -35,6 +35,7 @@ + From e52c9b70f9cc124630fa0ac4ed375f52e86a33cc Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 16:42:41 -0400 Subject: [PATCH 099/128] [eventpipe] use the correct cmake option name see src/mono/mono.proj --- src/mono/mono/eventpipe/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/eventpipe/CMakeLists.txt b/src/mono/mono/eventpipe/CMakeLists.txt index fe64183c449056..30d3139e5879ad 100644 --- a/src/mono/mono/eventpipe/CMakeLists.txt +++ b/src/mono/mono/eventpipe/CMakeLists.txt @@ -10,9 +10,9 @@ if(ENABLE_PERFTRACING) add_definitions(-DENABLE_PERFTRACING_PAL_TCP) endif (FEATURE_PERFTRACING_PAL_TCP) - if (FEATURE_PERFTRACING_DISABLE_LISTEN_PORTS) + if (FEATURE_PERFTRACING_DISABLE_PERFTRACING_LISTEN_PORTS) add_definitions(-DDISABLE_PERFTRACING_LISTEN_PORTS) - endif (FEATURE_PERFTRACING_DISABLE_LISTEN_PORTS) + endif (FEATURE_PERFTRACING_DISABLE_PERFTRACING_LISTEN_PORTS) if (FEATURE_PERFTRACING_DISABLE_DEFAULT_LISTEN_PORT) add_definitions(-DDISABLE_PERFTRACING_DEFAULT_LISTEN_PORT) From 9d127df3ee90ded24996abfccaa02ecf738046db Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 16:44:45 -0400 Subject: [PATCH 100/128] revert debug printf and commented out code --- .../Tracing/NativeRuntimeEventSource.cs | 1 - .../Diagnostics/Tracing/PollingCounter.cs | 2 -- src/mono/mono/eventpipe/ep-rt-mono.c | 1 - src/mono/mono/eventpipe/ep-rt-mono.h | 10 +--------- src/mono/mono/metadata/threads.c | 1 - src/mono/wasm/build/WasmApp.Native.targets | 2 +- src/native/eventpipe/ds-ipc.c | 20 ++++++++++++++++++- src/native/eventpipe/ep.c | 2 +- 8 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs index 79a7731f5f0ddd..0d97fdedaa2287 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/NativeRuntimeEventSource.cs @@ -38,7 +38,6 @@ private NativeRuntimeEventSource(int _) { } [NonEvent] internal unsafe void ProcessEvent(uint eventID, uint osThreadID, DateTime timeStamp, Guid activityId, Guid childActivityId, ReadOnlySpan payload) { - Internal.Console.WriteLine("STEVE: PROCESSEVENT CALLED"); // A simple fix to avoid dependencies brought by this method if event source is disabled via a feature switch. // Should be reconsidered when https://github.com/dotnet/runtime/issues/43657 is done. if (!IsSupported) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs index 9ea5aa4facb150..40e5a547c2beac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/PollingCounter.cs @@ -48,8 +48,6 @@ public PollingCounter(string name, EventSource eventSource, Func metricP #endif internal override void WritePayload(float intervalSec, int pollingIntervalMillisec) { - Internal.Console.WriteLine("STEVE: WRITING POLLING PAYLOAD"); - lock (this) { double value = 0; diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index e9de1b2a4876ff..096bc198184b0c 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2851,7 +2851,6 @@ ep_rt_mono_execute_rundown (ep_rt_execution_checkpoint_array_t *execution_checkp bool ep_rt_mono_write_event_ee_startup_start (void) { - mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: FIRING ep_rt_mono_write_event_ee_startup_start"); return FireEtwEEStartupStart_V1 ( clr_instance_get_id (), NULL, diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index 52a17a2ad5b04e..40a7e15d3d26f7 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -847,22 +847,14 @@ inline bool ep_rt_config_value_get_enable (void) { - /* bool enable = false; gchar *value = g_getenv ("DOTNET_EnableEventPipe"); if (!value) value = g_getenv ("COMPlus_EnableEventPipe"); - if (value && atoi (value) == 1) { - mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: EnableEventPipe: TRUE"); + if (value && atoi (value) == 1) enable = true; - } - else { - mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_DIAGNOSTICS, "STEVE: EnableEventPipe: FALSE"); - } g_free (value); return enable; - */ - return true; } static diff --git a/src/mono/mono/metadata/threads.c b/src/mono/mono/metadata/threads.c index f5a1a77d4a1ee3..f40e96030d3088 100644 --- a/src/mono/mono/metadata/threads.c +++ b/src/mono/mono/metadata/threads.c @@ -962,7 +962,6 @@ mono_thread_detach_internal (MonoInternalThread *thread) #ifndef HOST_WIN32 add_exiting_thread (thread); - mono_gc_finalize_notify (); #endif diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index a7fba33f36bf91..b92320d735befa 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -208,7 +208,7 @@ <_EmccCFlags Include="$(EmccCompileOptimizationFlag)" /> <_EmccCFlags Include="@(_EmccCommonFlags)" /> - + <_EmccCFlags Include="-DDISABLE_PERFTRACING_LISTEN_PORTS=1" /> <_EmccCFlags Include="-DENABLE_AOT=1" Condition="'$(_WasmShouldAOT)' == 'true'" /> <_EmccCFlags Include="-DDRIVER_GEN=1" Condition="'$(_WasmShouldAOT)' == 'true'" /> <_EmccCFlags Include="-DINVARIANT_GLOBALIZATION=1" Condition="'$(InvariantGlobalization)' == 'true'" /> diff --git a/src/native/eventpipe/ds-ipc.c b/src/native/eventpipe/ds-ipc.c index 51742563724f88..a216a3e4c2babb 100644 --- a/src/native/eventpipe/ds-ipc.c +++ b/src/native/eventpipe/ds-ipc.c @@ -263,7 +263,7 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) bool result = true; ep_char8_t *ports = ds_rt_config_value_get_ports (); - if (0 && ports) { + if (ports) { DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY (port_configs); DS_RT_DECLARE_LOCAL_PORT_CONFIG_ARRAY (port_config_parts); @@ -319,7 +319,25 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) ep_rt_utf8_string_free (ports); } +#ifndef DS_IPC_DISABLE_DEFAULT_LISTEN_PORT + // create the default listen port + uint32_t port_suspend = ds_rt_config_value_get_default_port_suspend (); + + DiagnosticsPortBuilder default_port_builder; + if (ds_port_builder_init (&default_port_builder)) { + default_port_builder.path = NULL; + default_port_builder.suspend_mode = port_suspend > 0 ? DS_PORT_SUSPEND_MODE_SUSPEND : DS_PORT_SUSPEND_MODE_NOSUSPEND; + default_port_builder.type = DS_PORT_TYPE_LISTEN; + + result &= ipc_stream_factory_build_and_add_port (&default_port_builder, callback, true); + + ds_port_builder_fini (&default_port_builder); + } else { + result &= false; + } +#else DS_LOG_DEBUG_0 ("ds_ipc_stream_factory_configure - Ignoring default LISTEN port"); +#endif return result; } diff --git a/src/native/eventpipe/ep.c b/src/native/eventpipe/ep.c index 210bd463a3575b..15e2811b2eb914 100644 --- a/src/native/eventpipe/ep.c +++ b/src/native/eventpipe/ep.c @@ -1026,7 +1026,7 @@ ep_enable_2 ( ep_provider_config_init (&providers [0], ep_rt_utf8_string_dup (ep_config_get_public_provider_name_utf8 ()), 0x4c14fccbd, EP_EVENT_LEVEL_VERBOSE, NULL); ep_provider_config_init (&providers [1], ep_rt_utf8_string_dup (ep_config_get_private_provider_name_utf8 ()), 0x4002000b, EP_EVENT_LEVEL_VERBOSE, NULL); - //ep_provider_config_init (&providers [2], ep_rt_utf8_string_dup (ep_config_get_sample_profiler_provider_name_utf8 ()), 0x0, EP_EVENT_LEVEL_VERBOSE, NULL); + ep_provider_config_init (&providers [2], ep_rt_utf8_string_dup (ep_config_get_sample_profiler_provider_name_utf8 ()), 0x0, EP_EVENT_LEVEL_VERBOSE, NULL); } else { // Count number of providers to parse. while (*providers_config_to_parse != '\0') { From 44f18ffd05380cef1ca2257f7abf689ff47dcd0b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 16:51:42 -0400 Subject: [PATCH 101/128] turn off additional logging --- src/mono/wasm/runtime/driver.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 0304381369756e..fd49e757b0521f 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -472,13 +472,6 @@ mono_wasm_load_runtime (const char *unused, int debug_level) monoeg_g_setenv ("MONO_SLEEP_ABORT_LIMIT", "250", 0); #endif - monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); - monoeg_g_setenv ("MONO_LOG_MASK", "all", 0); - // Setting this env var allows Diagnostic.Debug to write to stderr. In a browser environment this - // output will be sent to the console. Right now this is the only way to emit debug logging from - // corlib assemblies. - monoeg_g_setenv ("COMPlus_DebugWriteToStdErr", "1", 0); - #ifdef DEBUG // monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0); // monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0); From f7d8c1a3aefe2aa621faf9cf36ba82fc1692549c Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 16:57:45 -0400 Subject: [PATCH 102/128] hack: set FeatureWasmPerfTracing in the browser-mt-eventpipe sample It would be better to drive this (the inclusion of the tracing runtime component) from a user-visible flag. not the FeatureWasmPerfTracing implementation detail --- .../browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj | 1 + src/mono/wasm/build/WasmApp.InTree.props | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj index 8439bc84333c3c..124d312b33d21c 100644 --- a/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj +++ b/src/mono/sample/wasm/browser-mt-eventpipe/Wasm.Browser.ThreadsEP.Sample.csproj @@ -9,6 +9,7 @@ true true $(ExecXHarnessCmd) wasm test-browser --app=. --browser=Chrome $(XHarnessBrowserPathArg) --html-file=index.html --output-directory=$(XHarnessOutput) -- $(MSBuildProjectName).dll + true diff --git a/src/mono/wasm/build/WasmApp.InTree.props b/src/mono/wasm/build/WasmApp.InTree.props index 81b2623b25d1de..76c089b8dd4b87 100644 --- a/src/mono/wasm/build/WasmApp.InTree.props +++ b/src/mono/wasm/build/WasmApp.InTree.props @@ -15,7 +15,7 @@ <_MonoRuntimeComponentDontLink Include="libmono-component-debugger-stub-static.a" /> - + <_MonoRuntimeComponentDontLink Include="libmono-component-diagnostics_tracing-static.a" Condition="'$(FeatureWasmPerfTracing)' != 'true'"/> <_MonoRuntimeComponentDontLink Include="libmono-component-hot_reload-stub-static.a" /> From b0ce4e99b31726239acec032a3ba652a8c1a2fdd Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 19:17:17 -0400 Subject: [PATCH 103/128] remove unused variable --- src/mono/mono/utils/mono-threads-wasm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index 9be5c759ee2a81..b2533eb16a0c48 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -115,8 +115,6 @@ mono_native_thread_id_equals (MonoNativeThreadId id1, MonoNativeThreadId id2) return id1 == id2; } -static int pthread_warning_count = 0; - MonoNativeThreadId mono_native_thread_id_get (void) { From fea50587fe4df5758459397b08bfca8616a1886b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 22:57:57 -0400 Subject: [PATCH 104/128] remove unneeded configure checks --- src/mono/cmake/configure.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index 3bc688e2fccdf6..5c07e81258aa6a 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -110,8 +110,6 @@ ac_check_funcs( check_symbol_exists(madvise "sys/mman.h" HAVE_MADVISE) check_symbol_exists(pthread_mutexattr_setprotocol "pthread.h" HAVE_DECL_PTHREAD_MUTEXATTR_SETPROTOCOL) -check_symbol_exists(pthread_getattr_np "pthread.h" HAVE_PTHREAD_GETATTR_NP) -check_symbol_exists(pthread_create "pthread.h" HAVE_STEVE_PTHREAD_CHECK) check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC) check_symbol_exists(CLOCK_MONOTONIC_COARSE "time.h" HAVE_CLOCK_MONOTONIC_COARSE) From f27f834567b7afe900f0d8a2b76b29669a7205f7 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 19 Apr 2022 23:06:48 -0400 Subject: [PATCH 105/128] revert line damage; add better comment in export.ts --- .../ref/System.Threading.Thread.csproj | 2 +- .../src/System.Threading.Thread.csproj | 2 +- src/mono/wasm/emscripten-version.txt | 2 +- src/mono/wasm/runtime/buffers.ts | 2 +- src/mono/wasm/runtime/cs-to-js.ts | 2 +- src/mono/wasm/runtime/exports.ts | 8 ++++++-- src/mono/wasm/runtime/method-binding.ts | 2 +- src/mono/wasm/runtime/method-calls.ts | 2 +- 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj index 0305d28b75161e..8910affc2b9564 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj @@ -16,4 +16,4 @@ - + \ No newline at end of file diff --git a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj index 88a40c4dda0103..51aa452f452a4b 100644 --- a/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/src/System.Threading.Thread.csproj @@ -8,4 +8,4 @@ - + \ No newline at end of file diff --git a/src/mono/wasm/emscripten-version.txt b/src/mono/wasm/emscripten-version.txt index 23887f6eba2bab..d40b13a3fb8833 100644 --- a/src/mono/wasm/emscripten-version.txt +++ b/src/mono/wasm/emscripten-version.txt @@ -1 +1 @@ -3.1.7 +3.1.7 \ No newline at end of file diff --git a/src/mono/wasm/runtime/buffers.ts b/src/mono/wasm/runtime/buffers.ts index cefbf728f5f776..f89b663924f804 100644 --- a/src/mono/wasm/runtime/buffers.ts +++ b/src/mono/wasm/runtime/buffers.ts @@ -202,4 +202,4 @@ export function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr { const heapBytes = new Uint8Array(Module.HEAPU8.buffer, memoryOffset, bytes.length); heapBytes.set(bytes); return memoryOffset; -} +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/cs-to-js.ts b/src/mono/wasm/runtime/cs-to-js.ts index 0d422501c7845e..dcc67dcd6e5851 100644 --- a/src/mono/wasm/runtime/cs-to-js.ts +++ b/src/mono/wasm/runtime/cs-to-js.ts @@ -368,4 +368,4 @@ export function _unbox_ref_type_root_as_js_object(root: WasmRoot): a } return result; -} +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 7964d3f877c0ed..45124fc219aed2 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -294,7 +294,11 @@ function initializeImportsAndExports( configure_emscripten_startup(module, exportedAPI); - // HACK: Maintain compatibility with emscripten's generated dotnet.worker.js + // HACK: Emscripten expects the return value of this function to always be the Module object, + // but we changed ours to return a set of exported namespaces. In order for the emscripten + // generated worker code to keep working, we detect that we're running in a worker (via the + // presence of globalThis.importScripts) and emulate the old behavior. Note that this will + // impact anyone trying to load us in a web worker directly, not just emscripten! if (typeof ((globalThis)["importScripts"]) === "function") return exportedAPI.Module; @@ -414,4 +418,4 @@ class RuntimeList { const wr = this.list[runtimeId]; return wr ? wr.deref() : undefined; } -} +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/method-binding.ts b/src/mono/wasm/runtime/method-binding.ts index 2bf3f6cac49519..6dc3daec9f7c42 100644 --- a/src/mono/wasm/runtime/method-binding.ts +++ b/src/mono/wasm/runtime/method-binding.ts @@ -624,4 +624,4 @@ export type BoundMethodToken = { scratchBuffer: VoidPtr; scratchResultRoot: WasmRoot; scratchExceptionRoot: WasmRoot; -} +} \ No newline at end of file diff --git a/src/mono/wasm/runtime/method-calls.ts b/src/mono/wasm/runtime/method-calls.ts index 316c7990c32c60..52e9d74afee9b6 100644 --- a/src/mono/wasm/runtime/method-calls.ts +++ b/src/mono/wasm/runtime/method-calls.ts @@ -639,4 +639,4 @@ export function mono_wasm_compile_function(code: MonoString, is_exception: Int32 } catch (ex) { return wrap_error(is_exception, ex); } -} +} \ No newline at end of file From ef6477f6958fc7974dee929719f2f23927135ca7 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 20 Apr 2022 09:45:38 -0400 Subject: [PATCH 106/128] Exclude Microsoft.NET.WebAssembly.Threading from testPackages.proj --- src/libraries/testPackages/testPackages.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/testPackages/testPackages.proj b/src/libraries/testPackages/testPackages.proj index a27484cc6580f1..83db541d33f567 100644 --- a/src/libraries/testPackages/testPackages.proj +++ b/src/libraries/testPackages/testPackages.proj @@ -29,6 +29,8 @@ + + From eed9c390017a5a52c2b0ce7a6be5deae0e8660ac Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 20 Apr 2022 09:48:58 -0400 Subject: [PATCH 107/128] review feedback --- src/mono/sample/wasm/wasm.mk | 5 ++++- src/mono/wasm/runtime/startup.ts | 5 ++--- src/mono/wasm/wasm.proj | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/mono/sample/wasm/wasm.mk b/src/mono/sample/wasm/wasm.mk index 8723e576ca31a5..fbe782a3deb95a 100644 --- a/src/mono/sample/wasm/wasm.mk +++ b/src/mono/sample/wasm/wasm.mk @@ -10,6 +10,9 @@ CONFIG?=Release WASM_DEFAULT_BUILD_ARGS?=/p:TargetArchitecture=wasm /p:TargetOS=Browser /p:Configuration=$(CONFIG) +# we set specific headers to enable SharedArrayBuffer support in browsers for threading: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements +CORS_HEADERS?= -h "Cross-Origin-Opener-Policy:same-origin" -h "Cross-Origin-Embedder-Policy:require-corp" + # if we're in a container, don't try to open the browser ifneq ("$(wildcard /.dockerenv)", "") OPEN_BROWSER= @@ -35,7 +38,7 @@ run-browser: echo "The tool dotnet-serve could not be found. Install with: $(DOTNET) tool install --global dotnet-serve"; \ exit 1; \ else \ - $(DOTNET) serve -d:bin/$(CONFIG)/AppBundle -h "Cross-Origin-Opener-Policy:same-origin" -h "Cross-Origin-Embedder-Policy:require-corp" $(OPEN_BROWSER) -p:8000; \ + $(DOTNET) serve -d:bin/$(CONFIG)/AppBundle $(CORS_HEADERS) $(OPEN_BROWSER) -p:8000; \ fi run-console: diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 8eeeb7a7507618..0f5a2e91e9d0b7 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -46,8 +46,7 @@ export function configure_emscripten_startup(module: DotnetModule, exportedAPI: console.log("determined url of main script to be " + temp.href); (module)["mainScriptUrlOrBlob"] = temp.href; } - } else - console.log("could not determine url of main script for workers"); + } // these could be overriden on DotnetModuleConfig if (!module.preInit) { @@ -738,4 +737,4 @@ export type DownloadAssetsContext = { resolved_promises: (MonoInitFetchResult | undefined)[] | null; loaded_files: { url?: string, file: string }[], loaded_assets: { [id: string]: [VoidPtr, number] }, -} \ No newline at end of file +} diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 7c0c42973ebaf3..c89caa7139db7d 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -134,7 +134,6 @@ <_EmccLinkFlags Include="-s EXPORT_ES6=1" Condition="'$(WasmEnableES6)' == 'true'" /> - <_EmccLinkFlags Include="-s LLD_REPORT_UNDEFINED" /> <_EmccLinkFlags Include="-s ALLOW_MEMORY_GROWTH=1" /> <_EmccLinkFlags Include="-s NO_EXIT_RUNTIME=1" /> <_EmccLinkFlags Include="-s FORCE_FILESYSTEM=1" /> From d8a5afbc7d5d127f8309805da95aafb97270b8ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Thu, 21 Apr 2022 11:34:51 -0400 Subject: [PATCH 108/128] Apply suggestions from code review Co-authored-by: Viktor Hofer --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 4 ---- .../System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj | 1 - .../ref/System.Threading.Thread.WebAssembly.Threading.csproj | 1 - .../System.Threading.ThreadPool.WebAssembly.Threading.csproj | 1 - .../apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt | 1 - 5 files changed, 8 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index bf9f8d9c935484..419600c2792209 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -2,12 +2,10 @@ $(NetCoreAppCurrent) Exposes Threading APIs for WebAssembly projects - $(MSBuildProjectName) true false none false - true true true @@ -16,8 +14,6 @@ ref false - false - true diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj index d540a638313a0d..3c65f715727487 100644 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -10,7 +10,6 @@ ref $(DefineConstants);FEATURE_WASM_PERFTRACING - false true diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 8217ba208e32bb..f094a59df79c32 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -14,7 +14,6 @@ ref $(DefineConstants);FEATURE_WASM_THREADS - false true diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj index 17f9c8c48dd8c2..bff5d90878a210 100644 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -14,7 +14,6 @@ ref $(DefineConstants);FEATURE_WASM_THREADS - false true diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt index f17d7d57d32a99..c00a7b08e06e07 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt @@ -145,4 +145,3 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo Compat issues with assembly System.Security.Cryptography.X509Certificates: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. Total Issues: 136 - From f8eddc9f60903d036d8fb951db4a5b42bef4b4e7 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:23:55 -0400 Subject: [PATCH 109/128] Use a testPackages settings file to skip package runtime item verification --- .../Microsoft.NET.WebAssembly.Threading/settings.targets | 5 +++++ src/libraries/testPackages/testPackages.proj | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 src/libraries/testPackages/packageSettings/Microsoft.NET.WebAssembly.Threading/settings.targets diff --git a/src/libraries/testPackages/packageSettings/Microsoft.NET.WebAssembly.Threading/settings.targets b/src/libraries/testPackages/packageSettings/Microsoft.NET.WebAssembly.Threading/settings.targets new file mode 100644 index 00000000000000..a5e5b2e06a0731 --- /dev/null +++ b/src/libraries/testPackages/packageSettings/Microsoft.NET.WebAssembly.Threading/settings.targets @@ -0,0 +1,5 @@ + + + true + + diff --git a/src/libraries/testPackages/testPackages.proj b/src/libraries/testPackages/testPackages.proj index 83db541d33f567..a27484cc6580f1 100644 --- a/src/libraries/testPackages/testPackages.proj +++ b/src/libraries/testPackages/testPackages.proj @@ -29,8 +29,6 @@ - - From 47413d4b1e8cc8089b7c5cab11a4c754368b3f56 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:26:11 -0400 Subject: [PATCH 110/128] remove SIZEOF_VOID_P == 7 check --- src/mono/mono/utils/memfuncs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/utils/memfuncs.c b/src/mono/mono/utils/memfuncs.c index e95553ba9aa71a..4fc78079626abc 100644 --- a/src/mono/mono/utils/memfuncs.c +++ b/src/mono/mono/utils/memfuncs.c @@ -53,7 +53,7 @@ #define unaligned_bytes(ptr) (_toi(ptr) & ptr_mask) #define align_down(ptr) ((void*)(_toi(ptr) & ~ptr_mask)) #define align_up(ptr) ((void*) ((_toi(ptr) + ptr_mask) & ~ptr_mask)) -#if SIZEOF_VOID_P == 4 || SIZEOF_VOID_P == 7 +#if SIZEOF_VOID_P == 4 #define bytes_to_words(n) ((size_t)(n) >> 2) #elif SIZEOF_VOID_P == 8 #define bytes_to_words(n) ((size_t)(n) >> 3) From 28068a36d6e58ef30098f4e664e939fbe021e13b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:28:02 -0400 Subject: [PATCH 111/128] remove unneeded Directory.Build.props for ref package since ti doesn't compile its own assembly, none of these properties are needed --- .../Directory.Build.props | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props b/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props deleted file mode 100644 index ec628faa24a205..00000000000000 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - false - Microsoft - true - - From 52bebbcc657aff341bac7bf06d39d5deca9608df Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:32:51 -0400 Subject: [PATCH 112/128] use one ProjectReference item to share metadata for the ref assemblies --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 419600c2792209..11602c5a6035e5 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -17,9 +17,11 @@ - - - + From ea174d3f66c78023d7acfc27deac9034a8eed20b Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:33:40 -0400 Subject: [PATCH 113/128] remove ProjectReference comment and NoTargetsDoNotReferenceOutputAssemblies prop --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 11602c5a6035e5..bb257f79feb02f 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -12,8 +12,6 @@ $(NoWarn);NU5128;NU5131 ref - - false From 2716d3c5b177043b095b904029ee99ac16a9d963 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 12:34:46 -0400 Subject: [PATCH 114/128] Remove unneeded target --- .../src/Microsoft.NET.WebAssembly.Threading.proj | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index bb257f79feb02f..590f994827dc39 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -22,13 +22,6 @@ Pack="true" PrivateAssets="all" Private="true" IncludeReferenceAssemblyInPackage="true" /> - - - - - - - From 068759926947372059c443c1a821b37d47e14b91 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 21 Apr 2022 15:21:34 -0400 Subject: [PATCH 115/128] packaging simplification - move `_ExperimentalUpdateFileVersion` target to packaging.targets, conditioned on a new `IsExperimentalRefAssembly` attribute. (The target increments the file version of the ref assembly to make it easier to distinguish from the real non-experimental ref assembly) - Remove unneeded src subdirectories in ref assembly libraries - Move properties that are only used in the ref assembly projects directory into the projects and delete Directory.Build.props in the experimental ref assembly subdirectories. --- eng/packaging.targets | 16 ++++++++++++++++ .../src/Microsoft.NET.WebAssembly.Threading.proj | 11 ----------- .../Directory.Build.props | 9 --------- ...ostics.Tracing.WebAssembly.PerfTracing.csproj | 16 ++++++---------- .../Directory.Build.props | 9 --------- ...Threading.Thread.WebAssembly.Threading.csproj | 16 ++++++---------- ...Threading.Thread.WebAssembly.Threading.csproj | 8 -------- .../Directory.Build.props | 9 --------- ...ading.ThreadPool.WebAssembly.Threading.csproj | 16 ++++++---------- ...ading.ThreadPool.WebAssembly.Threading.csproj | 8 -------- 10 files changed, 34 insertions(+), 84 deletions(-) delete mode 100644 src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props delete mode 100644 src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props delete mode 100644 src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj delete mode 100644 src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props delete mode 100644 src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj diff --git a/eng/packaging.targets b/eng/packaging.targets index 1abe280c590bb0..9ab412728053ca 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -269,4 +269,20 @@ + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 590f994827dc39..955da9204185fe 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -22,15 +22,4 @@ Pack="true" PrivateAssets="all" Private="true" IncludeReferenceAssemblyInPackage="true" /> - - - <_FileVersionMaj>$(FileVersion.Split('.')[0]) - <_FileVersionMin>$(FileVersion.Split('.')[1]) - <_FileVersionBld>$(FileVersion.Split('.')[2]) - <_FileVersionRev>$(FileVersion.Split('.')[3]) - $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) - - - diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props deleted file mode 100644 index 2589cb58682917..00000000000000 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - false - Microsoft - true - - diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj index 3c65f715727487..7801fcda13d8b7 100644 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -5,6 +5,12 @@ $(NetCoreAppCurrent) enable true + + true + + false + Microsoft + true @@ -19,14 +25,4 @@ - - - <_FileVersionMaj>$(FileVersion.Split('.')[0]) - <_FileVersionMin>$(FileVersion.Split('.')[1]) - <_FileVersionBld>$(FileVersion.Split('.')[2]) - <_FileVersionRev>$(FileVersion.Split('.')[3]) - $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) - - diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props b/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props deleted file mode 100644 index a7613cae13b445..00000000000000 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - false - Microsoft - true - - diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index f094a59df79c32..21b58c679df04a 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -9,6 +9,12 @@ $(NoWarn);0809;0618;CS8614;CS3015;NU5131 $(NetCoreAppCurrent) enable + + true + + false + Microsoft + true @@ -25,14 +31,4 @@ - - - <_FileVersionMaj>$(FileVersion.Split('.')[0]) - <_FileVersionMin>$(FileVersion.Split('.')[1]) - <_FileVersionBld>$(FileVersion.Split('.')[2]) - <_FileVersionRev>$(FileVersion.Split('.')[3]) - $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) - - diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj deleted file mode 100644 index 5a18d5a9a7d19c..00000000000000 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/src/System.Threading.Thread.WebAssembly.Threading.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props deleted file mode 100644 index a7613cae13b445..00000000000000 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/Directory.Build.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - false - Microsoft - true - - diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj index bff5d90878a210..b1775539ea0323 100644 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -9,6 +9,12 @@ $(NoWarn);0809;0618;CS8614;CS3015;NU5131 $(NetCoreAppCurrent) enable + + true + + false + Microsoft + true @@ -23,14 +29,4 @@ - - - <_FileVersionMaj>$(FileVersion.Split('.')[0]) - <_FileVersionMin>$(FileVersion.Split('.')[1]) - <_FileVersionBld>$(FileVersion.Split('.')[2]) - <_FileVersionRev>$(FileVersion.Split('.')[3]) - $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) - - diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj deleted file mode 100644 index 5a18d5a9a7d19c..00000000000000 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/src/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From 52e05a14ed6295107e3bd801834b94d1486a16ef Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 22 Apr 2022 10:47:12 -0400 Subject: [PATCH 116/128] move and rename UpdateExperimentalRefAssemblyFileVersion target packages.targets is only included for IsPackable=true projects, and these ref assemblies are not packable. --- eng/packaging.targets | 16 ---------------- eng/references.targets | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/eng/packaging.targets b/eng/packaging.targets index 9ab412728053ca..1abe280c590bb0 100644 --- a/eng/packaging.targets +++ b/eng/packaging.targets @@ -269,20 +269,4 @@ - - - - - <_FileVersionMaj>$(FileVersion.Split('.')[0]) - <_FileVersionMin>$(FileVersion.Split('.')[1]) - <_FileVersionBld>$(FileVersion.Split('.')[2]) - <_FileVersionRev>$(FileVersion.Split('.')[3]) - $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) - - diff --git a/eng/references.targets b/eng/references.targets index bdb7faeed36b2b..5b7418b38e61f1 100644 --- a/eng/references.targets +++ b/eng/references.targets @@ -91,4 +91,20 @@ Condition="$(NetCoreAppLibraryNoReference.Contains('%(Filename);'))" /> + + + + + <_FileVersionMaj>$(FileVersion.Split('.')[0]) + <_FileVersionMin>$(FileVersion.Split('.')[1]) + <_FileVersionBld>$(FileVersion.Split('.')[2]) + <_FileVersionRev>$(FileVersion.Split('.')[3]) + $(_FileVersionMaj).$([MSBuild]::Add($(_FileVersionMin), 100)).$(_FileVersionBld).$(_FileVersionRev) + + From 0cfbc2b8e5f752eee40597911bae0a678bd382c6 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 22 Apr 2022 12:29:04 -0400 Subject: [PATCH 117/128] Assorted code review nits --- .../Microsoft.NET.WebAssembly.Threading.proj | 2 +- ...ics.Tracing.WebAssembly.PerfTracing.csproj | 11 ++++------- ...eading.Thread.WebAssembly.Threading.csproj | 19 ++++++------------- ...ng.ThreadPool.WebAssembly.Threading.csproj | 15 ++++----------- 4 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj index 955da9204185fe..c9b7e5207f0f4b 100644 --- a/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj +++ b/src/libraries/Microsoft.NET.WebAssembly.Threading/src/Microsoft.NET.WebAssembly.Threading.proj @@ -1,13 +1,13 @@ $(NetCoreAppCurrent) - Exposes Threading APIs for WebAssembly projects true false none false true true + Exposes Threading APIs for WebAssembly projects $(NoWarn);NU5128;NU5131 diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj index 7801fcda13d8b7..5aa20cfc95be79 100644 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -1,22 +1,19 @@ - System.Diagnostics.Tracing true $(NetCoreAppCurrent) enable true - + System.Diagnostics.Tracing + true false Microsoft true - - - ref - $(DefineConstants);FEATURE_WASM_PERFTRACING - true + + $(DefineConstants);FEATURE_WASM_PERFTRACING diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 21b58c679df04a..5122eeccc7cb01 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -1,26 +1,19 @@ - System.Threading.Thread - true - true - - $(NoWarn);0809;0618;CS8614;CS3015;NU5131 $(NetCoreAppCurrent) enable - + true + System.Threading.Thread + true + true false Microsoft true - - - ref - $(DefineConstants);FEATURE_WASM_THREADS - true + + $(DefineConstants);FEATURE_WASM_THREADS diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj index b1775539ea0323..682978f5aefef9 100644 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -2,25 +2,18 @@ System.Threading.ThreadPool true - true - - $(NoWarn);0809;0618;CS8614;CS3015;NU5131 $(NetCoreAppCurrent) enable - + true + true false Microsoft true - - - ref - $(DefineConstants);FEATURE_WASM_THREADS - true + + $(DefineConstants);FEATURE_WASM_THREADS From 262ad4e23459bfed6e8bad6b542aaa78c3c07fcb Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 11:35:30 -0400 Subject: [PATCH 118/128] Don't build/pack the multi-threaded sample on single-threaded runtime --- src/libraries/tests.proj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 28da0380667321..f0f42d40a4ec12 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -50,6 +50,11 @@ + + + + + From cb2afa559c737e047a4f0e0de81f976d40f04d9c Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 11:48:39 -0400 Subject: [PATCH 119/128] remove gratuitous debug printfs --- src/mono/mono/utils/mono-threads-wasm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/utils/mono-threads-wasm.c b/src/mono/mono/utils/mono-threads-wasm.c index b2533eb16a0c48..8da132a23b772f 100644 --- a/src/mono/mono/utils/mono-threads-wasm.c +++ b/src/mono/mono/utils/mono-threads-wasm.c @@ -8,6 +8,7 @@ #include #include +#include #include @@ -331,13 +332,13 @@ mono_threads_schedule_background_job (background_job_cb cb) { #ifndef DISABLE_THREADS if (!mono_threads_wasm_is_browser_thread ()) { - fprintf(stdout, "worker %p queued job %p\n", (gpointer)pthread_self(), (gpointer) cb); + THREADS_DEBUG ("worker %p queued job %p\n", (gpointer)pthread_self(), (gpointer) cb); mono_threads_wasm_async_run_in_main_thread_vi ((void (*)(gpointer))mono_threads_schedule_background_job, cb); return; } #endif - fprintf(stdout, "main thread queued job %p\n", (gpointer) cb); + THREADS_DEBUG ("main thread queued job %p\n", (gpointer) cb); if (!jobs) schedule_background_exec (); From dc1f1f694a562e6801fe1317a58e195cbb7c020f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Mon, 25 Apr 2022 11:54:24 -0400 Subject: [PATCH 120/128] Apply suggestions from code review Co-authored-by: Viktor Hofer --- .../System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj | 2 -- .../ref/System.Diagnostics.Tracing.csproj | 2 -- .../ref/System.Threading.Thread.WebAssembly.Threading.csproj | 2 -- .../System.Threading.Thread/ref/System.Threading.Thread.csproj | 2 -- .../System.Threading.ThreadPool.WebAssembly.Threading.csproj | 2 -- .../ref/System.Threading.ThreadPool.csproj | 2 -- 6 files changed, 12 deletions(-) diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj index 5aa20cfc95be79..0b76a14905552f 100644 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -11,8 +11,6 @@ false Microsoft true - - $(DefineConstants);FEATURE_WASM_PERFTRACING diff --git a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj index 39f5564a1b8f25..b8755eaf6e4a9a 100644 --- a/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing/ref/System.Diagnostics.Tracing.csproj @@ -4,8 +4,6 @@ $(NetCoreAppCurrent) enable false - - $(DefineConstants);FEATURE_WASM_PERFTRACING diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 5122eeccc7cb01..5f7dd71b319e3f 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -11,8 +11,6 @@ false Microsoft true - - $(DefineConstants);FEATURE_WASM_THREADS diff --git a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj index 8910affc2b9564..dcdad66bd3a25f 100644 --- a/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj +++ b/src/libraries/System.Threading.Thread/ref/System.Threading.Thread.csproj @@ -3,8 +3,6 @@ $(NetCoreAppCurrent) enable false - - $(DefineConstants);FEATURE_WASM_THREADS diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj index 682978f5aefef9..644e011481c528 100644 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -11,8 +11,6 @@ false Microsoft true - - $(DefineConstants);FEATURE_WASM_THREADS diff --git a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj index d7330bfe72150e..407aa0378c85b6 100644 --- a/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj +++ b/src/libraries/System.Threading.ThreadPool/ref/System.Threading.ThreadPool.csproj @@ -4,8 +4,6 @@ $(NetCoreAppCurrent) enable false - - $(DefineConstants);FEATURE_WASM_THREADS From edbb341dce26e3ec36fe1ae6bfd119a757a7d275 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 12:22:14 -0400 Subject: [PATCH 121/128] merge followup: nullable is enabled by default now --- .../System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj | 1 - .../ref/System.Threading.Thread.WebAssembly.Threading.csproj | 1 - .../ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj | 1 - 3 files changed, 3 deletions(-) diff --git a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj index 0b76a14905552f..f639277acdb371 100644 --- a/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj +++ b/src/libraries/System.Diagnostics.Tracing.WebAssembly.PerfTracing/ref/System.Diagnostics.Tracing.WebAssembly.PerfTracing.csproj @@ -2,7 +2,6 @@ true $(NetCoreAppCurrent) - enable true System.Diagnostics.Tracing diff --git a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj index 5f7dd71b319e3f..341b1140e37782 100644 --- a/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.Thread.WebAssembly.Threading/ref/System.Threading.Thread.WebAssembly.Threading.csproj @@ -1,7 +1,6 @@ $(NetCoreAppCurrent) - enable true System.Threading.Thread true diff --git a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj index 644e011481c528..8afbfd514f9b24 100644 --- a/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj +++ b/src/libraries/System.Threading.ThreadPool.WebAssembly.Threading/ref/System.Threading.ThreadPool.WebAssembly.Threading.csproj @@ -3,7 +3,6 @@ System.Threading.ThreadPool true $(NetCoreAppCurrent) - enable true true From 96e8f2f6d9574f6d4c60eae78727adc0f679b939 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 13:14:28 -0400 Subject: [PATCH 122/128] make eslint happy --- src/mono/wasm/runtime/startup.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 0f5a2e91e9d0b7..a8f3b7ce85b957 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -35,17 +35,18 @@ export function configure_emscripten_startup(module: DotnetModule, exportedAPI: (typeof (globalThis.document) === "object") && (typeof (globalThis.document.createElement) === "function") ) { - // blazor injects a module preload link element for dotnet.[version].[sha].js - let x = Array.from (document.head.getElementsByTagName('link')).filter(elt => elt.rel !== undefined && elt.rel == 'modulepreload' && elt.href !== undefined && elt.href.indexOf('dotnet') != -1 && elt.href.indexOf ('.js') != -1); - if (x.length == 1) { - console.log("determined url of main script to be " + x[0].href); - (module)["mainScriptUrlOrBlob"] = x[0].href; - } else { - const temp = globalThis.document.createElement("a"); - temp.href = "dotnet.js"; - console.log("determined url of main script to be " + temp.href); - (module)["mainScriptUrlOrBlob"] = temp.href; - } + // blazor injects a module preload link element for dotnet.[version].[sha].js + const blazorDotNetJS = Array.from (document.head.getElementsByTagName("link")).filter(elt => elt.rel !== undefined && elt.rel == "modulepreload" && elt.href !== undefined && elt.href.indexOf("dotnet") != -1 && elt.href.indexOf (".js") != -1); + if (blazorDotNetJS.length == 1) { + const hr = blazorDotNetJS[0].href; + console.log("determined url of main script to be " + hr); + (module)["mainScriptUrlOrBlob"] = hr; + } else { + const temp = globalThis.document.createElement("a"); + temp.href = "dotnet.js"; + console.log("determined url of main script to be " + temp.href); + (module)["mainScriptUrlOrBlob"] = temp.href; + } } // these could be overriden on DotnetModuleConfig From 1f2eda00369930025897a25ab523d57ecc291f8d Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 13:36:24 -0400 Subject: [PATCH 123/128] include wasm-config.h in wasm runtime host --- src/mono/wasm/runtime/corebindings.c | 1 + src/mono/wasm/runtime/driver.c | 1 + src/mono/wasm/runtime/pinvoke.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/mono/wasm/runtime/corebindings.c b/src/mono/wasm/runtime/corebindings.c index 8cc2ff15a1ed4d..8d6d29cd947681 100644 --- a/src/mono/wasm/runtime/corebindings.c +++ b/src/mono/wasm/runtime/corebindings.c @@ -13,6 +13,7 @@ #include #include +#include "wasm-config.h" #include "gc-common.h" //JS funcs diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index fd49e757b0521f..3a5977ee2c9657 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -28,6 +28,7 @@ #include #include +#include "wasm-config.h" #include "pinvoke.h" #include "gc-common.h" diff --git a/src/mono/wasm/runtime/pinvoke.c b/src/mono/wasm/runtime/pinvoke.c index 3804005cb5adb4..eb422204826474 100644 --- a/src/mono/wasm/runtime/pinvoke.c +++ b/src/mono/wasm/runtime/pinvoke.c @@ -1,3 +1,4 @@ +#include "wasm-config.h" #include "pinvoke.h" #include From d44167c4bb486afecfcd0a56565137e69ff30c63 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 13:45:19 -0400 Subject: [PATCH 124/128] add wasm-config.h directory to includde directories --- src/mono/wasm/runtime/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index e1bc88ce41e74c..b12a5068d8a417 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -8,7 +8,7 @@ option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threa set(CMAKE_EXECUTABLE_SUFFIX ".js") add_executable(dotnet corebindings.c driver.c pinvoke.c) -target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES}) +target_include_directories(dotnet PUBLIC ${MONO_INCLUDES} ${MONO_OBJ_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}) target_compile_options(dotnet PUBLIC @${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-compile.rsp -DCORE_BINDINGS -DGEN_PINVOKE=1) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_EMCC_FLAGS}) From abf83352e9572db1bb4d791e39c09befda15fb07 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 14:04:20 -0400 Subject: [PATCH 125/128] include wasm-config.h into the runtime pack fixes aot compilation --- src/mono/wasm/wasm.proj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index c89caa7139db7d..79b4160a943ace 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -264,6 +264,7 @@ + + From 051356de8ad8bacb62fc7267218efff767be6234 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 25 Apr 2022 18:43:31 -0400 Subject: [PATCH 127/128] put wasm-config.h into include/wasm from the outset --- src/mono/wasm/runtime/CMakeLists.txt | 4 ++-- src/mono/wasm/wasm.proj | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index b12a5068d8a417..dac8d63e719d35 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -8,7 +8,7 @@ option(DISABLE_WASM_USER_THREADS "defined if the build does not allow user threa 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}) +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) set_target_properties(dotnet PROPERTIES COMPILE_FLAGS ${CONFIGURATION_EMCC_FLAGS}) @@ -37,4 +37,4 @@ if(CMAKE_BUILD_TYPE STREQUAL "Release") add_custom_command(TARGET dotnet POST_BUILD COMMAND ${EMSDK_PATH}/upstream/bin/wasm-opt --enable-exception-handling --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.wasm -o ${NATIVE_BIN_DIR}/dotnet.wasm) endif() -configure_file(wasm-config.h.in wasm-config.h) +configure_file(wasm-config.h.in include/wasm/wasm-config.h) diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 79b4160a943ace..c89caa7139db7d 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -264,7 +264,6 @@ -