From 46e620cc83b3bf38d8ee24472576bf22af71c28e Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Mon, 1 Aug 2022 16:36:35 +0200
Subject: [PATCH 01/13] - added `JavaScriptExports.CallEntrypoint` replacing
 legacy `mono_bind_assembly_entry_point` - moved legacy imports and split
 `RuntimeHelpers`

---
 .../JavaScript/Interop/JavaScriptExports.cs   | 64 +++++++++++++++++++
 .../Marshaling/JSMarshalerArgument.Task.cs    |  4 +-
 src/mono/wasm/runtime/debug.ts                |  5 +-
 src/mono/wasm/runtime/dotnet.d.ts             |  6 ++
 src/mono/wasm/runtime/exports.ts              |  2 +
 src/mono/wasm/runtime/gc-handles.ts           |  2 +-
 src/mono/wasm/runtime/imports.ts              | 26 +-------
 src/mono/wasm/runtime/managed-exports.ts      | 49 ++++++++++----
 src/mono/wasm/runtime/marshal-to-cs.ts        | 18 +++---
 src/mono/wasm/runtime/marshal-to-js.ts        | 10 +--
 .../wasm/runtime/net6-legacy/corebindings.ts  | 33 ++++++++--
 src/mono/wasm/runtime/net6-legacy/cs-to-js.ts |  6 +-
 src/mono/wasm/runtime/net6-legacy/imports.ts  | 34 ++++++++++
 src/mono/wasm/runtime/net6-legacy/js-to-cs.ts | 23 +++----
 .../runtime/net6-legacy/method-binding.ts     |  5 +-
 .../wasm/runtime/net6-legacy/method-calls.ts  | 17 +----
 src/mono/wasm/runtime/run.ts                  | 31 ++++++++-
 src/mono/wasm/runtime/startup.ts              | 29 ++-------
 src/mono/wasm/runtime/types.ts                | 20 ------
 19 files changed, 242 insertions(+), 142 deletions(-)
 create mode 100644 src/mono/wasm/runtime/net6-legacy/imports.ts

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index c0aa35fed8763d..5f2259a75a7689 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -1,7 +1,9 @@
 ﻿// Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Reflection;
 using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
 
 namespace System.Runtime.InteropServices.JavaScript
 {
@@ -9,6 +11,68 @@ namespace System.Runtime.InteropServices.JavaScript
     // the methods are protected from trimming by DynamicDependency on JSFunctionBinding.BindJSFunction
     internal static unsafe partial class JavaScriptExports
     {
+        [MethodImpl(MethodImplOptions.NoInlining)] // https://github.com/dotnet/runtime/issues/71425
+        // the marshaled signature is:
+        // Task<int>? CallEntrypoint(MonoMethod* entrypointPtr, string[] args)
+        public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
+        {
+            ref JSMarshalerArgument arg_exc = ref arguments_buffer[0]; // initialized by caller in alloc_stack_frame()
+            ref JSMarshalerArgument arg_result = ref arguments_buffer[1]; // initialized by caller in alloc_stack_frame()
+            ref JSMarshalerArgument arg_1 = ref arguments_buffer[2]; // initialized and set by caller
+            ref JSMarshalerArgument arg_2 = ref arguments_buffer[3]; // initialized and set by caller
+            try
+            {
+                arg_1.ToManaged(out IntPtr entrypointPtr);
+                arg_2.ToManaged(out string?[]? args);
+                RuntimeMethodHandle methodHandle = JSHostImplementation.GetMethodHandleFromIntPtr(entrypointPtr);
+                MethodInfo? method = MethodBase.GetMethodFromHandle(methodHandle) as MethodInfo;
+                if (method == null)
+                {
+                    throw new InvalidOperationException("Missing entrypoint");
+                }
+                object[] argsToPass= System.Array.Empty<object>();
+                Task<int>? result = null;
+                var parameterInfos = method.GetParameters();
+                if (parameterInfos.Length > 0 && parameterInfos[0].ParameterType == typeof(string[]))
+                {
+                    if(args != null)
+                    {
+                        argsToPass = new object[] { args };
+                    }
+                    else
+                    {
+                        argsToPass = new object[] { System.Array.Empty<string>() };
+                    }
+                }
+                if (method.ReturnType == typeof(void))
+                {
+                    method.Invoke(null, argsToPass);
+                }
+                else if (method.ReturnType == typeof(int))
+                {
+                    int intResult = (int)method.Invoke(null, argsToPass)!;
+                    result = Task.FromResult(intResult);
+                }
+                else if (method.ReturnType == typeof(Task))
+                {
+                    method.Invoke(null, argsToPass);
+                    result = null;
+                }
+                else if (method.ReturnType == typeof(Task<int>))
+                {
+                    result = (Task<int>)method.Invoke(null, argsToPass)!;
+                }
+                arg_result.ToJS(result, (ref JSMarshalerArgument arg, int value) =>
+                {
+                    arg.ToJS(value);
+                });
+            }
+            catch (Exception ex)
+            {
+                arg_exc.ToJS(ex);
+            }
+        }
+
 
         // The JS layer invokes this method when the JS wrapper for a JS owned object
         //  has been collected by the JS garbage collector
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs
index e504bb15522b9a..f3101e881fe9ac 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Marshaling/JSMarshalerArgument.Task.cs
@@ -175,9 +175,9 @@ static void MarshalResult(ref JSMarshalerArgument arg, object? taskResult)
         /// Implementation of the argument marshaling.
         /// It's used by JSImport code generator and should not be used by developers in source code.
         /// </summary>
-        public void ToJS(Task value)
+        public void ToJS(Task? value)
         {
-            Task task = value;
+            Task? task = value;
 
             if (task == null)
             {
diff --git a/src/mono/wasm/runtime/debug.ts b/src/mono/wasm/runtime/debug.ts
index 40ab3a4201743b..c3cf3beb43ae09 100644
--- a/src/mono/wasm/runtime/debug.ts
+++ b/src/mono/wasm/runtime/debug.ts
@@ -2,10 +2,11 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 import Configuration from "consts:configuration";
-import { INTERNAL, Module, MONO, runtimeHelpers } from "./imports";
+import { INTERNAL, Module, runtimeHelpers } from "./imports";
 import { toBase64StringImpl } from "./base64";
 import cwraps from "./cwraps";
 import { VoidPtr, CharPtr } from "./types/emscripten";
+import { MONO } from "./net6-legacy/imports";
 const commands_received: any = new Map<number, CommandResponse>();
 const wasm_func_map = new Map<number, string>();
 commands_received.remove = function (key: number): CommandResponse { const value = this.get(key); this.delete(key); return value; };
@@ -34,7 +35,7 @@ regexes.push(/(?<replaceSection>[a-z]+:\/\/[^ )]*:wasm-function\[(?<funcNum>\d+)
 regexes.push(/(?<replaceSection><[^ >]+>[.:]wasm-function\[(?<funcNum>[0-9]+)\])/);
 
 export function mono_wasm_runtime_ready(): void {
-    runtimeHelpers.mono_wasm_runtime_is_ready = true;
+    INTERNAL.mono_wasm_runtime_is_ready = runtimeHelpers.mono_wasm_runtime_is_ready = true;
 
     // FIXME: where should this go?
     _next_call_function_res_id = 0;
diff --git a/src/mono/wasm/runtime/dotnet.d.ts b/src/mono/wasm/runtime/dotnet.d.ts
index f51c7a4d594d25..4ecaade5cbe7da 100644
--- a/src/mono/wasm/runtime/dotnet.d.ts
+++ b/src/mono/wasm/runtime/dotnet.d.ts
@@ -391,7 +391,13 @@ declare function getF32(offset: _MemOffset): number;
 declare function getF64(offset: _MemOffset): number;
 declare function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr;
 
+/**
+ * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
+ */
 declare function mono_run_main_and_exit(main_assembly_name: string, args: string[]): Promise<void>;
+/**
+ * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
+ */
 declare function mono_run_main(main_assembly_name: string, args: string[]): Promise<number>;
 
 declare function mono_wasm_setenv(name: string, value: string): void;
diff --git a/src/mono/wasm/runtime/exports.ts b/src/mono/wasm/runtime/exports.ts
index e995f40ab17a64..b3ca348538a28f 100644
--- a/src/mono/wasm/runtime/exports.ts
+++ b/src/mono/wasm/runtime/exports.ts
@@ -14,6 +14,7 @@ import { export_binding_api, export_mono_api } from "./net6-legacy/exports-legac
 import { export_internal } from "./exports-internal";
 import { export_linker } from "./exports-linker";
 import { init_polyfills } from "./polyfills";
+import { set_legacy_exports } from "./net6-legacy/imports";
 
 export const __initializeImportsAndExports: any = initializeImportsAndExports; // don't want to export the type
 export let __linker_exports: any = null;
@@ -34,6 +35,7 @@ function initializeImportsAndExports(
 
     // we want to have same instance of MONO, BINDING and Module in dotnet iffe
     set_imports_exports(imports, exports);
+    set_legacy_exports(exports);
     init_polyfills(replacements);
 
     // here we merge methods from the local objects into exported objects
diff --git a/src/mono/wasm/runtime/gc-handles.ts b/src/mono/wasm/runtime/gc-handles.ts
index af0f4776daa850..465bfc9264c078 100644
--- a/src/mono/wasm/runtime/gc-handles.ts
+++ b/src/mono/wasm/runtime/gc-handles.ts
@@ -105,7 +105,7 @@ export function teardown_managed_proxy(result: any, gc_handle: GCHandle): void {
         }
     }
     if (gc_handle !== GCHandleNull && _js_owned_object_table.delete(gc_handle)) {
-        runtimeHelpers.javaScriptExports._release_js_owned_object_by_gc_handle(gc_handle);
+        runtimeHelpers.javaScriptExports.release_js_owned_object_by_gc_handle(gc_handle);
     }
 }
 
diff --git a/src/mono/wasm/runtime/imports.ts b/src/mono/wasm/runtime/imports.ts
index 29772c201287d4..4aecd55b379ade 100644
--- a/src/mono/wasm/runtime/imports.ts
+++ b/src/mono/wasm/runtime/imports.ts
@@ -4,14 +4,11 @@
 /* eslint-disable @typescript-eslint/triple-slash-reference */
 /// <reference path="./types/v8.d.ts" />
 
-import { BINDINGType, MONOType } from "./net6-legacy/exports-legacy";
-import { DotnetModule, EarlyExports, EarlyImports, MonoConfig, RuntimeHelpers } from "./types";
+import { DotnetModule, EarlyExports, EarlyImports, RuntimeHelpers } from "./types";
 import { EmscriptenModule } from "./types/emscripten";
 
 // these are our public API (except internal)
 export let Module: EmscriptenModule & DotnetModule;
-export let MONO: MONOType;
-export let BINDING: BINDINGType;
 export let INTERNAL: any;
 export let EXPORTS: any;
 export let IMPORTS: any;
@@ -28,8 +25,6 @@ export function set_imports_exports(
     imports: EarlyImports,
     exports: EarlyExports,
 ): void {
-    MONO = exports.mono;
-    BINDING = exports.binding;
     INTERNAL = exports.internal;
     Module = exports.module;
 
@@ -46,28 +41,11 @@ export function set_imports_exports(
     runtimeHelpers.requirePromise = imports.requirePromise;
 }
 
-let monoConfig: MonoConfig = {} as any;
-let runtime_is_ready = false;
-
 export const runtimeHelpers: RuntimeHelpers = <any>{
     javaScriptExports: {},
     mono_wasm_load_runtime_done: false,
     mono_wasm_bindings_is_ready: false,
-    get mono_wasm_runtime_is_ready() {
-        return runtime_is_ready;
-    },
-    set mono_wasm_runtime_is_ready(value: boolean) {
-        runtime_is_ready = value;
-        INTERNAL.mono_wasm_runtime_is_ready = value;
-    },
-    get config() {
-        return monoConfig;
-    },
-    set config(value: MonoConfig) {
-        monoConfig = value;
-        MONO.config = value;
-        Module.config = value;
-    },
+    config: {},
     diagnostic_tracing: false,
     enable_debugging: false,
     fetch: null
diff --git a/src/mono/wasm/runtime/managed-exports.ts b/src/mono/wasm/runtime/managed-exports.ts
index 7b6e21ffe7e717..bb55943a7a2f28 100644
--- a/src/mono/wasm/runtime/managed-exports.ts
+++ b/src/mono/wasm/runtime/managed-exports.ts
@@ -4,22 +4,25 @@
 import { GCHandle, MonoMethod, mono_assert } from "./types";
 import cwraps from "./cwraps";
 import { Module, runtimeHelpers } from "./imports";
-import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerToCs, MarshalerToJs, MarshalerType, set_arg_type, set_gc_handle } from "./marshal";
+import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerToCs, MarshalerToJs, MarshalerType, set_arg_intptr, set_arg_type, set_gc_handle } from "./marshal";
 import { invoke_method_and_handle_exception } from "./invoke-cs";
-import { marshal_exception_to_cs } from "./marshal-to-cs";
+import { marshal_array_to_cs_impl, marshal_exception_to_cs } from "./marshal-to-cs";
+import { marshal_int32_to_js, marshal_task_to_js } from "./marshal-to-js";
 
 // in all the exported internals methods, we use the same data structures for stack frame as normal full blow interop
 // see src\libraries\System.Runtime.InteropServices.JavaScript\src\System\Runtime\InteropServices\JavaScript\Interop\JavaScriptExports.cs
 export interface JavaScriptExports {
     // the marshaled signature is: void ReleaseJSOwnedObjectByGCHandle(GCHandle gcHandle)
-    _release_js_owned_object_by_gc_handle(gc_handle: GCHandle): void;
+    release_js_owned_object_by_gc_handle(gc_handle: GCHandle): void;
     // the marshaled signature is: GCHandle CreateTaskCallback()
-    _create_task_callback(): GCHandle;
+    create_task_callback(): GCHandle;
     // the marshaled signature is: void CompleteTask<T>(GCHandle holder, Exception? exceptionResult, T? result)
-    _complete_task(holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs): void;
+    complete_task(holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs): void;
     // the marshaled signature is: TRes? CallDelegate<T1,T2,T3TRes>(GCHandle callback, T1? arg1, T2? arg2, T3? arg3)
-    _call_delegate(callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any,
+    call_delegate(callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any,
         res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs): any;
+    // the marshaled signature is: Task<int>? CallEntrypoint(MonoMethod* entrypointPtr, string[] args)
+    call_entry_point(entry_point: MonoMethod, args?: string[]): Promise<number>;
 }
 
 export function init_managed_exports(): void {
@@ -36,6 +39,8 @@ export function init_managed_exports(): void {
         throw "Can't find " + runtimeHelpers.runtime_interop_namespace + "." + runtimeHelpers.runtime_interop_exports_classname + " class";
 
 
+    const call_entry_point = get_method("CallEntrypoint");
+    mono_assert(call_entry_point, "Can't find CallEntrypoint method");
     const release_js_owned_object_by_gc_handle_method = get_method("ReleaseJSOwnedObjectByGCHandle");
     mono_assert(release_js_owned_object_by_gc_handle_method, "Can't find ReleaseJSOwnedObjectByGCHandle method");
     const create_task_callback_method = get_method("CreateTaskCallback");
@@ -44,11 +49,29 @@ export function init_managed_exports(): void {
     mono_assert(complete_task_method, "Can't find CompleteTask method");
     const call_delegate_method = get_method("CallDelegate");
     mono_assert(call_delegate_method, "Can't find CallDelegate method");
-
-    runtimeHelpers.javaScriptExports._release_js_owned_object_by_gc_handle = (gc_handle: GCHandle) => {
-        if (!gc_handle) {
-            Module.printErr("Must be valid gc_handle");
+    runtimeHelpers.javaScriptExports.call_entry_point = async (entry_point: MonoMethod, program_args?: string[]) => {
+        const sp = anyModule.stackSave();
+        try {
+            const args = alloc_stack_frame(4);
+            const res = get_arg(args, 1);
+            const arg1 = get_arg(args, 2);
+            const arg2 = get_arg(args, 3);
+            set_arg_intptr(arg1, <any>entry_point);
+            if (program_args && program_args.length == 0) {
+                program_args = undefined;
+            }
+            marshal_array_to_cs_impl(arg2, program_args, MarshalerType.String);
+            invoke_method_and_handle_exception(call_entry_point, args);
+            const promise = marshal_task_to_js(res, undefined, marshal_int32_to_js);
+            if (!promise) {
+                return 0;
+            }
+            return await promise;
+        } finally {
+            anyModule.stackRestore(sp);
         }
+    };
+    runtimeHelpers.javaScriptExports.release_js_owned_object_by_gc_handle = (gc_handle: GCHandle) => {
         mono_assert(gc_handle, "Must be valid gc_handle");
         const sp = anyModule.stackSave();
         try {
@@ -60,7 +83,7 @@ export function init_managed_exports(): void {
             anyModule.stackRestore(sp);
         }
     };
-    runtimeHelpers.javaScriptExports._create_task_callback = () => {
+    runtimeHelpers.javaScriptExports.create_task_callback = () => {
         const sp = anyModule.stackSave();
         try {
             const args = alloc_stack_frame(2);
@@ -71,7 +94,7 @@ export function init_managed_exports(): void {
             anyModule.stackRestore(sp);
         }
     };
-    runtimeHelpers.javaScriptExports._complete_task = (holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs) => {
+    runtimeHelpers.javaScriptExports.complete_task = (holder_gc_handle: GCHandle, error?: any, data?: any, res_converter?: MarshalerToCs) => {
         const sp = anyModule.stackSave();
         try {
             const args = alloc_stack_frame(5);
@@ -91,7 +114,7 @@ export function init_managed_exports(): void {
             anyModule.stackRestore(sp);
         }
     };
-    runtimeHelpers.javaScriptExports._call_delegate = (callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any, res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs) => {
+    runtimeHelpers.javaScriptExports.call_delegate = (callback_gc_handle: GCHandle, arg1_js: any, arg2_js: any, arg3_js: any, res_converter?: MarshalerToJs, arg1_converter?: MarshalerToCs, arg2_converter?: MarshalerToCs, arg3_converter?: MarshalerToCs) => {
         const sp = anyModule.stackSave();
         try {
             const args = alloc_stack_frame(6);
diff --git a/src/mono/wasm/runtime/marshal-to-cs.ts b/src/mono/wasm/runtime/marshal-to-cs.ts
index ae2019fb574174..0b4df5365951d9 100644
--- a/src/mono/wasm/runtime/marshal-to-cs.ts
+++ b/src/mono/wasm/runtime/marshal-to-cs.ts
@@ -362,17 +362,17 @@ function _marshal_task_to_cs(arg: JSMarshalerArgument, value: Promise<any>, _?:
     }
     mono_assert(isThenable(value), "Value is not a Promise");
 
-    const gc_handle: GCHandle = runtimeHelpers.javaScriptExports._create_task_callback();
+    const gc_handle: GCHandle = runtimeHelpers.javaScriptExports.create_task_callback();
     set_gc_handle(arg, gc_handle);
     set_arg_type(arg, MarshalerType.Task);
     const holder = new TaskCallbackHolder(value);
     setup_managed_proxy(holder, gc_handle);
 
     value.then(data => {
-        runtimeHelpers.javaScriptExports._complete_task(gc_handle, null, data, res_converter || _marshal_cs_object_to_cs);
+        runtimeHelpers.javaScriptExports.complete_task(gc_handle, null, data, res_converter || _marshal_cs_object_to_cs);
         teardown_managed_proxy(holder, gc_handle); // this holds holder alive for finalizer, until the promise is freed, (holding promise instead would not work)
     }).catch(reason => {
-        runtimeHelpers.javaScriptExports._complete_task(gc_handle, reason, null, undefined);
+        runtimeHelpers.javaScriptExports.complete_task(gc_handle, reason, null, undefined);
         teardown_managed_proxy(holder, gc_handle); // this holds holder alive for finalizer, until the promise is freed
     });
 }
@@ -454,16 +454,16 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void {
                 set_js_handle(arg, js_handle);
             }
             else if (value instanceof Uint8Array) {
-                _marshal_array_to_cs_impl(arg, value, MarshalerType.Byte);
+                marshal_array_to_cs_impl(arg, value, MarshalerType.Byte);
             }
             else if (value instanceof Float64Array) {
-                _marshal_array_to_cs_impl(arg, value, MarshalerType.Double);
+                marshal_array_to_cs_impl(arg, value, MarshalerType.Double);
             }
             else if (value instanceof Int32Array) {
-                _marshal_array_to_cs_impl(arg, value, MarshalerType.Int32);
+                marshal_array_to_cs_impl(arg, value, MarshalerType.Int32);
             }
             else if (Array.isArray(value)) {
-                _marshal_array_to_cs_impl(arg, value, MarshalerType.Object);
+                marshal_array_to_cs_impl(arg, value, MarshalerType.Object);
             }
             else if (value instanceof Int16Array
                 || value instanceof Int8Array
@@ -511,10 +511,10 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void {
 function _marshal_array_to_cs(arg: JSMarshalerArgument, value: Array<any> | TypedArray, sig?: JSMarshalerType): void {
     mono_assert(!!sig, "Expected valid sig parameter");
     const element_type = get_signature_arg1_type(sig);
-    _marshal_array_to_cs_impl(arg, value, element_type);
+    marshal_array_to_cs_impl(arg, value, element_type);
 }
 
-function _marshal_array_to_cs_impl(arg: JSMarshalerArgument, value: Array<any> | TypedArray, element_type: MarshalerType): void {
+export function marshal_array_to_cs_impl(arg: JSMarshalerArgument, value: Array<any> | TypedArray | undefined, element_type: MarshalerType): void {
     if (value === null || value === undefined) {
         set_arg_type(arg, MarshalerType.None);
     }
diff --git a/src/mono/wasm/runtime/marshal-to-js.ts b/src/mono/wasm/runtime/marshal-to-js.ts
index 7555fdbff6cf2a..12fc9c73842f45 100644
--- a/src/mono/wasm/runtime/marshal-to-js.ts
+++ b/src/mono/wasm/runtime/marshal-to-js.ts
@@ -26,7 +26,7 @@ export function initialize_marshalers_to_js(): void {
         cs_to_js_marshalers.set(MarshalerType.Byte, _marshal_byte_to_js);
         cs_to_js_marshalers.set(MarshalerType.Char, _marshal_char_to_js);
         cs_to_js_marshalers.set(MarshalerType.Int16, _marshal_int16_to_js);
-        cs_to_js_marshalers.set(MarshalerType.Int32, _marshal_int32_to_js);
+        cs_to_js_marshalers.set(MarshalerType.Int32, marshal_int32_to_js);
         cs_to_js_marshalers.set(MarshalerType.Int52, _marshal_int52_to_js);
         cs_to_js_marshalers.set(MarshalerType.BigInt64, _marshal_bigint64_to_js);
         cs_to_js_marshalers.set(MarshalerType.Single, _marshal_float_to_js);
@@ -39,7 +39,7 @@ export function initialize_marshalers_to_js(): void {
         cs_to_js_marshalers.set(MarshalerType.Object, _marshal_cs_object_to_js);
         cs_to_js_marshalers.set(MarshalerType.DateTime, _marshal_datetime_to_js);
         cs_to_js_marshalers.set(MarshalerType.DateTimeOffset, _marshal_datetime_to_js);
-        cs_to_js_marshalers.set(MarshalerType.Task, _marshal_task_to_js);
+        cs_to_js_marshalers.set(MarshalerType.Task, marshal_task_to_js);
         cs_to_js_marshalers.set(MarshalerType.Action, _marshal_delegate_to_js);
         cs_to_js_marshalers.set(MarshalerType.Function, _marshal_delegate_to_js);
         cs_to_js_marshalers.set(MarshalerType.None, _marshal_null_to_js);
@@ -174,7 +174,7 @@ function _marshal_int16_to_js(arg: JSMarshalerArgument): number | null {
     return get_arg_i16(arg);
 }
 
-function _marshal_int32_to_js(arg: JSMarshalerArgument): number | null {
+export function marshal_int32_to_js(arg: JSMarshalerArgument): number | null {
     const type = get_arg_type(arg);
     if (type == MarshalerType.None) {
         return null;
@@ -246,7 +246,7 @@ function _marshal_delegate_to_js(arg: JSMarshalerArgument, _?: JSMarshalerType,
         // this will create new Function for the C# delegate
         result = (arg1_js: any, arg2_js: any, arg3_js: any): any => {
             // arg numbers are shifted by one, the real first is a gc handle of the callback
-            return runtimeHelpers.javaScriptExports._call_delegate(gc_handle, arg1_js, arg2_js, arg3_js, res_converter, arg1_converter, arg2_converter, arg3_converter);
+            return runtimeHelpers.javaScriptExports.call_delegate(gc_handle, arg1_js, arg2_js, arg3_js, res_converter, arg1_converter, arg2_converter, arg3_converter);
         };
         setup_managed_proxy(result, gc_handle);
     }
@@ -254,7 +254,7 @@ function _marshal_delegate_to_js(arg: JSMarshalerArgument, _?: JSMarshalerType,
     return result;
 }
 
-function _marshal_task_to_js(arg: JSMarshalerArgument, _?: JSMarshalerType, res_converter?: MarshalerToJs): Promise<any> | null {
+export function marshal_task_to_js(arg: JSMarshalerArgument, _?: JSMarshalerType, res_converter?: MarshalerToJs): Promise<any> | null {
     const type = get_arg_type(arg);
     if (type === MarshalerType.None) {
         return null;
diff --git a/src/mono/wasm/runtime/net6-legacy/corebindings.ts b/src/mono/wasm/runtime/net6-legacy/corebindings.ts
index 4ac7b5b2263659..062de20442e3c3 100644
--- a/src/mono/wasm/runtime/net6-legacy/corebindings.ts
+++ b/src/mono/wasm/runtime/net6-legacy/corebindings.ts
@@ -3,10 +3,12 @@
 
 import { JSHandle, GCHandle, MonoObjectRef, MonoMethod, MonoObject } from "../types";
 import { mono_bind_method, _create_primitive_converters } from "./method-binding";
-import { WasmRoot } from "../roots";
-import { runtimeHelpers } from "../imports";
+import { mono_wasm_new_root, WasmRoot } from "../roots";
+import { Module, runtimeHelpers } from "../imports";
 import cwraps from "../cwraps";
 import { PromiseController } from "../promise-controller";
+import { legacyHelpers, wasm_type_symbol } from "./imports";
+import { find_corlib_class } from "../class-loader";
 type SigLine = [lazy: boolean, jsname: string, csname: string, signature: string/*ArgsMarshalString*/];
 const fn_signatures: SigLine[] = [
     [true, "_get_cs_owned_object_by_js_handle_ref", "GetCSOwnedObjectByJSHandleRef", "iim"],
@@ -64,11 +66,28 @@ export function bind_runtime_method(method_name: string, signature: string): Fun
 }
 
 export function init_legacy_exports(): void {
+    // please keep System.Runtime.InteropServices.JavaScript.JSHostImplementation.MappedType in sync
+    (<any>Object.prototype)[wasm_type_symbol] = 0;
+    (<any>Array.prototype)[wasm_type_symbol] = 1;
+    (<any>ArrayBuffer.prototype)[wasm_type_symbol] = 2;
+    (<any>DataView.prototype)[wasm_type_symbol] = 3;
+    (<any>Function.prototype)[wasm_type_symbol] = 4;
+    (<any>Uint8Array.prototype)[wasm_type_symbol] = 11;
+
+    const box_buffer_size = 65536;
+    legacyHelpers._unbox_buffer_size = 65536;
+    legacyHelpers._box_buffer = Module._malloc(box_buffer_size);
+    legacyHelpers._unbox_buffer = Module._malloc(legacyHelpers._unbox_buffer_size);
+    legacyHelpers._class_int32 = find_corlib_class("System", "Int32");
+    legacyHelpers._class_uint32 = find_corlib_class("System", "UInt32");
+    legacyHelpers._class_double = find_corlib_class("System", "Double");
+    legacyHelpers._class_boolean = find_corlib_class("System", "Boolean");
+    legacyHelpers._null_root = mono_wasm_new_root<MonoObject>();
     _create_primitive_converters();
 
-    runtimeHelpers.runtime_legacy_exports_classname = "LegacyExports";
-    runtimeHelpers.runtime_legacy_exports_class = cwraps.mono_wasm_assembly_find_class(runtimeHelpers.runtime_interop_module, runtimeHelpers.runtime_interop_namespace, runtimeHelpers.runtime_legacy_exports_classname);
-    if (!runtimeHelpers.runtime_legacy_exports_class)
+    legacyHelpers.runtime_legacy_exports_classname = "LegacyExports";
+    legacyHelpers.runtime_legacy_exports_class = cwraps.mono_wasm_assembly_find_class(runtimeHelpers.runtime_interop_module, runtimeHelpers.runtime_interop_namespace, legacyHelpers.runtime_legacy_exports_classname);
+    if (!legacyHelpers.runtime_legacy_exports_class)
         throw "Can't find " + runtimeHelpers.runtime_interop_namespace + "." + runtimeHelpers.runtime_interop_exports_classname + " class";
 
     for (const sig of fn_signatures) {
@@ -90,8 +109,8 @@ export function init_legacy_exports(): void {
 }
 
 export function get_method(method_name: string): MonoMethod {
-    const res = cwraps.mono_wasm_assembly_find_method(runtimeHelpers.runtime_legacy_exports_class, method_name, -1);
+    const res = cwraps.mono_wasm_assembly_find_method(legacyHelpers.runtime_legacy_exports_class, method_name, -1);
     if (!res)
-        throw "Can't find method " + runtimeHelpers.runtime_interop_namespace + "." + runtimeHelpers.runtime_legacy_exports_classname + "." + method_name;
+        throw "Can't find method " + runtimeHelpers.runtime_interop_namespace + "." + legacyHelpers.runtime_legacy_exports_classname + "." + method_name;
     return res;
 }
\ No newline at end of file
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 51fc454cb82708..e592523a00d705 100644
--- a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts
+++ b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts
@@ -1,7 +1,6 @@
 import { _are_promises_supported } from "../cancelable-promise";
 import cwraps from "../cwraps";
 import { mono_wasm_get_jsobj_from_js_handle, _lookup_js_owned_object, setup_managed_proxy, mono_wasm_get_js_handle, teardown_managed_proxy, assert_not_disposed } from "../gc-handles";
-import { runtimeHelpers } from "../imports";
 import { wrap_error_root } from "../invoke-js";
 import { ManagedObject } from "../marshal";
 import { getU32, getI32, getF32, getF64, setI32_unchecked } from "../memory";
@@ -11,6 +10,7 @@ import { conv_string_root } from "../strings";
 import { MarshalType, MonoType, MarshalError, MonoTypeNull, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, GCHandle, MonoStringRef, MonoObjectRef, MonoString, JSHandleDisposed, is_nullish } from "../types";
 import { Int32Ptr, VoidPtr } from "../types/emscripten";
 import { legacyManagedExports } from "./corebindings";
+import { legacyHelpers } from "./imports";
 import { js_to_mono_obj_root } from "./js-to-cs";
 import { mono_bind_method, mono_method_get_call_signature_ref } from "./method-binding";
 
@@ -101,8 +101,8 @@ export function unbox_mono_obj_root(root: WasmRoot<any>): any {
     if (root.value === 0)
         return undefined;
 
-    const unbox_buffer = runtimeHelpers._unbox_buffer;
-    const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.address, unbox_buffer, runtimeHelpers._unbox_buffer_size);
+    const unbox_buffer = legacyHelpers._unbox_buffer;
+    const type = cwraps.mono_wasm_try_unbox_primitive_and_get_type_ref(root.address, unbox_buffer, legacyHelpers._unbox_buffer_size);
     switch (type) {
         case MarshalType.INT:
             return getI32(unbox_buffer);
diff --git a/src/mono/wasm/runtime/net6-legacy/imports.ts b/src/mono/wasm/runtime/net6-legacy/imports.ts
new file mode 100644
index 00000000000000..976dd2a3d8ae08
--- /dev/null
+++ b/src/mono/wasm/runtime/net6-legacy/imports.ts
@@ -0,0 +1,34 @@
+import { EarlyExports, MonoClass } from "../types";
+import { VoidPtr } from "../types/emscripten";
+import { BINDINGType, MONOType } from "./exports-legacy";
+
+export let MONO: MONOType;
+export let BINDING: BINDINGType;
+
+export const legacyHelpers: LegacyHelpers = <any>{
+};
+
+export function set_legacy_exports(
+    exports: EarlyExports,
+): void {
+    MONO = exports.mono;
+    BINDING = exports.binding;
+}
+
+export type LegacyHelpers = {
+    runtime_legacy_exports_classname: string;
+    runtime_legacy_exports_class: MonoClass;
+
+    // A WasmRoot that is guaranteed to contain 0
+    _null_root: any;
+    _class_int32: MonoClass;
+    _class_uint32: MonoClass;
+    _class_double: MonoClass;
+    _class_boolean: MonoClass;
+    _unbox_buffer_size: number;
+    _box_buffer: VoidPtr;
+    _unbox_buffer: VoidPtr;
+    _box_root: any;
+}
+
+export const wasm_type_symbol = Symbol.for("wasm type");
diff --git a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
index 438afbae9b63cc..d76d1041a6a145 100644
--- a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
+++ b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
@@ -1,16 +1,17 @@
 import { isThenable } from "../cancelable-promise";
 import cwraps from "../cwraps";
 import { js_owned_gc_handle_symbol, assert_not_disposed, cs_owned_js_handle_symbol, mono_wasm_get_js_handle, setup_managed_proxy, mono_wasm_release_cs_owned_object, teardown_managed_proxy, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles";
-import { runtimeHelpers, Module } from "../imports";
+import { Module } from "../imports";
 import { wrap_error_root } from "../invoke-js";
 import { setI32_unchecked, setU32_unchecked, setF64, setB32 } from "../memory";
 import { WasmRoot, mono_wasm_new_root, mono_wasm_release_roots, mono_wasm_new_external_root } from "../roots";
 import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "../strings";
-import { MonoObject, is_nullish, MonoClass, wasm_type_symbol, MonoArray, MonoMethod, MonoObjectNull, JSHandle, MonoObjectRef, JSHandleNull, JSHandleDisposed } from "../types";
+import { MonoObject, is_nullish, MonoClass, MonoArray, MonoMethod, MonoObjectNull, JSHandle, MonoObjectRef, JSHandleNull, JSHandleDisposed } from "../types";
 import { TypedArray, Int32Ptr } from "../types/emscripten";
 import { has_backing_array_buffer } from "./buffers";
 import { legacyManagedExports } from "./corebindings";
 import { get_js_owned_object_by_gc_handle_ref } from "./cs-to-js";
+import { legacyHelpers, wasm_type_symbol } from "./imports";
 
 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export function _js_to_mono_uri_root(should_add_in_flight: boolean, js_obj: any, result: WasmRoot<MonoObject>): void {
@@ -71,17 +72,17 @@ export function js_to_mono_obj_root(js_obj: any, result: WasmRoot<MonoObject>, s
         case typeof js_obj === "number": {
             let box_class: MonoClass;
             if ((js_obj | 0) === js_obj) {
-                setI32_unchecked(runtimeHelpers._box_buffer, js_obj);
-                box_class = runtimeHelpers._class_int32;
+                setI32_unchecked(legacyHelpers._box_buffer, js_obj);
+                box_class = legacyHelpers._class_int32;
             } else if ((js_obj >>> 0) === js_obj) {
-                setU32_unchecked(runtimeHelpers._box_buffer, js_obj);
-                box_class = runtimeHelpers._class_uint32;
+                setU32_unchecked(legacyHelpers._box_buffer, js_obj);
+                box_class = legacyHelpers._class_uint32;
             } else {
-                setF64(runtimeHelpers._box_buffer, js_obj);
-                box_class = runtimeHelpers._class_double;
+                setF64(legacyHelpers._box_buffer, js_obj);
+                box_class = legacyHelpers._class_double;
             }
 
-            cwraps.mono_wasm_box_primitive_ref(box_class, runtimeHelpers._box_buffer, 8, result.address);
+            cwraps.mono_wasm_box_primitive_ref(box_class, legacyHelpers._box_buffer, 8, result.address);
             return;
         }
         case typeof js_obj === "string":
@@ -91,8 +92,8 @@ export function js_to_mono_obj_root(js_obj: any, result: WasmRoot<MonoObject>, s
             js_string_to_mono_string_interned_root(js_obj, <any>result);
             return;
         case typeof js_obj === "boolean":
-            setB32(runtimeHelpers._box_buffer, js_obj);
-            cwraps.mono_wasm_box_primitive_ref(runtimeHelpers._class_boolean, runtimeHelpers._box_buffer, 4, result.address);
+            setB32(legacyHelpers._box_buffer, js_obj);
+            cwraps.mono_wasm_box_primitive_ref(legacyHelpers._class_boolean, legacyHelpers._box_buffer, 4, result.address);
             return;
         case isThenable(js_obj) === true: {
             _wrap_js_thenable_as_task_root(js_obj, result);
diff --git a/src/mono/wasm/runtime/net6-legacy/method-binding.ts b/src/mono/wasm/runtime/net6-legacy/method-binding.ts
index 414c93377d5e15..aa40ba6b35b544 100644
--- a/src/mono/wasm/runtime/net6-legacy/method-binding.ts
+++ b/src/mono/wasm/runtime/net6-legacy/method-binding.ts
@@ -2,7 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 import cwraps from "../cwraps";
-import { runtimeHelpers, BINDING, Module } from "../imports";
+import { Module } from "../imports";
 import { parseFQN } from "../invoke-cs";
 import { setI32, setU32, setF32, setF64, setU52, setI52, setB32, setI32_unchecked, setU32_unchecked, _zero_region, _create_temp_frame, getB32, getI32, getU32, getF32, getF64 } from "../memory";
 import { WasmRoot, mono_wasm_new_external_root, mono_wasm_new_root, WasmRootBuffer } from "../roots";
@@ -11,6 +11,7 @@ import { MonoMethod, MonoObject, MonoType, MonoClass, mono_assert, VoidPtrNull,
 import { VoidPtr } from "../types/emscripten";
 import { legacyManagedExports } from "./corebindings";
 import { get_js_owned_object_by_gc_handle_ref, _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js";
+import { BINDING, legacyHelpers } from "./imports";
 import { js_to_mono_obj_root, _js_to_mono_uri_root, js_to_mono_enum } from "./js-to-cs";
 import { _teardown_after_call } from "./method-calls";
 
@@ -684,5 +685,5 @@ export function mono_method_resolve(fqn: string): MonoMethod {
 }
 
 export function mono_method_get_call_signature_ref(method: MonoMethod, mono_obj?: WasmRoot<MonoObject>): string/*ArgsMarshalString*/ {
-    return legacyManagedExports._get_call_sig_ref(method, mono_obj ? mono_obj.address : runtimeHelpers._null_root.address);
+    return legacyManagedExports._get_call_sig_ref(method, mono_obj ? mono_obj.address : legacyHelpers._null_root.address);
 }
diff --git a/src/mono/wasm/runtime/net6-legacy/method-calls.ts b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
index af7c17b80c8653..a2522ec5b09451 100644
--- a/src/mono/wasm/runtime/net6-legacy/method-calls.ts
+++ b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
@@ -1,13 +1,12 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-import { assembly_load } from "../class-loader";
-import cwraps from "../cwraps";
 import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles";
 import { Module, runtimeHelpers, INTERNAL } from "../imports";
 import { wrap_error_root } from "../invoke-js";
 import { _release_temp_frame } from "../memory";
 import { WasmRoot, mono_wasm_new_external_root, mono_wasm_new_root } from "../roots";
+import { find_entry_point } from "../run";
 import { conv_string_root, js_string_to_mono_string_root } from "../strings";
 import { JSHandle, MonoStringRef, MonoObjectRef, MonoArray, MonoString, MonoObject, is_nullish, mono_assert } from "../types";
 import { Int32Ptr, VoidPtr } from "../types/emscripten";
@@ -69,19 +68,7 @@ export function mono_bind_static_method(fqn: string, signature?: string/*ArgsMar
 }
 
 export function mono_bind_assembly_entry_point(assembly: string, signature?: string/*ArgsMarshalString*/): Function {
-    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
-    const asm = assembly_load(assembly);
-    if (!asm)
-        throw new Error("Could not find assembly: " + assembly);
-
-    let auto_set_breakpoint = 0;
-    if (runtimeHelpers.wait_for_debugger == 1)
-        auto_set_breakpoint = 1;
-
-    const method = cwraps.mono_wasm_assembly_get_entry_point(asm, auto_set_breakpoint);
-    if (!method)
-        throw new Error("Could not find entry point for assembly: " + assembly);
-
+    const method = find_entry_point(assembly);
     if (typeof (signature) !== "string")
         signature = mono_method_get_call_signature_ref(method, undefined);
 
diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts
index fcf1c78664c075..1572b8eb70c250 100644
--- a/src/mono/wasm/runtime/run.ts
+++ b/src/mono/wasm/runtime/run.ts
@@ -1,8 +1,13 @@
 import { INTERNAL, Module, runtimeHelpers } from "./imports";
-import { mono_call_assembly_entry_point } from "./net6-legacy/method-calls";
 import { mono_wasm_wait_for_debugger } from "./debug";
 import { abort_startup, mono_wasm_set_main_args } from "./startup";
+import cwraps from "./cwraps";
+import { assembly_load } from "./class-loader";
+import { mono_assert } from "./types";
 
+/**
+ * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
+ */
 export async function mono_run_main_and_exit(main_assembly_name: string, args: string[]): Promise<void> {
     try {
         const result = await mono_run_main(main_assembly_name, args);
@@ -15,13 +20,33 @@ export async function mono_run_main_and_exit(main_assembly_name: string, args: s
     }
 }
 
+/**
+ * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
+ */
 export async function mono_run_main(main_assembly_name: string, args: string[]): Promise<number> {
     mono_wasm_set_main_args(main_assembly_name, args);
     if (runtimeHelpers.wait_for_debugger == -1) {
         console.log("MONO_WASM: waiting for debugger...");
-        return await mono_wasm_wait_for_debugger().then(() => mono_call_assembly_entry_point(main_assembly_name, [args], "m"));
+        await mono_wasm_wait_for_debugger();
     }
-    return mono_call_assembly_entry_point(main_assembly_name, [args], "m");
+    const method = find_entry_point(main_assembly_name);
+    return runtimeHelpers.javaScriptExports.call_entry_point(method, args);
+}
+
+export function find_entry_point(assembly: string) {
+    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
+    const asm = assembly_load(assembly);
+    if (!asm)
+        throw new Error("Could not find assembly: " + assembly);
+
+    let auto_set_breakpoint = 0;
+    if (runtimeHelpers.wait_for_debugger == 1)
+        auto_set_breakpoint = 1;
+
+    const method = cwraps.mono_wasm_assembly_get_entry_point(asm, auto_set_breakpoint);
+    if (!method)
+        throw new Error("Could not find entry point for assembly: " + assembly);
+    return method;
 }
 
 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts
index f95c432707b075..fab2c00a96879f 100644
--- a/src/mono/wasm/runtime/startup.ts
+++ b/src/mono/wasm/runtime/startup.ts
@@ -2,19 +2,17 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 import MonoWasmThreads from "consts:monoWasmThreads";
-import { mono_assert, CharPtrNull, DotnetModule, MonoConfig, wasm_type_symbol, MonoObject, MonoConfigError, LoadingResource, AssetEntry, ResourceRequest, DotnetPublicAPI } from "./types";
-import { BINDING, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_PTHREAD, ENVIRONMENT_IS_SHELL, INTERNAL, Module, MONO, runtimeHelpers } from "./imports";
+import { mono_assert, CharPtrNull, DotnetModule, MonoConfig, MonoConfigError, LoadingResource, AssetEntry, ResourceRequest, DotnetPublicAPI } from "./types";
+import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_PTHREAD, ENVIRONMENT_IS_SHELL, INTERNAL, Module, runtimeHelpers } from "./imports";
 import cwraps, { init_c_exports } from "./cwraps";
 import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug";
 import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu";
 import { toBase64StringImpl } from "./base64";
 import { mono_wasm_init_aot_profiler, mono_wasm_init_coverage_profiler } from "./profiler";
-import { find_corlib_class } from "./class-loader";
 import { VoidPtr, CharPtr } from "./types/emscripten";
 import { mono_on_abort, set_exit_code } from "./run";
 import { initialize_marshalers_to_cs } from "./marshal-to-cs";
 import { initialize_marshalers_to_js } from "./marshal-to-js";
-import { mono_wasm_new_root } from "./roots";
 import { init_crypto } from "./crypto-worker";
 import { init_polyfills_async } from "./polyfills";
 import * as pthreads_worker from "./pthreads/worker";
@@ -26,6 +24,7 @@ import { init_legacy_exports } from "./net6-legacy/corebindings";
 import { mono_wasm_load_bytes_into_heap } from "./memory";
 import { cwraps_internal } from "./exports-internal";
 import { cwraps_binding_api, cwraps_mono_api } from "./net6-legacy/exports-legacy";
+import { BINDING, MONO } from "./net6-legacy/imports";
 
 let all_assets_loaded_in_memory: Promise<void> | null = null;
 const loaded_files: { url: string, file: string }[] = [];
@@ -582,32 +581,12 @@ export function bindings_init(): void {
     }
     runtimeHelpers.mono_wasm_bindings_is_ready = true;
     try {
-
-        // please keep System.Runtime.InteropServices.JavaScript.JSHostImplementation.MappedType in sync
-        (<any>Object.prototype)[wasm_type_symbol] = 0;
-        (<any>Array.prototype)[wasm_type_symbol] = 1;
-        (<any>ArrayBuffer.prototype)[wasm_type_symbol] = 2;
-        (<any>DataView.prototype)[wasm_type_symbol] = 3;
-        (<any>Function.prototype)[wasm_type_symbol] = 4;
-        (<any>Uint8Array.prototype)[wasm_type_symbol] = 11;
-
-        runtimeHelpers._box_buffer_size = 65536;
-        runtimeHelpers._unbox_buffer_size = 65536;
-        runtimeHelpers._box_buffer = Module._malloc(runtimeHelpers._box_buffer_size);
-        runtimeHelpers._unbox_buffer = Module._malloc(runtimeHelpers._unbox_buffer_size);
-        runtimeHelpers._i52_error_scratch_buffer = <any>Module._malloc(4);
-        runtimeHelpers._class_int32 = find_corlib_class("System", "Int32");
-        runtimeHelpers._class_uint32 = find_corlib_class("System", "UInt32");
-        runtimeHelpers._class_double = find_corlib_class("System", "Double");
-        runtimeHelpers._class_boolean = find_corlib_class("System", "Boolean");
-
         init_managed_exports();
         init_legacy_exports();
         initialize_marshalers_to_js();
         initialize_marshalers_to_cs();
+        runtimeHelpers._i52_error_scratch_buffer = <any>Module._malloc(4);
 
-        runtimeHelpers._box_root = mono_wasm_new_root<MonoObject>();
-        runtimeHelpers._null_root = mono_wasm_new_root<MonoObject>();
     } catch (err) {
         _print_error("MONO_WASM: Error in bindings_init", err);
         throw err;
diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts
index 494db151c1fdfc..d52ea8f3e61cf2 100644
--- a/src/mono/wasm/runtime/types.ts
+++ b/src/mono/wasm/runtime/types.ts
@@ -125,30 +125,12 @@ export type AssetBehaviours =
     | "dotnetwasm"; // the binary of the dotnet runtime
 
 export type RuntimeHelpers = {
-    get_call_sig_ref: MonoMethod;
-    complete_task_method: MonoMethod;
-    create_task_method: MonoMethod;
-    call_delegate: MonoMethod;
     runtime_interop_module: MonoAssembly;
     runtime_interop_namespace: string;
     runtime_interop_exports_classname: string;
     runtime_interop_exports_class: MonoClass;
-    runtime_legacy_exports_classname: string;
-    runtime_legacy_exports_class: MonoClass;
 
-    _box_buffer_size: number;
-    _unbox_buffer_size: number;
-
-    _box_buffer: VoidPtr;
-    _unbox_buffer: VoidPtr;
     _i52_error_scratch_buffer: Int32Ptr;
-    _box_root: any;
-    // A WasmRoot that is guaranteed to contain 0
-    _null_root: any;
-    _class_int32: MonoClass;
-    _class_uint32: MonoClass;
-    _class_double: MonoClass;
-    _class_boolean: MonoClass;
     mono_wasm_load_runtime_done: boolean;
     mono_wasm_runtime_is_ready: boolean;
     mono_wasm_bindings_is_ready: boolean;
@@ -167,8 +149,6 @@ export type RuntimeHelpers = {
     javaScriptExports: JavaScriptExports,
 }
 
-export const wasm_type_symbol = Symbol.for("wasm type");
-
 export type GlobalizationMode =
     "icu" | // load ICU globalization data from any runtime assets with behavior "icu".
     "invariant" | //  operate in invariant globalization mode.

From f3d13730f06de2c607e2cacfd29494f54d16291a Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Mon, 1 Aug 2022 20:28:08 +0200
Subject: [PATCH 02/13] wip

---
 .../InteropServices/JavaScript/Interop/JavaScriptExports.cs   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 5f2259a75a7689..a07e31499e74b5 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -62,6 +62,10 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 {
                     result = (Task<int>)method.Invoke(null, argsToPass)!;
                 }
+                else
+                {
+                    throw new InvalidProgramException(method.ReturnType.FullName);
+                }
                 arg_result.ToJS(result, (ref JSMarshalerArgument arg, int value) =>
                 {
                     arg.ToJS(value);

From 27f232b2be870df13454f00dce9080a7425cf1ac Mon Sep 17 00:00:00 2001
From: Pavel Savara <pavelsavara@microsoft.com>
Date: Wed, 3 Aug 2022 11:43:07 +0200
Subject: [PATCH 03/13] Update
 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs

Co-authored-by: Katelyn Gadd <kg@luminance.org>
---
 .../JavaScript/Interop/JavaScriptExports.cs              | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index a07e31499e74b5..86245edfd12b1f 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -35,14 +35,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 var parameterInfos = method.GetParameters();
                 if (parameterInfos.Length > 0 && parameterInfos[0].ParameterType == typeof(string[]))
                 {
-                    if(args != null)
-                    {
-                        argsToPass = new object[] { args };
-                    }
-                    else
-                    {
-                        argsToPass = new object[] { System.Array.Empty<string>() };
-                    }
+                    argsToPass = new object[] { args ?? System.Array.Empty<string>() };
                 }
                 if (method.ReturnType == typeof(void))
                 {

From 0a2156f098a35747937164abf6f7dbfdd721233a Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Wed, 3 Aug 2022 11:59:36 +0200
Subject: [PATCH 04/13] feedback

---
 .../JavaScript/Interop/JavaScriptExports.cs           | 11 +++++++++--
 src/mono/wasm/runtime/invoke-cs.ts                    |  2 +-
 src/mono/wasm/runtime/managed-exports.ts              |  6 +++---
 src/mono/wasm/runtime/net6-legacy/method-calls.ts     |  4 ++--
 src/mono/wasm/runtime/run.ts                          |  2 +-
 5 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 86245edfd12b1f..3d09aeaf781e98 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -23,13 +23,20 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
             try
             {
                 arg_1.ToManaged(out IntPtr entrypointPtr);
-                arg_2.ToManaged(out string?[]? args);
+                if (entrypointPtr == IntPtr.Zero)
+                {
+                    throw new MissingMethodException("Missing entrypoint");
+                }
+
                 RuntimeMethodHandle methodHandle = JSHostImplementation.GetMethodHandleFromIntPtr(entrypointPtr);
+                // this would not work for generic types. But Main() could not be generic, so we are fine.
                 MethodInfo? method = MethodBase.GetMethodFromHandle(methodHandle) as MethodInfo;
                 if (method == null)
                 {
-                    throw new InvalidOperationException("Missing entrypoint");
+                    throw new InvalidProgramException("Can't resolve entrypoint handle");
                 }
+
+                arg_2.ToManaged(out string?[]? args);
                 object[] argsToPass= System.Array.Empty<object>();
                 Task<int>? result = null;
                 var parameterInfos = method.GetParameters();
diff --git a/src/mono/wasm/runtime/invoke-cs.ts b/src/mono/wasm/runtime/invoke-cs.ts
index d4e91aaeb65d7f..730a1c05cda0da 100644
--- a/src/mono/wasm/runtime/invoke-cs.ts
+++ b/src/mono/wasm/runtime/invoke-cs.ts
@@ -170,7 +170,7 @@ function _walk_exports_to_set_function(assembly: string, namespace: string, clas
 }
 
 export async function mono_wasm_get_assembly_exports(assembly: string): Promise<any> {
-    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
+    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "The runtime must be initialized.");
     const result = exportsByAssembly.get(assembly);
     if (!result) {
         const asm = assembly_load(assembly);
diff --git a/src/mono/wasm/runtime/managed-exports.ts b/src/mono/wasm/runtime/managed-exports.ts
index bb55943a7a2f28..1a891f4a75bf81 100644
--- a/src/mono/wasm/runtime/managed-exports.ts
+++ b/src/mono/wasm/runtime/managed-exports.ts
@@ -49,7 +49,7 @@ export function init_managed_exports(): void {
     mono_assert(complete_task_method, "Can't find CompleteTask method");
     const call_delegate_method = get_method("CallDelegate");
     mono_assert(call_delegate_method, "Can't find CallDelegate method");
-    runtimeHelpers.javaScriptExports.call_entry_point = async (entry_point: MonoMethod, program_args?: string[]) => {
+    runtimeHelpers.javaScriptExports.call_entry_point = (entry_point: MonoMethod, program_args?: string[]) => {
         const sp = anyModule.stackSave();
         try {
             const args = alloc_stack_frame(4);
@@ -64,9 +64,9 @@ export function init_managed_exports(): void {
             invoke_method_and_handle_exception(call_entry_point, args);
             const promise = marshal_task_to_js(res, undefined, marshal_int32_to_js);
             if (!promise) {
-                return 0;
+                return Promise.resolve(0);
             }
-            return await promise;
+            return promise;
         } finally {
             anyModule.stackRestore(sp);
         }
diff --git a/src/mono/wasm/runtime/net6-legacy/method-calls.ts b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
index a2522ec5b09451..c9d487d41bdb36 100644
--- a/src/mono/wasm/runtime/net6-legacy/method-calls.ts
+++ b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
@@ -51,7 +51,7 @@ export function _teardown_after_call(
 }
 
 export function mono_bind_static_method(fqn: string, signature?: string/*ArgsMarshalString*/): Function {
-    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
+    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "The runtime must be initialized.");
 
     const key = `${fqn}-${signature}`;
     let js_method = boundMethodsByFqn.get(key);
@@ -82,7 +82,7 @@ export function mono_bind_assembly_entry_point(assembly: string, signature?: str
 }
 
 export function mono_call_assembly_entry_point(assembly: string, args?: any[], signature?: string/*ArgsMarshalString*/): number {
-    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
+    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "The runtime must be initialized.");
     if (!args) {
         args = [[]];
     }
diff --git a/src/mono/wasm/runtime/run.ts b/src/mono/wasm/runtime/run.ts
index 1572b8eb70c250..0a602566dfa7ab 100644
--- a/src/mono/wasm/runtime/run.ts
+++ b/src/mono/wasm/runtime/run.ts
@@ -34,7 +34,7 @@ export async function mono_run_main(main_assembly_name: string, args: string[]):
 }
 
 export function find_entry_point(assembly: string) {
-    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "Expected binding to be initialized later during startup sequence.");
+    mono_assert(runtimeHelpers.mono_wasm_bindings_is_ready, "The runtime must be initialized.");
     const asm = assembly_load(assembly);
     if (!asm)
         throw new Error("Could not find assembly: " + assembly);

From 2d9068e268253beda84b28b9368a437bb516f211 Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Wed, 3 Aug 2022 13:55:59 +0200
Subject: [PATCH 05/13] fix

---
 .../JavaScript/Interop/JavaScriptExports.cs      | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 3d09aeaf781e98..c17949d0727cef 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -55,8 +55,20 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 }
                 else if (method.ReturnType == typeof(Task))
                 {
-                    method.Invoke(null, argsToPass);
-                    result = null;
+                    Task result1 = (Task)method.Invoke(null, argsToPass)!;
+                    TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
+                    result = tcs.Task;
+                    result1.ContinueWith((t) =>
+                    {
+                        if (t.IsFaulted)
+                        {
+                            tcs.SetException(t.Exception!);
+                        }
+                        else
+                        {
+                            tcs.SetResult(0);
+                        }
+                    }, TaskScheduler.Default);
                 }
                 else if (method.ReturnType == typeof(Task<int>))
                 {

From bb4d41b3a7182f860860de7685cf1fc05fe3da13 Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Wed, 3 Aug 2022 15:40:20 +0200
Subject: [PATCH 06/13] fix

---
 src/mono/wasm/runtime/managed-exports.ts | 9 ++++++---
 src/mono/wasm/runtime/marshal-to-cs.ts   | 4 ++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/mono/wasm/runtime/managed-exports.ts b/src/mono/wasm/runtime/managed-exports.ts
index 1a891f4a75bf81..eba6ad05e32e4d 100644
--- a/src/mono/wasm/runtime/managed-exports.ts
+++ b/src/mono/wasm/runtime/managed-exports.ts
@@ -4,9 +4,9 @@
 import { GCHandle, MonoMethod, mono_assert } from "./types";
 import cwraps from "./cwraps";
 import { Module, runtimeHelpers } from "./imports";
-import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerToCs, MarshalerToJs, MarshalerType, set_arg_intptr, set_arg_type, set_gc_handle } from "./marshal";
+import { alloc_stack_frame, get_arg, get_arg_gc_handle, MarshalerToCs, MarshalerToJs, MarshalerType, set_arg_type, set_gc_handle } from "./marshal";
 import { invoke_method_and_handle_exception } from "./invoke-cs";
-import { marshal_array_to_cs_impl, marshal_exception_to_cs } from "./marshal-to-cs";
+import { marshal_array_to_cs_impl, marshal_exception_to_cs, marshal_intptr_to_cs } from "./marshal-to-cs";
 import { marshal_int32_to_js, marshal_task_to_js } from "./marshal-to-js";
 
 // in all the exported internals methods, we use the same data structures for stack frame as normal full blow interop
@@ -56,7 +56,7 @@ export function init_managed_exports(): void {
             const res = get_arg(args, 1);
             const arg1 = get_arg(args, 2);
             const arg2 = get_arg(args, 3);
-            set_arg_intptr(arg1, <any>entry_point);
+            marshal_intptr_to_cs(arg1, entry_point);
             if (program_args && program_args.length == 0) {
                 program_args = undefined;
             }
@@ -77,6 +77,7 @@ export function init_managed_exports(): void {
         try {
             const args = alloc_stack_frame(3);
             const arg1 = get_arg(args, 2);
+            set_arg_type(arg1, MarshalerType.Object);
             set_gc_handle(arg1, gc_handle);
             invoke_method_and_handle_exception(release_js_owned_object_by_gc_handle_method, args);
         } finally {
@@ -99,6 +100,7 @@ export function init_managed_exports(): void {
         try {
             const args = alloc_stack_frame(5);
             const arg1 = get_arg(args, 2);
+            set_arg_type(arg1, MarshalerType.Object);
             set_gc_handle(arg1, holder_gc_handle);
             const arg2 = get_arg(args, 3);
             if (error) {
@@ -120,6 +122,7 @@ export function init_managed_exports(): void {
             const args = alloc_stack_frame(6);
 
             const arg1 = get_arg(args, 2);
+            set_arg_type(arg1, MarshalerType.Object);
             set_gc_handle(arg1, callback_gc_handle);
             // payload arg numbers are shifted by one, the real first is a gc handle of the callback
 
diff --git a/src/mono/wasm/runtime/marshal-to-cs.ts b/src/mono/wasm/runtime/marshal-to-cs.ts
index 0b4df5365951d9..d16ed0f289e360 100644
--- a/src/mono/wasm/runtime/marshal-to-cs.ts
+++ b/src/mono/wasm/runtime/marshal-to-cs.ts
@@ -32,7 +32,7 @@ export function initialize_marshalers_to_cs(): void {
         js_to_cs_marshalers.set(MarshalerType.BigInt64, _marshal_bigint64_to_cs);
         js_to_cs_marshalers.set(MarshalerType.Double, _marshal_double_to_cs);
         js_to_cs_marshalers.set(MarshalerType.Single, _marshal_float_to_cs);
-        js_to_cs_marshalers.set(MarshalerType.IntPtr, _marshal_intptr_to_cs);
+        js_to_cs_marshalers.set(MarshalerType.IntPtr, marshal_intptr_to_cs);
         js_to_cs_marshalers.set(MarshalerType.DateTime, _marshal_date_time_to_cs);
         js_to_cs_marshalers.set(MarshalerType.DateTimeOffset, _marshal_date_time_offset_to_cs);
         js_to_cs_marshalers.set(MarshalerType.String, _marshal_string_to_cs);
@@ -238,7 +238,7 @@ function _marshal_float_to_cs(arg: JSMarshalerArgument, value: any): void {
     }
 }
 
-function _marshal_intptr_to_cs(arg: JSMarshalerArgument, value: any): void {
+export function marshal_intptr_to_cs(arg: JSMarshalerArgument, value: any): void {
     if (value === null || value === undefined) {
         set_arg_type(arg, MarshalerType.None);
     }

From b26c8565352118ca4ef4eb7a9d26ca440ca4e47f Mon Sep 17 00:00:00 2001
From: Ankit Jain <radical@gmail.com>
Date: Wed, 3 Aug 2022 17:42:51 +0000
Subject: [PATCH 07/13] [wasm] Fix Wasm.Build.Tests builds

Issue: https://github.com/dotnet/runtime/issues/73312
---
 eng/Versions.props | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/eng/Versions.props b/eng/Versions.props
index 2a45d875c7e826..bc6f6aaf9d1d79 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -163,7 +163,7 @@
     <MoqVersion>4.12.0</MoqVersion>
     <FsCheckVersion>2.14.3</FsCheckVersion>
     <!-- Uncomment to set a fixed version, else the latest is used -->
-    <!--<SdkVersionForWorkloadTesting>7.0.100-preview.3.22151.18</SdkVersionForWorkloadTesting>-->
+    <SdkVersionForWorkloadTesting>7.0.100-rc.1.22402.35</SdkVersionForWorkloadTesting>
     <CompilerPlatformTestingVersion>1.1.2-beta1.22205.2</CompilerPlatformTestingVersion>
     <!-- Docs -->
     <MicrosoftPrivateIntellisenseVersion>7.0.0-preview-20220721.1</MicrosoftPrivateIntellisenseVersion>

From b487be678cf538242149852f27a462d68c342ea0 Mon Sep 17 00:00:00 2001
From: Ankit Jain <radical@gmail.com>
Date: Wed, 3 Aug 2022 18:09:11 +0000
Subject: [PATCH 08/13] [wasm] Disable failing Wasm.Build.Tests test on windows

Issue: https://github.com/dotnet/runtime/issues/71887
---
 .../Wasm.Build.Tests/WasmTemplateTests.cs     | 25 +++++++++++++++----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs
index 9bb7d0a2179ce5..d7e136eb014309 100644
--- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs
+++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 
 using System;
+using System.Collections.Generic;
 using System.IO;
 using System.Threading.Tasks;
 using Xunit;
@@ -170,12 +171,26 @@ public void ConsoleBuildAndRun(string config, bool relinking)
             Assert.Contains("args[2] = z", output);
         }
 
+        public static TheoryData<string, bool, bool> TestDataForConsolePublishAndRun()
+        {
+            var data = new TheoryData<string, bool, bool>();
+            data.Add("Debug", false, false);
+            data.Add("Debug", false, false);
+            data.Add("Debug", false, true);
+            data.Add("Release", false, false); // Release relinks by default
+
+            // [ActiveIssue("https://github.com/dotnet/runtime/issues/71887", TestPlatforms.Windows)]
+            if (!OperatingSystem.IsWindows())
+            {
+                data.Add("Debug", true, false);
+                data.Add("Release", true, false);
+            }
+
+            return data;
+        }
+
         [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))]
-        [InlineData("Debug", false, false)]
-        [InlineData("Debug", false, true)]
-        [InlineData("Debug", true, false)]
-        [InlineData("Release", false, false)] // Release relinks by default
-        [InlineData("Release", true, false)]
+        [MemberData(nameof(TestDataForConsolePublishAndRun))]
         public void ConsolePublishAndRun(string config, bool aot, bool relinking)
         {
             string id = $"{config}_{Path.GetRandomFileName()}";

From d6c8330aa846d4b1b8b720168d503b43752b1a0f Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Thu, 4 Aug 2022 09:47:09 +0200
Subject: [PATCH 09/13] types cleanup

---
 src/mono/wasm/runtime/dotnet-legacy.d.ts      | 409 +++---------------
 src/mono/wasm/runtime/invoke-js.ts            |   4 +-
 src/mono/wasm/runtime/marshal.ts              |   4 +-
 src/mono/wasm/runtime/memory.ts               |   6 +-
 .../wasm/runtime/net6-legacy/corebindings.ts  |   4 +-
 src/mono/wasm/runtime/net6-legacy/cs-to-js.ts |   4 +-
 .../wasm/runtime/net6-legacy/export-types.ts  | 121 +++---
 .../runtime/net6-legacy/exports-legacy.ts     |   2 -
 src/mono/wasm/runtime/net6-legacy/js-to-cs.ts |   4 +-
 .../runtime/net6-legacy/method-binding.ts     |   4 +-
 .../wasm/runtime/net6-legacy/method-calls.ts  |   4 +-
 src/mono/wasm/runtime/roots.ts                |  29 +-
 src/mono/wasm/runtime/strings.ts              |   6 +-
 src/mono/wasm/runtime/types.ts                |  31 ++
 14 files changed, 167 insertions(+), 465 deletions(-)

diff --git a/src/mono/wasm/runtime/dotnet-legacy.d.ts b/src/mono/wasm/runtime/dotnet-legacy.d.ts
index 9043ae5717ab4b..dfcb17292ee228 100644
--- a/src/mono/wasm/runtime/dotnet-legacy.d.ts
+++ b/src/mono/wasm/runtime/dotnet-legacy.d.ts
@@ -14,56 +14,6 @@ declare interface NativePointer {
 declare interface VoidPtr extends NativePointer {
     __brand: "VoidPtr";
 }
-declare interface CharPtr extends NativePointer {
-    __brand: "CharPtr";
-}
-declare interface Int32Ptr extends NativePointer {
-    __brand: "Int32Ptr";
-}
-declare interface EmscriptenModule {
-    HEAP8: Int8Array;
-    HEAP16: Int16Array;
-    HEAP32: Int32Array;
-    HEAPU8: Uint8Array;
-    HEAPU16: Uint16Array;
-    HEAPU32: Uint32Array;
-    HEAPF32: Float32Array;
-    HEAPF64: Float64Array;
-    _malloc(size: number): VoidPtr;
-    _free(ptr: VoidPtr): void;
-    print(message: string): void;
-    printErr(message: string): void;
-    ccall<T>(ident: string, returnType?: string | null, argTypes?: string[], args?: any[], opts?: any): T;
-    cwrap<T extends Function>(ident: string, returnType: string, argTypes?: string[], opts?: any): T;
-    cwrap<T extends Function>(ident: string, ...args: any[]): T;
-    setValue(ptr: VoidPtr, value: number, type: string, noSafe?: number | boolean): void;
-    setValue(ptr: Int32Ptr, value: number, type: string, noSafe?: number | boolean): void;
-    getValue(ptr: number, type: string, noSafe?: number | boolean): number;
-    UTF8ToString(ptr: CharPtr, maxBytesToRead?: number): string;
-    UTF8ArrayToString(u8Array: Uint8Array, idx?: number, maxBytesToRead?: number): string;
-    FS_createPath(parent: string, path: string, canRead?: boolean, canWrite?: boolean): string;
-    FS_createDataFile(parent: string, name: string, data: TypedArray, canRead: boolean, canWrite: boolean, canOwn?: boolean): string;
-    FS_readFile(filename: string, opts: any): any;
-    removeRunDependency(id: string): void;
-    addRunDependency(id: string): void;
-    stackSave(): VoidPtr;
-    stackRestore(stack: VoidPtr): void;
-    stackAlloc(size: number): VoidPtr;
-    ready: Promise<unknown>;
-    instantiateWasm?: (imports: WebAssembly.Imports, successCallback: (instance: WebAssembly.Instance, module: WebAssembly.Module) => void) => any;
-    preInit?: (() => any)[] | (() => any);
-    preRun?: (() => any)[] | (() => any);
-    onRuntimeInitialized?: () => any;
-    postRun?: (() => any)[] | (() => any);
-    onAbort?: {
-        (error: any): void;
-    };
-}
-declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
-
-declare function mono_wasm_runtime_ready(): void;
-
-declare function mono_wasm_load_icu_data(offset: VoidPtr): boolean;
 
 interface MonoObject extends ManagedPointer {
     __brandMonoObject: "MonoObject";
@@ -77,151 +27,8 @@ interface MonoArray extends MonoObject {
 interface MonoObjectRef extends ManagedPointer {
     __brandMonoObjectRef: "MonoObjectRef";
 }
-declare type MonoConfig = {
-    assemblyRootFolder?: string;
-    assets?: AssetEntry[];
-    /**
-     * debugLevel > 0 enables debugging and sets the debug log level to debugLevel
-     * debugLevel == 0 disables debugging and enables interpreter optimizations
-     * debugLevel < 0 enabled debugging and disables debug logging.
-     */
-    debugLevel?: number;
-    maxParallelDownloads?: number;
-    globalizationMode?: GlobalizationMode;
-    diagnosticTracing?: boolean;
-    remoteSources?: string[];
-    environmentVariables?: {
-        [i: string]: string;
-    };
-    runtimeOptions?: string[];
-    aotProfilerOptions?: AOTProfilerOptions;
-    coverageProfilerOptions?: CoverageProfilerOptions;
-    ignorePdbLoadErrors?: boolean;
-    waitForDebugger?: number;
-};
-interface ResourceRequest {
-    name: string;
-    behavior: AssetBehaviours;
-    resolvedUrl?: string;
-    hash?: string;
-}
-interface AssetEntry extends ResourceRequest {
-    virtualPath?: string;
-    culture?: string;
-    loadRemote?: boolean;
-    isOptional?: boolean;
-    buffer?: ArrayBuffer;
-    pending?: LoadingResource;
-}
-declare type AssetBehaviours = "resource" | "assembly" | "pdb" | "heap" | "icu" | "vfs" | "dotnetwasm";
-declare type GlobalizationMode = "icu" | // load ICU globalization data from any runtime assets with behavior "icu".
-"invariant" | //  operate in invariant globalization mode.
-"auto";
-declare type AOTProfilerOptions = {
-    writeAt?: string;
-    sendTo?: string;
-};
-declare type CoverageProfilerOptions = {
-    writeAt?: string;
-    sendTo?: string;
-};
-interface LoadingResource {
-    name: string;
-    url: string;
-    response: Promise<Response>;
-}
-
-declare function mono_wasm_get_assembly_exports(assembly: string): Promise<any>;
-
 declare type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
 declare type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
-declare function setB32(offset: _MemOffset, value: number | boolean): void;
-declare function setU8(offset: _MemOffset, value: number): void;
-declare function setU16(offset: _MemOffset, value: number): void;
-declare function setU32(offset: _MemOffset, value: _NumberOrPointer): void;
-declare function setI8(offset: _MemOffset, value: number): void;
-declare function setI16(offset: _MemOffset, value: number): void;
-declare function setI32(offset: _MemOffset, value: number): void;
-/**
- * Throws for values which are not 52 bit integer. See Number.isSafeInteger()
- */
-declare function setI52(offset: _MemOffset, value: number): void;
-/**
- * Throws for values which are not 52 bit integer or are negative. See Number.isSafeInteger().
- */
-declare function setU52(offset: _MemOffset, value: number): void;
-declare function setI64Big(offset: _MemOffset, value: bigint): void;
-declare function setF32(offset: _MemOffset, value: number): void;
-declare function setF64(offset: _MemOffset, value: number): void;
-declare function getB32(offset: _MemOffset): boolean;
-declare function getU8(offset: _MemOffset): number;
-declare function getU16(offset: _MemOffset): number;
-declare function getU32(offset: _MemOffset): number;
-declare function getI8(offset: _MemOffset): number;
-declare function getI16(offset: _MemOffset): number;
-declare function getI32(offset: _MemOffset): number;
-/**
- * Throws for Number.MIN_SAFE_INTEGER > value > Number.MAX_SAFE_INTEGER
- */
-declare function getI52(offset: _MemOffset): number;
-/**
- * Throws for 0 > value > Number.MAX_SAFE_INTEGER
- */
-declare function getU52(offset: _MemOffset): number;
-declare function getI64Big(offset: _MemOffset): bigint;
-declare function getF32(offset: _MemOffset): number;
-declare function getF64(offset: _MemOffset): number;
-declare function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr;
-
-/**
- * Allocates a block of memory that can safely contain pointers into the managed heap.
- * The result object has get(index) and set(index, value) methods that can be used to retrieve and store managed pointers.
- * Once you are done using the root buffer, you must call its release() method.
- * For small numbers of roots, it is preferable to use the mono_wasm_new_root and mono_wasm_new_roots APIs instead.
- */
-declare function mono_wasm_new_root_buffer(capacity: number, name?: string): WasmRootBuffer;
-/**
- * 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().
- */
-declare function mono_wasm_new_external_root<T extends MonoObject>(address: VoidPtr | MonoObjectRef): WasmRoot<T>;
-/**
- * Allocates temporary storage for a pointer into the managed heap.
- * Pointers stored here will be visible to the GC, ensuring that the object they point to aren't moved or collected.
- * If you already have a managed pointer you can pass it as an argument to initialize the temporary storage.
- * 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<T extends MonoObject>(value?: T | undefined): WasmRoot<T>;
-/**
- * Releases 1 or more root or root buffer objects.
- * Multiple objects may be passed on the argument list.
- * 'undefined' may be passed as an argument so it is safe to call this method from finally blocks
- *  even if you are not sure all of your roots have been created yet.
- * @param {... WasmRoot} roots
- */
-declare function mono_wasm_release_roots(...args: WasmRoot<any>[]): void;
-declare class WasmRootBuffer {
-    private __count;
-    private length;
-    private __offset;
-    private __offset32;
-    private __handle;
-    private __ownsAllocation;
-    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): 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;
-    release(): void;
-    toString(): string;
-}
 interface WasmRoot<T extends MonoObject> {
     get_address(): MonoObjectRef;
     get_address_32(): number;
@@ -239,111 +46,17 @@ interface WasmRoot<T extends MonoObject> {
     release(): void;
     toString(): string;
 }
-
-/**
- * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
- */
-declare function mono_run_main_and_exit(main_assembly_name: string, args: string[]): Promise<void>;
-/**
- * Possible signatures are described here  https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
- */
-declare function mono_run_main(main_assembly_name: string, args: string[]): Promise<number>;
-
-interface APIType {
-    runMain: (mainAssemblyName: string, args: string[]) => Promise<number>;
-    runMainAndExit: (mainAssemblyName: string, args: string[]) => Promise<void>;
-    setEnvironmentVariable: (name: string, value: string) => void;
-    getAssemblyExports(assemblyName: string): Promise<any>;
-    setModuleImports(moduleName: string, moduleImports: any): void;
-    getConfig: () => MonoConfig;
-    setHeapB32: (offset: NativePointer, value: number | boolean) => void;
-    setHeapU8: (offset: NativePointer, value: number) => void;
-    setHeapU16: (offset: NativePointer, value: number) => void;
-    setHeapU32: (offset: NativePointer, value: NativePointer | number) => void;
-    setHeapI8: (offset: NativePointer, value: number) => void;
-    setHeapI16: (offset: NativePointer, value: number) => void;
-    setHeapI32: (offset: NativePointer, value: number) => void;
-    setHeapI52: (offset: NativePointer, value: number) => void;
-    setHeapU52: (offset: NativePointer, value: number) => void;
-    setHeapI64Big: (offset: NativePointer, value: bigint) => void;
-    setHeapF32: (offset: NativePointer, value: number) => void;
-    setHeapF64: (offset: NativePointer, value: number) => void;
-    getHeapB32: (offset: NativePointer) => boolean;
-    getHeapU8: (offset: NativePointer) => number;
-    getHeapU16: (offset: NativePointer) => number;
-    getHeapU32: (offset: NativePointer) => number;
-    getHeapI8: (offset: NativePointer) => number;
-    getHeapI16: (offset: NativePointer) => number;
-    getHeapI32: (offset: NativePointer) => number;
-    getHeapI52: (offset: NativePointer) => number;
-    getHeapU52: (offset: NativePointer) => number;
-    getHeapI64Big: (offset: NativePointer) => bigint;
-    getHeapF32: (offset: NativePointer) => number;
-    getHeapF64: (offset: NativePointer) => number;
-}
-declare type DotnetPublicAPI = {
-    /**
-     * @deprecated Please use API object instead. See also MONOType in dotnet-legacy.d.ts
-     */
-    MONO: any;
-    /**
-     * @deprecated Please use API object instead. See also BINDINGType in dotnet-legacy.d.ts
-     */
-    BINDING: any;
-    INTERNAL: any;
-    Module: EmscriptenModule;
-    runtimeId: number;
-    runtimeBuildInfo: {
-        productVersion: string;
-        buildConfiguration: string;
-    } & APIType;
-};
-
-declare global {
-    function getDotnetRuntime(runtimeId: number): DotnetPublicAPI | undefined;
+interface WasmRootBuffer {
+    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;
+    clear(): void;
+    release(): void;
+    toString(): string;
 }
 
-declare function mono_wasm_setenv(name: string, value: string): void;
-declare function mono_wasm_load_data_archive(data: Uint8Array, prefix: string): boolean;
-/**
- * Loads the mono config file (typically called mono-config.json) asynchroniously
- * Note: the run dependencies are so emsdk actually awaits it in order.
- *
- * @param {string} configFilePath - relative path to the config file
- * @throws Will throw an error if the config file loading fails
- */
-declare function mono_wasm_load_config(configFilePath: string): Promise<void>;
-
-/**
- * @deprecated Not GC or thread safe
- */
-declare function conv_string(mono_obj: MonoString): string | null;
-declare function conv_string_root(root: WasmRoot<MonoString>): string | null;
-declare function js_string_to_mono_string_root(string: string, result: WasmRoot<MonoString>): void;
-/**
- * @deprecated Not GC or thread safe
- */
-declare function js_string_to_mono_string(string: string): MonoString;
-
-declare function unbox_mono_obj(mono_obj: MonoObject): any;
-declare function unbox_mono_obj_root(root: WasmRoot<any>): any;
-declare function mono_array_to_js_array(mono_array: MonoArray): any[] | null;
-declare function mono_array_root_to_js_array(arrayRoot: WasmRoot<MonoArray>): any[] | null;
-
-/**
- * @deprecated Not GC or thread safe. For blazor use only
- */
-declare function js_to_mono_obj(js_obj: any): MonoObject;
-declare function js_to_mono_obj_root(js_obj: any, result: WasmRoot<MonoObject>, should_add_in_flight: boolean): void;
-declare function js_typed_array_to_array_root(js_obj: any, result: WasmRoot<MonoArray>): void;
-/**
- * @deprecated Not GC or thread safe
- */
-declare function js_typed_array_to_array(js_obj: any): MonoArray;
-
-declare function mono_bind_static_method(fqn: string, signature?: string): Function;
-declare function mono_call_assembly_entry_point(assembly: string, args?: any[], signature?: string): number;
-
 /**
  * @deprecated Please use methods in top level API object instead
  */
@@ -351,11 +64,11 @@ declare type BINDINGType = {
     /**
      * @deprecated Please use [JSExportAttribute] instead
      */
-    bind_static_method: typeof mono_bind_static_method;
+    bind_static_method: (fqn: string, signature?: string) => Function;
     /**
      * @deprecated Please use runMain() instead
      */
-    call_assembly_entry_point: typeof mono_call_assembly_entry_point;
+    call_assembly_entry_point: (assembly: string, args?: any[], signature?: string) => number;
     /**
      * @deprecated Not GC or thread safe
      */
@@ -367,27 +80,27 @@ declare type BINDINGType = {
     /**
      * @deprecated Not GC or thread safe
      */
-    js_string_to_mono_string: typeof js_string_to_mono_string;
+    js_string_to_mono_string: (string: string) => MonoString;
     /**
      * @deprecated Not GC or thread safe
      */
-    js_typed_array_to_array: typeof js_typed_array_to_array;
+    js_typed_array_to_array: (js_obj: any) => MonoArray;
     /**
      * @deprecated Not GC or thread safe
      */
-    mono_array_to_js_array: typeof mono_array_to_js_array;
+    mono_array_to_js_array: (mono_array: MonoArray) => any[] | null;
     /**
      * @deprecated Not GC or thread safe
      */
-    js_to_mono_obj: typeof js_to_mono_obj;
+    js_to_mono_obj: (js_obj: any) => MonoObject;
     /**
      * @deprecated Not GC or thread safe
      */
-    conv_string: typeof conv_string;
+    conv_string: (mono_obj: MonoString) => string | null;
     /**
      * @deprecated Not GC or thread safe
      */
-    unbox_mono_obj: typeof unbox_mono_obj;
+    unbox_mono_obj: (mono_obj: MonoObject) => any;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
@@ -399,27 +112,27 @@ declare type BINDINGType = {
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
+    js_string_to_mono_string_root: (string: string, result: WasmRoot<MonoString>) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
+    js_typed_array_to_array_root: (js_obj: any, result: WasmRoot<MonoArray>) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_to_mono_obj_root: typeof js_to_mono_obj_root;
+    js_to_mono_obj_root: (js_obj: any, result: WasmRoot<MonoObject>, should_add_in_flight: boolean) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    conv_string_root: typeof conv_string_root;
+    conv_string_root: (root: WasmRoot<MonoString>) => string | null;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    unbox_mono_obj_root: typeof unbox_mono_obj_root;
+    unbox_mono_obj_root: (root: WasmRoot<any>) => any;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
+    mono_array_root_to_js_array: (arrayRoot: WasmRoot<MonoArray>) => any[] | null;
 };
 /**
  * @deprecated Please use methods in top level API object instead
@@ -428,27 +141,27 @@ declare type MONOType = {
     /**
      * @deprecated Please use setEnvironmentVariable() instead
      */
-    mono_wasm_setenv: typeof mono_wasm_setenv;
+    mono_wasm_setenv: (name: string, value: string) => void;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
+    mono_wasm_load_bytes_into_heap: (bytes: Uint8Array) => VoidPtr;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
+    mono_wasm_load_icu_data: (offset: VoidPtr) => boolean;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
+    mono_wasm_runtime_ready: () => void;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
+    mono_wasm_load_data_archive: (data: Uint8Array, prefix: string) => boolean;
     /**
      * @deprecated Please use configSrc instead
      */
-    mono_wasm_load_config: typeof mono_wasm_load_config;
+    mono_wasm_load_config: (configFilePath: string) => Promise<void>;
     /**
      * @deprecated Please use runMain instead
      */
@@ -456,31 +169,27 @@ declare type MONOType = {
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
+    mono_wasm_new_root_buffer: (capacity: number, name?: string) => WasmRootBuffer;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_root: typeof mono_wasm_new_root;
+    mono_wasm_new_root: <T extends MonoObject>(value?: T | undefined) => WasmRoot<T>;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
+    mono_wasm_new_external_root: <T extends MonoObject>(address: VoidPtr | MonoObjectRef) => WasmRoot<T>;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_release_roots: typeof mono_wasm_release_roots;
+    mono_wasm_release_roots: (...args: WasmRoot<any>[]) => void;
     /**
      * @deprecated Please use runMain instead
      */
-    mono_run_main: typeof mono_run_main;
+    mono_run_main: (main_assembly_name: string, args: string[]) => Promise<number>;
     /**
      * @deprecated Please use runMainAndExit instead
      */
-    mono_run_main_and_exit: typeof mono_run_main_and_exit;
-    /**
-     * @deprecated Please use getAssemblyExports instead
-     */
-    mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
+    mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise<void>;
     /**
      * @deprecated Please use config.assets instead
      */
@@ -500,99 +209,99 @@ declare type MONOType = {
     /**
      * @deprecated Please use setHeapB32
      */
-    setB32: typeof setB32;
+    setB32: (offset: _MemOffset, value: number | boolean) => void;
     /**
      * @deprecated Please use setHeapI8
      */
-    setI8: typeof setI8;
+    setI8: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI16
      */
-    setI16: typeof setI16;
+    setI16: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI32
      */
-    setI32: typeof setI32;
+    setI32: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI52
      */
-    setI52: typeof setI52;
+    setI52: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU52
      */
-    setU52: typeof setU52;
+    setU52: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI64Big
      */
-    setI64Big: typeof setI64Big;
+    setI64Big: (offset: _MemOffset, value: bigint) => void;
     /**
      * @deprecated Please use setHeapU8
      */
-    setU8: typeof setU8;
+    setU8: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU16
      */
-    setU16: typeof setU16;
+    setU16: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU32
      */
-    setU32: typeof setU32;
+    setU32: (offset: _MemOffset, value: _NumberOrPointer) => void;
     /**
      * @deprecated Please use setHeapF32
      */
-    setF32: typeof setF32;
+    setF32: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapF64
      */
-    setF64: typeof setF64;
+    setF64: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use getHeapB32
      */
-    getB32: typeof getB32;
+    getB32: (offset: _MemOffset) => boolean;
     /**
      * @deprecated Please use getHeapI8
      */
-    getI8: typeof getI8;
+    getI8: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI16
      */
-    getI16: typeof getI16;
+    getI16: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI32
      */
-    getI32: typeof getI32;
+    getI32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI52
      */
-    getI52: typeof getI52;
+    getI52: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU52
      */
-    getU52: typeof getU52;
+    getU52: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI64Big
      */
-    getI64Big: typeof getI64Big;
+    getI64Big: (offset: _MemOffset) => bigint;
     /**
      * @deprecated Please use getHeapU8
      */
-    getU8: typeof getU8;
+    getU8: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU16
      */
-    getU16: typeof getU16;
+    getU16: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU32
      */
-    getU32: typeof getU32;
+    getU32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapF32
      */
-    getF32: typeof getF32;
+    getF32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapF64
      */
-    getF64: typeof getF64;
+    getF64: (offset: _MemOffset) => number;
 };
 
 export { BINDINGType, MONOType };
diff --git a/src/mono/wasm/runtime/invoke-js.ts b/src/mono/wasm/runtime/invoke-js.ts
index 1482b3f4383c2e..f6a65f43f1d3f8 100644
--- a/src/mono/wasm/runtime/invoke-js.ts
+++ b/src/mono/wasm/runtime/invoke-js.ts
@@ -6,11 +6,11 @@ import { marshal_exception_to_cs, generate_arg_marshal_to_cs } from "./marshal-t
 import { get_signature_argument_count, JavaScriptMarshalerArgSize, bound_js_function_symbol, JSMarshalerTypeSize, get_sig, JSMarshalerSignatureHeaderSize, get_signature_version, MarshalerType, get_signature_type } from "./marshal";
 import { setI32 } from "./memory";
 import { conv_string_root, js_string_to_mono_string_root } from "./strings";
-import { mono_assert, JSHandle, MonoObject, MonoObjectRef, MonoString, MonoStringRef, JSFunctionSignature, JSMarshalerArguments } from "./types";
+import { mono_assert, JSHandle, MonoObject, MonoObjectRef, MonoString, MonoStringRef, JSFunctionSignature, JSMarshalerArguments, WasmRoot } from "./types";
 import { Int32Ptr } from "./types/emscripten";
 import { IMPORTS, INTERNAL, Module, runtimeHelpers } from "./imports";
 import { generate_arg_marshal_to_js } from "./marshal-to-js";
-import { mono_wasm_new_external_root, WasmRoot } from "./roots";
+import { mono_wasm_new_external_root } from "./roots";
 import { mono_wasm_symbolicate_string } from "./debug";
 
 export function mono_wasm_bind_js_function(function_name: MonoStringRef, module_name: MonoStringRef, signature: JSFunctionSignature, function_js_handle: Int32Ptr, is_exception: Int32Ptr, result_address: MonoObjectRef): void {
diff --git a/src/mono/wasm/runtime/marshal.ts b/src/mono/wasm/runtime/marshal.ts
index 4b0700714c39b8..77bec6b6aa762f 100644
--- a/src/mono/wasm/runtime/marshal.ts
+++ b/src/mono/wasm/runtime/marshal.ts
@@ -4,8 +4,8 @@
 import { js_owned_gc_handle_symbol, teardown_managed_proxy } from "./gc-handles";
 import { Module } from "./imports";
 import { getF32, getF64, getI16, getI32, getI64Big, getU16, getU32, getU8, setF32, setF64, setI16, setI32, setI64Big, setU16, setU32, setU8 } from "./memory";
-import { mono_wasm_new_external_root, WasmRoot } from "./roots";
-import { mono_assert, GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerArguments, JSFunctionSignature, JSMarshalerType, JSMarshalerArgument, MarshalerToJs, MarshalerToCs } from "./types";
+import { mono_wasm_new_external_root } from "./roots";
+import { mono_assert, GCHandle, JSHandle, MonoObject, MonoString, GCHandleNull, JSMarshalerArguments, JSFunctionSignature, JSMarshalerType, JSMarshalerArgument, MarshalerToJs, MarshalerToCs, WasmRoot } from "./types";
 import { CharPtr, TypedArray, VoidPtr } from "./types/emscripten";
 
 export const cs_to_js_marshalers = new Map<MarshalerType, MarshalerToJs>();
diff --git a/src/mono/wasm/runtime/memory.ts b/src/mono/wasm/runtime/memory.ts
index 1653b94af2b72d..05d64666ffa5d0 100644
--- a/src/mono/wasm/runtime/memory.ts
+++ b/src/mono/wasm/runtime/memory.ts
@@ -1,7 +1,7 @@
 import monoWasmThreads from "consts:monoWasmThreads";
 import { Module, runtimeHelpers } from "./imports";
-import { mono_assert } from "./types";
-import { VoidPtr, NativePointer, ManagedPointer } from "./types/emscripten";
+import { mono_assert, _MemOffset, _NumberOrPointer } from "./types";
+import { VoidPtr } from "./types/emscripten";
 import * as cuint64 from "./cuint64";
 import cwraps, { I52Error } from "./cwraps";
 
@@ -44,8 +44,6 @@ export function _release_temp_frame(): void {
     alloca_offset = <VoidPtr>alloca_stack.pop();
 }
 
-type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
-type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
 
 function assert_int_in_range(value: Number, min: Number, max: Number) {
     mono_assert(Number.isSafeInteger(value), () => `Value is not an integer: ${value} (${typeof (value)})`);
diff --git a/src/mono/wasm/runtime/net6-legacy/corebindings.ts b/src/mono/wasm/runtime/net6-legacy/corebindings.ts
index 062de20442e3c3..759f84e1a307cd 100644
--- a/src/mono/wasm/runtime/net6-legacy/corebindings.ts
+++ b/src/mono/wasm/runtime/net6-legacy/corebindings.ts
@@ -1,9 +1,9 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-import { JSHandle, GCHandle, MonoObjectRef, MonoMethod, MonoObject } from "../types";
+import { JSHandle, GCHandle, MonoObjectRef, MonoMethod, MonoObject, WasmRoot } from "../types";
 import { mono_bind_method, _create_primitive_converters } from "./method-binding";
-import { mono_wasm_new_root, WasmRoot } from "../roots";
+import { mono_wasm_new_root } from "../roots";
 import { Module, runtimeHelpers } from "../imports";
 import cwraps from "../cwraps";
 import { PromiseController } from "../promise-controller";
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 e592523a00d705..faecba1fdb5639 100644
--- a/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts
+++ b/src/mono/wasm/runtime/net6-legacy/cs-to-js.ts
@@ -5,9 +5,9 @@ import { wrap_error_root } from "../invoke-js";
 import { ManagedObject } from "../marshal";
 import { getU32, getI32, getF32, getF64, setI32_unchecked } from "../memory";
 import { createPromiseController } from "../promise-controller";
-import { WasmRoot, mono_wasm_new_root, mono_wasm_new_external_root } from "../roots";
+import { mono_wasm_new_root, mono_wasm_new_external_root } from "../roots";
 import { conv_string_root } from "../strings";
-import { MarshalType, MonoType, MarshalError, MonoTypeNull, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, GCHandle, MonoStringRef, MonoObjectRef, MonoString, JSHandleDisposed, is_nullish } from "../types";
+import { MarshalType, MonoType, MarshalError, MonoTypeNull, MonoArray, MonoArrayNull, MonoObject, MonoObjectNull, GCHandle, MonoStringRef, MonoObjectRef, MonoString, JSHandleDisposed, is_nullish, WasmRoot } from "../types";
 import { Int32Ptr, VoidPtr } from "../types/emscripten";
 import { legacyManagedExports } from "./corebindings";
 import { legacyHelpers } from "./imports";
diff --git a/src/mono/wasm/runtime/net6-legacy/export-types.ts b/src/mono/wasm/runtime/net6-legacy/export-types.ts
index c2f9022c377b2e..8dcd913ca9dcda 100644
--- a/src/mono/wasm/runtime/net6-legacy/export-types.ts
+++ b/src/mono/wasm/runtime/net6-legacy/export-types.ts
@@ -1,16 +1,5 @@
-import { mono_wasm_runtime_ready } from "../debug";
-import { mono_wasm_load_icu_data } from "../icu";
-import { mono_wasm_get_assembly_exports } from "../invoke-cs";
-import { mono_wasm_load_bytes_into_heap, setB32, setI8, setI16, setI32, setI52, setU52, setI64Big, setU8, setU16, setU32, setF32, setF64, getB32, getI8, getI16, getI32, getI52, getU52, getI64Big, getU8, getU16, getU32, getF32, getF64 } from "../memory";
-import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_root, mono_wasm_release_roots } from "../roots";
-import { mono_run_main, mono_run_main_and_exit } from "../run";
-import { mono_wasm_setenv, mono_wasm_load_data_archive, mono_wasm_load_config } from "../startup";
-import { js_string_to_mono_string, conv_string, js_string_to_mono_string_root, conv_string_root } from "../strings";
-import { MonoArray, MonoObject, MonoObjectRef } from "../types";
+import { MonoArray, MonoObject, MonoObjectRef, MonoString, WasmRoot, WasmRootBuffer, _MemOffset, _NumberOrPointer } from "../types";
 import { VoidPtr } from "../types/emscripten";
-import { mono_array_to_js_array, unbox_mono_obj, unbox_mono_obj_root, mono_array_root_to_js_array } from "./cs-to-js";
-import { js_typed_array_to_array, js_to_mono_obj, js_typed_array_to_array_root, js_to_mono_obj_root } from "./js-to-cs";
-import { mono_bind_static_method, mono_call_assembly_entry_point } from "./method-calls";
 
 /**
  * @deprecated Please use methods in top level API object instead
@@ -19,11 +8,11 @@ export type BINDINGType = {
     /**
      * @deprecated Please use [JSExportAttribute] instead
      */
-    bind_static_method: typeof mono_bind_static_method;
+    bind_static_method: (fqn: string, signature?: string) => Function;
     /**
      * @deprecated Please use runMain() instead
      */
-    call_assembly_entry_point: typeof mono_call_assembly_entry_point;
+    call_assembly_entry_point: (assembly: string, args?: any[], signature?: string) => number;
     /**
      * @deprecated Not GC or thread safe
      */
@@ -35,27 +24,27 @@ export type BINDINGType = {
     /**
      * @deprecated Not GC or thread safe
      */
-    js_string_to_mono_string: typeof js_string_to_mono_string;
+    js_string_to_mono_string: (string: string) => MonoString;
     /**
      * @deprecated Not GC or thread safe
      */
-    js_typed_array_to_array: typeof js_typed_array_to_array;
+    js_typed_array_to_array: (js_obj: any) => MonoArray;
     /**
      * @deprecated Not GC or thread safe
      */
-    mono_array_to_js_array: typeof mono_array_to_js_array;
+    mono_array_to_js_array: (mono_array: MonoArray) => any[] | null;
     /**
      * @deprecated Not GC or thread safe
      */
-    js_to_mono_obj: typeof js_to_mono_obj;
+    js_to_mono_obj: (js_obj: any) => MonoObject;
     /**
      * @deprecated Not GC or thread safe
      */
-    conv_string: typeof conv_string;
+    conv_string: (mono_obj: MonoString) => string | null;
     /**
      * @deprecated Not GC or thread safe
      */
-    unbox_mono_obj: typeof unbox_mono_obj;
+    unbox_mono_obj: (mono_obj: MonoObject) => any;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
@@ -67,28 +56,28 @@ export type BINDINGType = {
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_string_to_mono_string_root: typeof js_string_to_mono_string_root;
+    js_string_to_mono_string_root: (string: string, result: WasmRoot<MonoString>) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_typed_array_to_array_root: typeof js_typed_array_to_array_root;
+    js_typed_array_to_array_root: (js_obj: any, result: WasmRoot<MonoArray>) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    js_to_mono_obj_root: typeof js_to_mono_obj_root;
+    js_to_mono_obj_root: (js_obj: any, result: WasmRoot<MonoObject>, should_add_in_flight: boolean) => void;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    conv_string_root: typeof conv_string_root;
+    conv_string_root: (root: WasmRoot<MonoString>) => string | null;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    unbox_mono_obj_root: typeof unbox_mono_obj_root;
+    unbox_mono_obj_root: (root: WasmRoot<any>) => any;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_array_root_to_js_array: typeof mono_array_root_to_js_array;
-}
+    mono_array_root_to_js_array: (arrayRoot: WasmRoot<MonoArray>) => any[] | null;
+};
 
 /**
  * @deprecated Please use methods in top level API object instead
@@ -97,27 +86,27 @@ export type MONOType = {
     /**
      * @deprecated Please use setEnvironmentVariable() instead
      */
-    mono_wasm_setenv: typeof mono_wasm_setenv;
+    mono_wasm_setenv: (name: string, value: string) => void;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_bytes_into_heap: typeof mono_wasm_load_bytes_into_heap;
+    mono_wasm_load_bytes_into_heap: (bytes: Uint8Array) => VoidPtr;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_icu_data: typeof mono_wasm_load_icu_data;
+    mono_wasm_load_icu_data: (offset: VoidPtr) => boolean;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_runtime_ready: typeof mono_wasm_runtime_ready;
+    mono_wasm_runtime_ready: () => void;
     /**
      * @deprecated Please use config.assets instead
      */
-    mono_wasm_load_data_archive: typeof mono_wasm_load_data_archive;
+    mono_wasm_load_data_archive: (data: Uint8Array, prefix: string) => boolean;
     /**
      * @deprecated Please use configSrc instead
      */
-    mono_wasm_load_config: typeof mono_wasm_load_config;
+    mono_wasm_load_config: (configFilePath: string) => Promise<void>;
     /**
      * @deprecated Please use runMain instead
      */
@@ -125,31 +114,27 @@ export type MONOType = {
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_root_buffer: typeof mono_wasm_new_root_buffer;
+    mono_wasm_new_root_buffer: (capacity: number, name?: string) => WasmRootBuffer;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_root: typeof mono_wasm_new_root;
+    mono_wasm_new_root: <T extends MonoObject>(value?: T | undefined) => WasmRoot<T>;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_new_external_root: typeof mono_wasm_new_external_root;
+    mono_wasm_new_external_root: <T extends MonoObject>(address: VoidPtr | MonoObjectRef) => WasmRoot<T>;
     /**
      * @deprecated Please use [JSImportAttribute] or [JSExportAttribute] for interop instead.
      */
-    mono_wasm_release_roots: typeof mono_wasm_release_roots;
+    mono_wasm_release_roots: (...args: WasmRoot<any>[]) => void;
     /**
      * @deprecated Please use runMain instead
      */
-    mono_run_main: typeof mono_run_main;
+    mono_run_main: (main_assembly_name: string, args: string[]) => Promise<number>;
     /**
      * @deprecated Please use runMainAndExit instead
      */
-    mono_run_main_and_exit: typeof mono_run_main_and_exit;
-    /**
-     * @deprecated Please use getAssemblyExports instead
-     */
-    mono_wasm_get_assembly_exports: typeof mono_wasm_get_assembly_exports;
+    mono_run_main_and_exit: (main_assembly_name: string, args: string[]) => Promise<void>;
     /**
      * @deprecated Please use config.assets instead
      */
@@ -169,97 +154,97 @@ export type MONOType = {
     /**
      * @deprecated Please use setHeapB32
      */
-    setB32: typeof setB32;
+    setB32: (offset: _MemOffset, value: number | boolean) => void;
     /**
      * @deprecated Please use setHeapI8
      */
-    setI8: typeof setI8;
+    setI8: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI16
      */
-    setI16: typeof setI16;
+    setI16: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI32
      */
-    setI32: typeof setI32;
+    setI32: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI52
      */
-    setI52: typeof setI52;
+    setI52: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU52
      */
-    setU52: typeof setU52;
+    setU52: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI64Big
      */
-    setI64Big: typeof setI64Big;
+    setI64Big: (offset: _MemOffset, value: bigint) => void;
     /**
      * @deprecated Please use setHeapU8
      */
-    setU8: typeof setU8;
+    setU8: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU16
      */
-    setU16: typeof setU16;
+    setU16: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU32
      */
-    setU32: typeof setU32;
+    setU32: (offset: _MemOffset, value: _NumberOrPointer) => void;
     /**
      * @deprecated Please use setHeapF32
      */
-    setF32: typeof setF32;
+    setF32: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapF64
      */
-    setF64: typeof setF64;
+    setF64: (offset: _MemOffset, value: number) => void;
     /**
      * @deprecated Please use getHeapB32
      */
-    getB32: typeof getB32;
+    getB32: (offset: _MemOffset) => boolean;
     /**
      * @deprecated Please use getHeapI8
      */
-    getI8: typeof getI8;
+    getI8: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI16
      */
-    getI16: typeof getI16;
+    getI16: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI32
      */
-    getI32: typeof getI32;
+    getI32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI52
      */
-    getI52: typeof getI52;
+    getI52: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU52
      */
-    getU52: typeof getU52;
+    getU52: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapI64Big
      */
-    getI64Big: typeof getI64Big;
+    getI64Big: (offset: _MemOffset) => bigint;
     /**
      * @deprecated Please use getHeapU8
      */
-    getU8: typeof getU8;
+    getU8: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU16
      */
-    getU16: typeof getU16;
+    getU16: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapU32
      */
-    getU32: typeof getU32;
+    getU32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapF32
      */
-    getF32: typeof getF32;
+    getF32: (offset: _MemOffset) => number;
     /**
      * @deprecated Please use getHeapF64
      */
-    getF64: typeof getF64;
-}
\ No newline at end of file
+    getF64: (offset: _MemOffset) => number;
+};
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts
index 7dd9f494aa424c..4202cf7ebc3406 100644
--- a/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts
+++ b/src/mono/wasm/runtime/net6-legacy/exports-legacy.ts
@@ -2,7 +2,6 @@ import cwraps from "../cwraps";
 import { mono_wasm_runtime_ready } from "../debug";
 import { mono_wasm_load_icu_data } from "../icu";
 import { runtimeHelpers } from "../imports";
-import { mono_wasm_get_assembly_exports } from "../invoke-cs";
 import { mono_wasm_load_bytes_into_heap, setB32, setI8, setI16, setI32, setI52, setU52, setI64Big, setU8, setU16, setU32, setF32, setF64, getB32, getI8, getI16, getI32, getI52, getU52, getI64Big, getU8, getU16, getU32, getF32, getF64 } from "../memory";
 import { mono_wasm_new_root_buffer, mono_wasm_new_root, mono_wasm_new_external_root, mono_wasm_release_roots } from "../roots";
 import { mono_run_main, mono_run_main_and_exit } from "../run";
@@ -31,7 +30,6 @@ export function export_mono_api(): MONOType {
         mono_wasm_release_roots,
         mono_run_main,
         mono_run_main_and_exit,
-        mono_wasm_get_assembly_exports,
 
         // for Blazor's future!
         mono_wasm_add_assembly: <any>null,
diff --git a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
index d76d1041a6a145..5cd7c406a978b6 100644
--- a/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
+++ b/src/mono/wasm/runtime/net6-legacy/js-to-cs.ts
@@ -4,9 +4,9 @@ import { js_owned_gc_handle_symbol, assert_not_disposed, cs_owned_js_handle_symb
 import { Module } from "../imports";
 import { wrap_error_root } from "../invoke-js";
 import { setI32_unchecked, setU32_unchecked, setF64, setB32 } from "../memory";
-import { WasmRoot, mono_wasm_new_root, mono_wasm_release_roots, mono_wasm_new_external_root } from "../roots";
+import { mono_wasm_new_root, mono_wasm_release_roots, mono_wasm_new_external_root } from "../roots";
 import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root } from "../strings";
-import { MonoObject, is_nullish, MonoClass, MonoArray, MonoMethod, MonoObjectNull, JSHandle, MonoObjectRef, JSHandleNull, JSHandleDisposed } from "../types";
+import { MonoObject, is_nullish, MonoClass, MonoArray, MonoMethod, MonoObjectNull, JSHandle, MonoObjectRef, JSHandleNull, JSHandleDisposed, WasmRoot } from "../types";
 import { TypedArray, Int32Ptr } from "../types/emscripten";
 import { has_backing_array_buffer } from "./buffers";
 import { legacyManagedExports } from "./corebindings";
diff --git a/src/mono/wasm/runtime/net6-legacy/method-binding.ts b/src/mono/wasm/runtime/net6-legacy/method-binding.ts
index aa40ba6b35b544..d890508263ae58 100644
--- a/src/mono/wasm/runtime/net6-legacy/method-binding.ts
+++ b/src/mono/wasm/runtime/net6-legacy/method-binding.ts
@@ -5,9 +5,9 @@ import cwraps from "../cwraps";
 import { Module } from "../imports";
 import { parseFQN } from "../invoke-cs";
 import { setI32, setU32, setF32, setF64, setU52, setI52, setB32, setI32_unchecked, setU32_unchecked, _zero_region, _create_temp_frame, getB32, getI32, getU32, getF32, getF64 } from "../memory";
-import { WasmRoot, mono_wasm_new_external_root, mono_wasm_new_root, WasmRootBuffer } from "../roots";
+import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots";
 import { js_string_to_mono_string_root, js_string_to_mono_string_interned_root, conv_string_root } from "../strings";
-import { MonoMethod, MonoObject, MonoType, MonoClass, mono_assert, VoidPtrNull, MarshalType, MonoString, MonoObjectNull } from "../types";
+import { MonoMethod, MonoObject, MonoType, MonoClass, mono_assert, VoidPtrNull, MarshalType, MonoString, MonoObjectNull, WasmRootBuffer, WasmRoot } from "../types";
 import { VoidPtr } from "../types/emscripten";
 import { legacyManagedExports } from "./corebindings";
 import { get_js_owned_object_by_gc_handle_ref, _unbox_mono_obj_root_with_known_nonprimitive_type } from "./cs-to-js";
diff --git a/src/mono/wasm/runtime/net6-legacy/method-calls.ts b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
index c9d487d41bdb36..37790b769be2e4 100644
--- a/src/mono/wasm/runtime/net6-legacy/method-calls.ts
+++ b/src/mono/wasm/runtime/net6-legacy/method-calls.ts
@@ -5,10 +5,10 @@ import { get_js_obj, mono_wasm_get_jsobj_from_js_handle } from "../gc-handles";
 import { Module, runtimeHelpers, INTERNAL } from "../imports";
 import { wrap_error_root } from "../invoke-js";
 import { _release_temp_frame } from "../memory";
-import { WasmRoot, mono_wasm_new_external_root, mono_wasm_new_root } from "../roots";
+import { mono_wasm_new_external_root, mono_wasm_new_root } from "../roots";
 import { find_entry_point } from "../run";
 import { conv_string_root, js_string_to_mono_string_root } from "../strings";
-import { JSHandle, MonoStringRef, MonoObjectRef, MonoArray, MonoString, MonoObject, is_nullish, mono_assert } from "../types";
+import { JSHandle, MonoStringRef, MonoObjectRef, MonoArray, MonoString, MonoObject, is_nullish, mono_assert, WasmRoot } from "../types";
 import { Int32Ptr, VoidPtr } from "../types/emscripten";
 import { mono_array_root_to_js_array, unbox_mono_obj_root } from "./cs-to-js";
 import { js_array_to_mono_array, js_to_mono_obj_root } from "./js-to-cs";
diff --git a/src/mono/wasm/runtime/roots.ts b/src/mono/wasm/runtime/roots.ts
index 7868f18e2259d8..6f33a644765629 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, MonoObject, is_nullish } from "./types";
+import { MonoObjectRef, MonoObjectRefNull, MonoObject, is_nullish, WasmRoot, WasmRootBuffer } from "./types";
 import { _zero_region } from "./memory";
 
 const maxScratchRoots = 8192;
@@ -33,7 +33,7 @@ export function mono_wasm_new_root_buffer(capacity: number, name?: string): Wasm
 
     _zero_region(offset, capacityBytes);
 
-    return new WasmRootBuffer(offset, capacity, true, name);
+    return new WasmRootBufferImpl(offset, capacity, true, name);
 }
 
 /**
@@ -52,7 +52,7 @@ export function mono_wasm_new_root_buffer_from_pointer(offset: VoidPtr, capacity
 
     _zero_region(offset, capacityBytes);
 
-    return new WasmRootBuffer(offset, capacity, false, name);
+    return new WasmRootBufferImpl(offset, capacity, false, name);
 }
 
 /**
@@ -173,8 +173,7 @@ function _mono_wasm_claim_scratch_index() {
     return result;
 }
 
-
-export class WasmRootBuffer {
+export class WasmRootBufferImpl implements WasmRootBuffer {
     private __count: number;
     private length: number;
     private __offset: VoidPtr;
@@ -261,24 +260,6 @@ export class WasmRootBuffer {
     }
 }
 
-export interface WasmRoot<T extends MonoObject> {
-    get_address(): MonoObjectRef;
-    get_address_32(): number;
-    get address(): MonoObjectRef;
-    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<T>): void;
-    copy_to(destination: WasmRoot<T>): void;
-    valueOf(): T;
-    clear(): void;
-    release(): void;
-    toString(): string;
-}
-
 class WasmJsOwnedRoot<T extends MonoObject> implements WasmRoot<T> {
     private __buffer: WasmRootBuffer;
     private __index: number;
@@ -301,7 +282,7 @@ class WasmJsOwnedRoot<T extends MonoObject> implements WasmRoot<T> {
     }
 
     get(): T {
-        const result = this.__buffer._unsafe_get(this.__index);
+        const result = (<WasmRootBufferImpl>this.__buffer)._unsafe_get(this.__index);
         return <any>result;
     }
 
diff --git a/src/mono/wasm/runtime/strings.ts b/src/mono/wasm/runtime/strings.ts
index a8faf7ad9de3ff..8eba930124db5c 100644
--- a/src/mono/wasm/runtime/strings.ts
+++ b/src/mono/wasm/runtime/strings.ts
@@ -1,11 +1,11 @@
 // 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, WasmRootBuffer } from "./roots";
-import { MonoString, MonoStringNull, is_nullish } from "./types";
+import { mono_wasm_new_root_buffer } from "./roots";
+import { MonoString, MonoStringNull, is_nullish, WasmRoot, WasmRootBuffer } from "./types";
 import { Module } from "./imports";
 import cwraps from "./cwraps";
-import { mono_wasm_new_root, WasmRoot } from "./roots";
+import { mono_wasm_new_root } from "./roots";
 import { getI32, getU32 } from "./memory";
 import { NativePointer, CharPtr } from "./types/emscripten";
 
diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts
index 702504497dc11c..a1b938e123e3c5 100644
--- a/src/mono/wasm/runtime/types.ts
+++ b/src/mono/wasm/runtime/types.ts
@@ -379,3 +379,34 @@ export interface JSMarshalerArgument extends NativePointer {
     __brand: "JSMarshalerArgument"
 }
 
+export type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
+export type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
+
+export interface WasmRoot<T extends MonoObject> {
+    get_address(): MonoObjectRef;
+    get_address_32(): number;
+    get address(): MonoObjectRef;
+    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<T>): void;
+    copy_to(destination: WasmRoot<T>): void;
+    valueOf(): T;
+    clear(): void;
+    release(): void;
+    toString(): string;
+}
+
+export interface WasmRootBuffer {
+    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
+    clear(): void;
+    release(): void;
+    toString(): string;
+}

From f1a77d34d1ccdc2c285dd1239389b9590c44763a Mon Sep 17 00:00:00 2001
From: Pavel Savara <pavelsavara@microsoft.com>
Date: Thu, 4 Aug 2022 09:49:24 +0200
Subject: [PATCH 10/13] Update
 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Marek Fišera <mara@neptuo.com>
---
 .../InteropServices/JavaScript/Interop/JavaScriptExports.cs   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 9cbc65b6c8464e..12a3219bff60c3 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -55,10 +55,10 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 }
                 else if (method.ReturnType == typeof(Task))
                 {
-                    Task result1 = (Task)method.Invoke(null, argsToPass)!;
+                    Task methodResult = (Task)method.Invoke(null, argsToPass)!;
                     TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
                     result = tcs.Task;
-                    result1.ContinueWith((t) =>
+                    methodResult.ContinueWith((t) =>
                     {
                         if (t.IsFaulted)
                         {

From 3763a30a8788e0c23aabc3d735c1c2d7af0139b0 Mon Sep 17 00:00:00 2001
From: Pavel Savara <pavelsavara@microsoft.com>
Date: Thu, 4 Aug 2022 09:49:40 +0200
Subject: [PATCH 11/13] Update
 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Marek Fišera <mara@neptuo.com>
---
 .../InteropServices/JavaScript/Interop/JavaScriptExports.cs     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index 12a3219bff60c3..f96f7f86b31492 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -37,7 +37,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 }
 
                 arg_2.ToManaged(out string?[]? args);
-                object[] argsToPass= System.Array.Empty<object>();
+                object[] argsToPass = System.Array.Empty<object>();
                 Task<int>? result = null;
                 var parameterInfos = method.GetParameters();
                 if (parameterInfos.Length > 0 && parameterInfos[0].ParameterType == typeof(string[]))

From 00f8f08bc03f83a445d00b922d4dee9c01cd1ca8 Mon Sep 17 00:00:00 2001
From: Pavel Savara <pavelsavara@microsoft.com>
Date: Thu, 4 Aug 2022 09:49:59 +0200
Subject: [PATCH 12/13] Update
 src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Marek Fišera <mara@neptuo.com>
---
 .../InteropServices/JavaScript/Interop/JavaScriptExports.cs     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
index f96f7f86b31492..7434974ae1319f 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System/Runtime/InteropServices/JavaScript/Interop/JavaScriptExports.cs
@@ -76,7 +76,7 @@ public static void CallEntrypoint(JSMarshalerArgument* arguments_buffer)
                 }
                 else
                 {
-                    throw new InvalidProgramException(method.ReturnType.FullName);
+                    throw new InvalidProgramException($"Return type '{method.ReturnType.FullName}' from main method in not supported");
                 }
                 arg_result.ToJS(result, (ref JSMarshalerArgument arg, int value) =>
                 {

From b950b9f1488408f06374775d51ab1235f857d7b9 Mon Sep 17 00:00:00 2001
From: pavelsavara <pavel.savara@gmail.com>
Date: Thu, 4 Aug 2022 09:58:36 +0200
Subject: [PATCH 13/13] feedback

---
 src/mono/wasm/runtime/dotnet-legacy.d.ts      | 52 ++++++++--------
 src/mono/wasm/runtime/memory.ts               | 62 +++++++++----------
 .../wasm/runtime/net6-legacy/export-types.ts  | 50 +++++++--------
 src/mono/wasm/runtime/types.ts                |  4 +-
 4 files changed, 84 insertions(+), 84 deletions(-)

diff --git a/src/mono/wasm/runtime/dotnet-legacy.d.ts b/src/mono/wasm/runtime/dotnet-legacy.d.ts
index dfcb17292ee228..a3b7591887d3ac 100644
--- a/src/mono/wasm/runtime/dotnet-legacy.d.ts
+++ b/src/mono/wasm/runtime/dotnet-legacy.d.ts
@@ -27,8 +27,8 @@ interface MonoArray extends MonoObject {
 interface MonoObjectRef extends ManagedPointer {
     __brandMonoObjectRef: "MonoObjectRef";
 }
-declare type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
-declare type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
+declare type MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
+declare type NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
 interface WasmRoot<T extends MonoObject> {
     get_address(): MonoObjectRef;
     get_address_32(): number;
@@ -209,99 +209,99 @@ declare type MONOType = {
     /**
      * @deprecated Please use setHeapB32
      */
-    setB32: (offset: _MemOffset, value: number | boolean) => void;
+    setB32: (offset: MemOffset, value: number | boolean) => void;
     /**
      * @deprecated Please use setHeapI8
      */
-    setI8: (offset: _MemOffset, value: number) => void;
+    setI8: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI16
      */
-    setI16: (offset: _MemOffset, value: number) => void;
+    setI16: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI32
      */
-    setI32: (offset: _MemOffset, value: number) => void;
+    setI32: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI52
      */
-    setI52: (offset: _MemOffset, value: number) => void;
+    setI52: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU52
      */
-    setU52: (offset: _MemOffset, value: number) => void;
+    setU52: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI64Big
      */
-    setI64Big: (offset: _MemOffset, value: bigint) => void;
+    setI64Big: (offset: MemOffset, value: bigint) => void;
     /**
      * @deprecated Please use setHeapU8
      */
-    setU8: (offset: _MemOffset, value: number) => void;
+    setU8: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU16
      */
-    setU16: (offset: _MemOffset, value: number) => void;
+    setU16: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU32
      */
-    setU32: (offset: _MemOffset, value: _NumberOrPointer) => void;
+    setU32: (offset: MemOffset, value: NumberOrPointer) => void;
     /**
      * @deprecated Please use setHeapF32
      */
-    setF32: (offset: _MemOffset, value: number) => void;
+    setF32: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapF64
      */
-    setF64: (offset: _MemOffset, value: number) => void;
+    setF64: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use getHeapB32
      */
-    getB32: (offset: _MemOffset) => boolean;
+    getB32: (offset: MemOffset) => boolean;
     /**
      * @deprecated Please use getHeapI8
      */
-    getI8: (offset: _MemOffset) => number;
+    getI8: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI16
      */
-    getI16: (offset: _MemOffset) => number;
+    getI16: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI32
      */
-    getI32: (offset: _MemOffset) => number;
+    getI32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI52
      */
-    getI52: (offset: _MemOffset) => number;
+    getI52: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU52
      */
-    getU52: (offset: _MemOffset) => number;
+    getU52: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI64Big
      */
-    getI64Big: (offset: _MemOffset) => bigint;
+    getI64Big: (offset: MemOffset) => bigint;
     /**
      * @deprecated Please use getHeapU8
      */
-    getU8: (offset: _MemOffset) => number;
+    getU8: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU16
      */
-    getU16: (offset: _MemOffset) => number;
+    getU16: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU32
      */
-    getU32: (offset: _MemOffset) => number;
+    getU32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapF32
      */
-    getF32: (offset: _MemOffset) => number;
+    getF32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapF64
      */
-    getF64: (offset: _MemOffset) => number;
+    getF64: (offset: MemOffset) => number;
 };
 
 export { BINDINGType, MONOType };
diff --git a/src/mono/wasm/runtime/memory.ts b/src/mono/wasm/runtime/memory.ts
index 05d64666ffa5d0..95373c22fb7bf6 100644
--- a/src/mono/wasm/runtime/memory.ts
+++ b/src/mono/wasm/runtime/memory.ts
@@ -1,6 +1,6 @@
 import monoWasmThreads from "consts:monoWasmThreads";
 import { Module, runtimeHelpers } from "./imports";
-import { mono_assert, _MemOffset, _NumberOrPointer } from "./types";
+import { mono_assert, MemOffset, NumberOrPointer } from "./types";
 import { VoidPtr } from "./types/emscripten";
 import * as cuint64 from "./cuint64";
 import cwraps, { I52Error } from "./cwraps";
@@ -57,47 +57,47 @@ export function _zero_region(byteOffset: VoidPtr, sizeBytes: number): void {
         Module.HEAP8.fill(0, <any>byteOffset, sizeBytes);
 }
 
-export function setB32(offset: _MemOffset, value: number | boolean): void {
+export function setB32(offset: MemOffset, value: number | boolean): void {
     const boolValue = !!value;
     if (typeof (value) === "number")
         assert_int_in_range(value, 0, 1);
     Module.HEAP32[<any>offset >>> 2] = boolValue ? 1 : 0;
 }
 
-export function setU8(offset: _MemOffset, value: number): void {
+export function setU8(offset: MemOffset, value: number): void {
     assert_int_in_range(value, 0, 0xFF);
     Module.HEAPU8[<any>offset] = value;
 }
 
-export function setU16(offset: _MemOffset, value: number): void {
+export function setU16(offset: MemOffset, value: number): void {
     assert_int_in_range(value, 0, 0xFFFF);
     Module.HEAPU16[<any>offset >>> 1] = value;
 }
 
-export function setU32_unchecked(offset: _MemOffset, value: _NumberOrPointer): void {
+export function setU32_unchecked(offset: MemOffset, value: NumberOrPointer): void {
     Module.HEAPU32[<any>offset >>> 2] = <number><any>value;
 }
 
-export function setU32(offset: _MemOffset, value: _NumberOrPointer): void {
+export function setU32(offset: MemOffset, value: NumberOrPointer): void {
     assert_int_in_range(<any>value, 0, 0xFFFF_FFFF);
     Module.HEAPU32[<any>offset >>> 2] = <number><any>value;
 }
 
-export function setI8(offset: _MemOffset, value: number): void {
+export function setI8(offset: MemOffset, value: number): void {
     assert_int_in_range(value, -0x80, 0x7F);
     Module.HEAP8[<any>offset] = value;
 }
 
-export function setI16(offset: _MemOffset, value: number): void {
+export function setI16(offset: MemOffset, value: number): void {
     assert_int_in_range(value, -0x8000, 0x7FFF);
     Module.HEAP16[<any>offset >>> 1] = value;
 }
 
-export function setI32_unchecked(offset: _MemOffset, value: number): void {
+export function setI32_unchecked(offset: MemOffset, value: number): void {
     Module.HEAP32[<any>offset >>> 2] = value;
 }
 
-export function setI32(offset: _MemOffset, value: number): void {
+export function setI32(offset: MemOffset, value: number): void {
     assert_int_in_range(<any>value, -0x8000_0000, 0x7FFF_FFFF);
     Module.HEAP32[<any>offset >>> 2] = value;
 }
@@ -119,7 +119,7 @@ function autoThrowI52(error: I52Error) {
 /**
  * Throws for values which are not 52 bit integer. See Number.isSafeInteger()
  */
-export function setI52(offset: _MemOffset, value: number): void {
+export function setI52(offset: MemOffset, value: number): void {
     mono_assert(Number.isSafeInteger(value), () => `Value is not a safe integer: ${value} (${typeof (value)})`);
     const error = cwraps.mono_wasm_f64_to_i52(<any>offset, value);
     autoThrowI52(error);
@@ -128,14 +128,14 @@ export function setI52(offset: _MemOffset, value: number): void {
 /**
  * Throws for values which are not 52 bit integer or are negative. See Number.isSafeInteger().
  */
-export function setU52(offset: _MemOffset, value: number): void {
+export function setU52(offset: MemOffset, value: number): void {
     mono_assert(Number.isSafeInteger(value), () => `Value is not a safe integer: ${value} (${typeof (value)})`);
     mono_assert(value >= 0, "Can't convert negative Number into UInt64");
     const error = cwraps.mono_wasm_f64_to_u52(<any>offset, value);
     autoThrowI52(error);
 }
 
-export function setI64Big(offset: _MemOffset, value: bigint): void {
+export function setI64Big(offset: MemOffset, value: bigint): void {
     mono_assert(is_bigint_supported, "BigInt is not supported.");
     mono_assert(typeof value === "bigint", () => `Value is not an bigint: ${value} (${typeof (value)})`);
     mono_assert(value >= min_int64_big && value <= max_int64_big, () => `Overflow: value ${value} is out of ${min_int64_big} ${max_int64_big} range`);
@@ -143,49 +143,49 @@ export function setI64Big(offset: _MemOffset, value: bigint): void {
     HEAPI64[<any>offset >>> 3] = value;
 }
 
-export function setF32(offset: _MemOffset, value: number): void {
+export function setF32(offset: MemOffset, value: number): void {
     mono_assert(typeof value === "number", () => `Value is not a Number: ${value} (${typeof (value)})`);
     Module.HEAPF32[<any>offset >>> 2] = value;
 }
 
-export function setF64(offset: _MemOffset, value: number): void {
+export function setF64(offset: MemOffset, value: number): void {
     mono_assert(typeof value === "number", () => `Value is not a Number: ${value} (${typeof (value)})`);
     Module.HEAPF64[<any>offset >>> 3] = value;
 }
 
 
-export function getB32(offset: _MemOffset): boolean {
+export function getB32(offset: MemOffset): boolean {
     return !!(Module.HEAP32[<any>offset >>> 2]);
 }
 
-export function getU8(offset: _MemOffset): number {
+export function getU8(offset: MemOffset): number {
     return Module.HEAPU8[<any>offset];
 }
 
-export function getU16(offset: _MemOffset): number {
+export function getU16(offset: MemOffset): number {
     return Module.HEAPU16[<any>offset >>> 1];
 }
 
-export function getU32(offset: _MemOffset): number {
+export function getU32(offset: MemOffset): number {
     return Module.HEAPU32[<any>offset >>> 2];
 }
 
-export function getI8(offset: _MemOffset): number {
+export function getI8(offset: MemOffset): number {
     return Module.HEAP8[<any>offset];
 }
 
-export function getI16(offset: _MemOffset): number {
+export function getI16(offset: MemOffset): number {
     return Module.HEAP16[<any>offset >>> 1];
 }
 
-export function getI32(offset: _MemOffset): number {
+export function getI32(offset: MemOffset): number {
     return Module.HEAP32[<any>offset >>> 2];
 }
 
 /**
  * Throws for Number.MIN_SAFE_INTEGER > value > Number.MAX_SAFE_INTEGER
  */
-export function getI52(offset: _MemOffset): number {
+export function getI52(offset: MemOffset): number {
     const result = cwraps.mono_wasm_i52_to_f64(<any>offset, runtimeHelpers._i52_error_scratch_buffer);
     const error = getI32(runtimeHelpers._i52_error_scratch_buffer);
     autoThrowI52(error);
@@ -195,23 +195,23 @@ export function getI52(offset: _MemOffset): number {
 /**
  * Throws for 0 > value > Number.MAX_SAFE_INTEGER
  */
-export function getU52(offset: _MemOffset): number {
+export function getU52(offset: MemOffset): number {
     const result = cwraps.mono_wasm_u52_to_f64(<any>offset, runtimeHelpers._i52_error_scratch_buffer);
     const error = getI32(runtimeHelpers._i52_error_scratch_buffer);
     autoThrowI52(error);
     return result;
 }
 
-export function getI64Big(offset: _MemOffset): bigint {
+export function getI64Big(offset: MemOffset): bigint {
     mono_assert(is_bigint_supported, "BigInt is not supported.");
     return HEAPI64[<any>offset >>> 3];
 }
 
-export function getF32(offset: _MemOffset): number {
+export function getF32(offset: MemOffset): number {
     return Module.HEAPF32[<any>offset >>> 2];
 }
 
-export function getF64(offset: _MemOffset): number {
+export function getF64(offset: MemOffset): number {
     return Module.HEAPF64[<any>offset >>> 3];
 }
 
@@ -225,13 +225,13 @@ export function afterUpdateGlobalBufferAndViews(buffer: ArrayBufferLike): void {
     }
 }
 
-export function getCU64(offset: _MemOffset): cuint64.CUInt64 {
+export function getCU64(offset: MemOffset): cuint64.CUInt64 {
     const lo = getU32(offset);
     const hi = getU32(<any>offset + 4);
     return cuint64.pack32(lo, hi);
 }
 
-export function setCU64(offset: _MemOffset, value: cuint64.CUInt64): void {
+export function setCU64(offset: MemOffset, value: cuint64.CUInt64): void {
     const [lo, hi] = cuint64.unpack32(value);
     setU32_unchecked(offset, lo);
     setU32_unchecked(<any>offset + 4, hi);
@@ -266,11 +266,11 @@ export function mono_wasm_load_bytes_into_heap(bytes: Uint8Array): VoidPtr {
 const BuiltinAtomics = globalThis.Atomics;
 
 export const Atomics = monoWasmThreads ? {
-    storeI32(offset: _MemOffset, value: number): void {
+    storeI32(offset: MemOffset, value: number): void {
 
         BuiltinAtomics.store(Module.HEAP32, <any>offset >>> 2, value);
     },
-    notifyI32(offset: _MemOffset, count: number): void {
+    notifyI32(offset: MemOffset, count: number): void {
         BuiltinAtomics.notify(Module.HEAP32, <any>offset >>> 2, count);
     }
 } : {
diff --git a/src/mono/wasm/runtime/net6-legacy/export-types.ts b/src/mono/wasm/runtime/net6-legacy/export-types.ts
index 8dcd913ca9dcda..22291a91491802 100644
--- a/src/mono/wasm/runtime/net6-legacy/export-types.ts
+++ b/src/mono/wasm/runtime/net6-legacy/export-types.ts
@@ -1,4 +1,4 @@
-import { MonoArray, MonoObject, MonoObjectRef, MonoString, WasmRoot, WasmRootBuffer, _MemOffset, _NumberOrPointer } from "../types";
+import { MonoArray, MonoObject, MonoObjectRef, MonoString, WasmRoot, WasmRootBuffer, MemOffset, NumberOrPointer } from "../types";
 import { VoidPtr } from "../types/emscripten";
 
 /**
@@ -154,97 +154,97 @@ export type MONOType = {
     /**
      * @deprecated Please use setHeapB32
      */
-    setB32: (offset: _MemOffset, value: number | boolean) => void;
+    setB32: (offset: MemOffset, value: number | boolean) => void;
     /**
      * @deprecated Please use setHeapI8
      */
-    setI8: (offset: _MemOffset, value: number) => void;
+    setI8: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI16
      */
-    setI16: (offset: _MemOffset, value: number) => void;
+    setI16: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI32
      */
-    setI32: (offset: _MemOffset, value: number) => void;
+    setI32: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI52
      */
-    setI52: (offset: _MemOffset, value: number) => void;
+    setI52: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU52
      */
-    setU52: (offset: _MemOffset, value: number) => void;
+    setU52: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapI64Big
      */
-    setI64Big: (offset: _MemOffset, value: bigint) => void;
+    setI64Big: (offset: MemOffset, value: bigint) => void;
     /**
      * @deprecated Please use setHeapU8
      */
-    setU8: (offset: _MemOffset, value: number) => void;
+    setU8: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU16
      */
-    setU16: (offset: _MemOffset, value: number) => void;
+    setU16: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapU32
      */
-    setU32: (offset: _MemOffset, value: _NumberOrPointer) => void;
+    setU32: (offset: MemOffset, value: NumberOrPointer) => void;
     /**
      * @deprecated Please use setHeapF32
      */
-    setF32: (offset: _MemOffset, value: number) => void;
+    setF32: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use setHeapF64
      */
-    setF64: (offset: _MemOffset, value: number) => void;
+    setF64: (offset: MemOffset, value: number) => void;
     /**
      * @deprecated Please use getHeapB32
      */
-    getB32: (offset: _MemOffset) => boolean;
+    getB32: (offset: MemOffset) => boolean;
     /**
      * @deprecated Please use getHeapI8
      */
-    getI8: (offset: _MemOffset) => number;
+    getI8: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI16
      */
-    getI16: (offset: _MemOffset) => number;
+    getI16: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI32
      */
-    getI32: (offset: _MemOffset) => number;
+    getI32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI52
      */
-    getI52: (offset: _MemOffset) => number;
+    getI52: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU52
      */
-    getU52: (offset: _MemOffset) => number;
+    getU52: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapI64Big
      */
-    getI64Big: (offset: _MemOffset) => bigint;
+    getI64Big: (offset: MemOffset) => bigint;
     /**
      * @deprecated Please use getHeapU8
      */
-    getU8: (offset: _MemOffset) => number;
+    getU8: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU16
      */
-    getU16: (offset: _MemOffset) => number;
+    getU16: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapU32
      */
-    getU32: (offset: _MemOffset) => number;
+    getU32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapF32
      */
-    getF32: (offset: _MemOffset) => number;
+    getF32: (offset: MemOffset) => number;
     /**
      * @deprecated Please use getHeapF64
      */
-    getF64: (offset: _MemOffset) => number;
+    getF64: (offset: MemOffset) => number;
 };
\ No newline at end of file
diff --git a/src/mono/wasm/runtime/types.ts b/src/mono/wasm/runtime/types.ts
index a1b938e123e3c5..e11d7efe6a36f6 100644
--- a/src/mono/wasm/runtime/types.ts
+++ b/src/mono/wasm/runtime/types.ts
@@ -379,8 +379,8 @@ export interface JSMarshalerArgument extends NativePointer {
     __brand: "JSMarshalerArgument"
 }
 
-export type _MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
-export type _NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
+export type MemOffset = number | VoidPtr | NativePointer | ManagedPointer;
+export type NumberOrPointer = number | VoidPtr | NativePointer | ManagedPointer;
 
 export interface WasmRoot<T extends MonoObject> {
     get_address(): MonoObjectRef;
