diff --git a/src/mono/wasm/runtime/cwraps.ts b/src/mono/wasm/runtime/cwraps.ts index 4026be432c3004..58ab6a3a40f747 100644 --- a/src/mono/wasm/runtime/cwraps.ts +++ b/src/mono/wasm/runtime/cwraps.ts @@ -100,6 +100,7 @@ const fn_signatures: SigLine[] = [ [true, "mono_wasm_get_i32_unaligned", "number", ["number"]], [true, "mono_wasm_get_f32_unaligned", "number", ["number"]], [true, "mono_wasm_get_f64_unaligned", "number", ["number"]], + [true, "mono_wasm_read_as_bool_or_null_unsafe", "number", ["number"]], // jiterpreter [true, "mono_jiterp_trace_bailout", "void", ["number"]], @@ -240,6 +241,7 @@ export interface t_Cwraps { mono_wasm_get_i32_unaligned(source: VoidPtr): number; mono_wasm_get_f32_unaligned(source: VoidPtr): number; mono_wasm_get_f64_unaligned(source: VoidPtr): number; + mono_wasm_read_as_bool_or_null_unsafe(obj: MonoObject): number; mono_jiterp_trace_bailout(reason: number): void; mono_jiterp_get_trace_bailout_count(reason: number): number; diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index d7e729e669b62a..793a607a8196f3 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -969,6 +969,34 @@ mono_wasm_get_type_aqn (MonoType * typePtr) { return mono_type_get_name_full (typePtr, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED); } +// this will return bool value if the object is a bool, otherwise it will return -1 or error +EMSCRIPTEN_KEEPALIVE int +mono_wasm_read_as_bool_or_null_unsafe (PVOLATILE(MonoObject) obj) { + + int result = -1; + + MONO_ENTER_GC_UNSAFE; + + MonoClass *klass = mono_object_get_class (obj); + if (!klass) { + goto end; + } + + MonoType *type = mono_class_get_type (klass); + if (!type) { + goto end; + } + + int mono_type = mono_type_get_type (type); + if (MONO_TYPE_BOOLEAN == mono_type) { + result = ((signed char*)mono_object_unbox (obj) == 0 ? 0 : 1); + } + + end: + MONO_EXIT_GC_UNSAFE; + return result; +} + // This code runs inside a gc unsafe region static int _mono_wasm_try_unbox_primitive_and_get_type_ref_impl (PVOLATILE(MonoObject) obj, void *result, int result_capacity) { diff --git a/src/mono/wasm/runtime/exports-internal.ts b/src/mono/wasm/runtime/exports-internal.ts index 88e7d009d38dbc..13c7ec160d1b0b 100644 --- a/src/mono/wasm/runtime/exports-internal.ts +++ b/src/mono/wasm/runtime/exports-internal.ts @@ -18,6 +18,8 @@ import { loadLazyAssembly } from "./lazyLoading"; import { loadSatelliteAssemblies } from "./satelliteAssemblies"; import { forceDisposeProxies } from "./gc-handles"; import { mono_wasm_get_func_id_to_name_mappings } from "./logging"; +import { MonoObject, MonoObjectNull } from "./types/internal"; +import { monoStringToStringUnsafe } from "./strings"; export function export_internal(): any { return { @@ -96,6 +98,10 @@ export function export_internal(): any { mono_wasm_gc_lock, mono_wasm_gc_unlock, + // Blazor legacy replacement + monoObjectAsBoolOrNullUnsafe, + monoStringToStringUnsafe, + loadLazyAssembly, loadSatelliteAssemblies }; @@ -110,3 +116,18 @@ export function cwraps_internal(internal: any): void { mono_wasm_exec_regression: cwraps.mono_wasm_exec_regression, }); } + +/* @deprecated not GC safe, legacy support for Blazor */ +export function monoObjectAsBoolOrNullUnsafe(obj: MonoObject): boolean | null { + if (obj === MonoObjectNull) { + return null; + } + const res = cwraps.mono_wasm_read_as_bool_or_null_unsafe(obj); + if (res === 0) { + return false; + } + if (res === 1) { + return true; + } + return null; +} diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts index 6e50e26e164c0c..0e594c4cd0d8c0 100644 --- a/src/mono/wasm/runtime/exports.ts +++ b/src/mono/wasm/runtime/exports.ts @@ -101,9 +101,11 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI { } }); }; - globalThisAny.MONO = globals.mono; - globalThisAny.BINDING = globals.binding; - globalThisAny.INTERNAL = globals.internal; + if (WasmEnableLegacyJsInterop && !linkerDisableLegacyJsInterop) { + globalThisAny.MONO = globals.mono; + globalThisAny.BINDING = globals.binding; + globalThisAny.INTERNAL = globals.internal; + } globalThisAny.Module = module; // Blazor back compat diff --git a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts index 1400f7f84ed263..f93a3d13c53fd5 100644 --- a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts +++ b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts @@ -10,13 +10,12 @@ import { wrap_error_root, wrap_no_error_root } from "../invoke-js"; import { ManagedObject } from "../marshal"; import { getU32, getI32, getF32, getF64, setI32_unchecked } from "../memory"; import { mono_wasm_new_root, mono_wasm_new_external_root } from "../roots"; -import { monoStringToString } from "../strings"; +import { monoStringToString, monoStringToStringUnsafe } from "../strings"; import { legacyManagedExports } from "./corebindings"; import { legacyHelpers } from "./globals"; import { js_to_mono_obj_root } from "./js-to-cs"; import { assert_legacy_interop, mono_bind_method, mono_method_get_call_signature_ref } from "./method-binding"; import { createPromiseController } from "../globals"; -import { monoStringToStringUnsafe } from "./strings"; const delegate_invoke_symbol = Symbol.for("wasm delegate_invoke"); diff --git a/src/mono/wasm/runtime/net6-legacy/strings.ts b/src/mono/wasm/runtime/net6-legacy/strings.ts index 1f6dadab26173f..f651100c672902 100644 --- a/src/mono/wasm/runtime/net6-legacy/strings.ts +++ b/src/mono/wasm/runtime/net6-legacy/strings.ts @@ -3,10 +3,9 @@ import { mono_assert } from "../globals"; import { mono_wasm_new_root } from "../roots"; -import { interned_string_table, monoStringToString, mono_wasm_empty_string, stringToInternedMonoStringRoot, stringToMonoStringRoot } from "../strings"; -import { MonoString, MonoStringNull, is_nullish } from "../types/internal"; +import { interned_string_table, mono_wasm_empty_string, stringToInternedMonoStringRoot, stringToMonoStringRoot } from "../strings"; +import { MonoString, is_nullish } from "../types/internal"; -let mono_wasm_string_root: any; import { assert_legacy_interop } from "./method-binding"; /** @@ -39,16 +38,3 @@ export function stringToMonoStringIntern(string: string): string { root.release(); } } -/* @deprecated not GC safe, use monoStringToString */ -export function monoStringToStringUnsafe(mono_string: MonoString): string | null { - if (mono_string === MonoStringNull) - return null; - assert_legacy_interop(); - if (!mono_wasm_string_root) - mono_wasm_string_root = mono_wasm_new_root(); - - mono_wasm_string_root.value = mono_string; - const result = monoStringToString(mono_wasm_string_root); - mono_wasm_string_root.value = MonoStringNull; - return result; -} diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts index a03d478973a53f..9058f29d0bf2a9 100644 --- a/src/mono/wasm/runtime/strings.ts +++ b/src/mono/wasm/runtime/strings.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_buffer } from "./roots"; +import { mono_wasm_new_root, mono_wasm_new_root_buffer } from "./roots"; import { MonoString, MonoStringNull, WasmRoot, WasmRootBuffer } from "./types/internal"; import { Module } from "./globals"; import cwraps from "./cwraps"; @@ -248,4 +248,20 @@ export function viewOrCopy(view: Uint8Array, start: CharPtr, end: CharPtr): Uint return needsCopy ? view.slice(start, end) : view.subarray(start, end); -} \ No newline at end of file +} + +// below is minimal legacy support for Blazor +let mono_wasm_string_root: any; + +/* @deprecated not GC safe, use monoStringToString */ +export function monoStringToStringUnsafe(mono_string: MonoString): string | null { + if (mono_string === MonoStringNull) + return null; + if (!mono_wasm_string_root) + mono_wasm_string_root = mono_wasm_new_root(); + + mono_wasm_string_root.value = mono_string; + const result = monoStringToString(mono_wasm_string_root); + mono_wasm_string_root.value = MonoStringNull; + return result; +}