Skip to content

Commit

Permalink
[browser] fix bit width from 32 to 8 for managed boolean (#100304)
Browse files Browse the repository at this point in the history
* wip

* more

* feedback

* comments

* more
  • Loading branch information
pavelsavara committed Mar 27, 2024
1 parent 748b61e commit 3a447e4
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public partial struct JSMarshalerArgument
internal struct JSMarshalerArgumentImpl
{
[FieldOffset(0)]
internal bool BooleanValue;
internal bool BooleanValue; // note this is 1 byte
[FieldOffset(0)]
internal byte ByteValue;
[FieldOffset(0)]
Expand Down Expand Up @@ -64,7 +64,7 @@ internal struct JSMarshalerArgumentImpl
internal IntPtr ContextHandle;

[FieldOffset(20)]
internal bool ReceiverShouldFree;
internal bool ReceiverShouldFree; // note this is 1 byte

[FieldOffset(24)]
internal IntPtr CallerNativeTID;
Expand Down
8 changes: 8 additions & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,10 @@ type APIType = {
* Writes to the WASM linear memory
*/
setHeapB32: (offset: NativePointer, value: number | boolean) => void;
/**
* Writes to the WASM linear memory
*/
setHeapB8: (offset: NativePointer, value: number | boolean) => void;
/**
* Writes to the WASM linear memory
*/
Expand Down Expand Up @@ -531,6 +535,10 @@ type APIType = {
* Reads from the WASM linear memory
*/
getHeapB32: (offset: NativePointer) => boolean;
/**
* Reads from the WASM linear memory
*/
getHeapB8: (offset: NativePointer) => boolean;
/**
* Reads from the WASM linear memory
*/
Expand Down
4 changes: 3 additions & 1 deletion src/mono/browser/runtime/export-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { MonoConfig, APIType } from "./types";

import { mono_wasm_get_assembly_exports } from "./invoke-cs";
import { mono_wasm_set_module_imports } from "./invoke-js";
import { getB32, getF32, getF64, getI16, getI32, getI52, getI64Big, getI8, getU16, getU32, getU52, getU8, localHeapViewF32, localHeapViewF64, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewI8, localHeapViewU16, localHeapViewU32, localHeapViewU8, setB32, setF32, setF64, setI16, setI32, setI52, setI64Big, setI8, setU16, setU32, setU52, setU8 } from "./memory";
import { getB32, getB8, getF32, getF64, getI16, getI32, getI52, getI64Big, getI8, getU16, getU32, getU52, getU8, localHeapViewF32, localHeapViewF64, localHeapViewI16, localHeapViewI32, localHeapViewI64Big, localHeapViewI8, localHeapViewU16, localHeapViewU32, localHeapViewU8, setB32, setB8, setF32, setF64, setI16, setI32, setI52, setI64Big, setI8, setU16, setU32, setU52, setU8 } from "./memory";
import { mono_run_main, mono_run_main_and_exit } from "./run";
import { mono_wasm_setenv } from "./startup";
import { loaderHelpers, runtimeHelpers } from "./globals";
Expand All @@ -23,6 +23,7 @@ export function export_api(): any {
},
invokeLibraryInitializers: loaderHelpers.invokeLibraryInitializers,
setHeapB32: setB32,
setHeapB8: setB8,
setHeapU8: setU8,
setHeapU16: setU16,
setHeapU32: setU32,
Expand All @@ -35,6 +36,7 @@ export function export_api(): any {
setHeapF32: setF32,
setHeapF64: setF64,
getHeapB32: getB32,
getHeapB8: getB8,
getHeapU8: getU8,
getHeapU16: getU16,
getHeapU32: getU32,
Expand Down
10 changes: 5 additions & 5 deletions src/mono/browser/runtime/marshal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import WasmEnableThreads from "consts:wasmEnableThreads";

import { js_owned_gc_handle_symbol, teardown_managed_proxy } from "./gc-handles";
import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
import { getF32, getF64, getI16, getI32, getI64Big, getU16, getU32, getU8, setF32, setF64, setI16, setI32, setI64Big, setU16, setU32, setU8, localHeapViewF64, localHeapViewI32, localHeapViewU8, _zero_region, getB32, setB32, forceThreadMemoryViewRefresh } from "./memory";
import { getF32, getF64, getI16, getI32, getI64Big, getU16, getU32, getU8, setF32, setF64, setI16, setI32, setI64Big, setU16, setU32, setU8, localHeapViewF64, localHeapViewI32, localHeapViewU8, _zero_region, forceThreadMemoryViewRefresh, setB8, getB8 } from "./memory";
import { mono_wasm_new_external_root } from "./roots";
import { GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerArguments, JSFunctionSignature, JSMarshalerType, JSMarshalerArgument, MarshalerToJs, MarshalerToCs, WasmRoot, MarshalerType, PThreadPtr, PThreadPtrNull, VoidPtrNull } from "./types/internal";
import { TypedArray, VoidPtr } from "./types/emscripten";
Expand Down Expand Up @@ -89,7 +89,7 @@ export function is_args_exception(args: JSMarshalerArguments): boolean {
export function is_receiver_should_free(args: JSMarshalerArguments): boolean {
if (!WasmEnableThreads) return false;
mono_assert(args, "Null args");
return getB32(<any>args + JSMarshalerArgumentOffsets.ReceiverShouldFree);
return getB8(<any>args + JSMarshalerArgumentOffsets.ReceiverShouldFree);
}

export function get_sync_done_semaphore_ptr(args: JSMarshalerArguments): VoidPtr {
Expand All @@ -106,7 +106,7 @@ export function get_caller_native_tid(args: JSMarshalerArguments): PThreadPtr {

export function set_receiver_should_free(args: JSMarshalerArguments): void {
mono_assert(args, "Null args");
setB32(<any>args + JSMarshalerArgumentOffsets.ReceiverShouldFree, true);
setB8(<any>args + JSMarshalerArgumentOffsets.ReceiverShouldFree, true);
}

export function set_args_context(args: JSMarshalerArguments): void {
Expand Down Expand Up @@ -209,7 +209,7 @@ export function set_arg_element_type(arg: JSMarshalerArgument, type: MarshalerTy

export function get_arg_bool(arg: JSMarshalerArgument): boolean {
mono_assert(arg, "Null arg");
return !!getU8(<any>arg);
return getB8(<any>arg);
}

export function get_arg_u8(arg: JSMarshalerArgument): number {
Expand Down Expand Up @@ -268,7 +268,7 @@ export function get_arg_f64(arg: JSMarshalerArgument): number {
export function set_arg_bool(arg: JSMarshalerArgument, value: boolean): void {
mono_assert(arg, "Null arg");
mono_check(typeof value === "boolean", () => `Value is not a Boolean: ${value} (${typeof (value)})`);
setB32(<any>arg, value ? 1 : 0);
setB8(<any>arg, value);
}

export function set_arg_u8(arg: JSMarshalerArgument, value: number): void {
Expand Down
24 changes: 23 additions & 1 deletion src/mono/browser/runtime/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { VoidPtr, CharPtr } from "./types/emscripten";
import cwraps, { I52Error } from "./cwraps";
import { Module, mono_assert, runtimeHelpers } from "./globals";
import { utf8ToString } from "./strings";
import { mono_log_warn } from "./logging";

const alloca_stack: Array<VoidPtr> = [];
const alloca_buffer_size = 32 * 1024;
Expand Down Expand Up @@ -58,6 +59,7 @@ export function _zero_region(byteOffset: VoidPtr, sizeBytes: number): void {
localHeapViewU8().fill(0, <any>byteOffset, <any>byteOffset + sizeBytes);
}

/** note: MonoBoolean is 8 bits not 32 bits when inside a structure or array */
export function setB32(offset: MemOffset, value: number | boolean): void {
receiveWorkerHeapViews();
const boolValue = !!value;
Expand All @@ -66,6 +68,14 @@ export function setB32(offset: MemOffset, value: number | boolean): void {
Module.HEAP32[<any>offset >>> 2] = boolValue ? 1 : 0;
}

export function setB8(offset: MemOffset, value: number | boolean): void {
const boolValue = !!value;
if (typeof (value) === "number")
assert_int_in_range(value, 0, 1);
receiveWorkerHeapViews();
Module.HEAPU8[<any>offset] = boolValue ? 1 : 0;
}

export function setU8(offset: MemOffset, value: number): void {
assert_int_in_range(value, 0, 0xFF);
receiveWorkerHeapViews();
Expand Down Expand Up @@ -177,10 +187,22 @@ export function setF64(offset: MemOffset, value: number): void {
Module.HEAPF64[<any>offset >>> 3] = value;
}

let warnDirtyBool = true;

/** note: MonoBoolean is 8 bits not 32 bits when inside a structure or array */
export function getB32(offset: MemOffset): boolean {
receiveWorkerHeapViews();
return !!(Module.HEAP32[<any>offset >>> 2]);
const value = (Module.HEAPU32[<any>offset >>> 2]);
if (value > 1 && warnDirtyBool) {
warnDirtyBool = false;
mono_log_warn(`getB32: value at ${offset} is not a boolean, but a number: ${value}`);
}
return !!value;
}

export function getB8(offset: MemOffset): boolean {
receiveWorkerHeapViews();
return !!(Module.HEAPU8[<any>offset]);
}

export function getU8(offset: MemOffset): number {
Expand Down
8 changes: 8 additions & 0 deletions src/mono/browser/runtime/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ export type APIType = {
* Writes to the WASM linear memory
*/
setHeapB32: (offset: NativePointer, value: number | boolean) => void;
/**
* Writes to the WASM linear memory
*/
setHeapB8: (offset: NativePointer, value: number | boolean) => void;
/**
* Writes to the WASM linear memory
*/
Expand Down Expand Up @@ -500,6 +504,10 @@ export type APIType = {
* Reads from the WASM linear memory
*/
getHeapB32: (offset: NativePointer) => boolean;
/**
* Reads from the WASM linear memory
*/
getHeapB8: (offset: NativePointer) => boolean;
/**
* Reads from the WASM linear memory
*/
Expand Down

0 comments on commit 3a447e4

Please sign in to comment.